~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to fs/nfs/nfs3proc.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <linux/errno.h>
11
11
#include <linux/string.h>
12
12
#include <linux/sunrpc/clnt.h>
 
13
#include <linux/slab.h>
13
14
#include <linux/nfs.h>
14
15
#include <linux/nfs3.h>
15
16
#include <linux/nfs_fs.h>
22
23
 
23
24
#define NFSDBG_FACILITY         NFSDBG_PROC
24
25
 
25
 
/* A wrapper to handle the EJUKEBOX error message */
 
26
/* A wrapper to handle the EJUKEBOX and EKEYEXPIRED error messages */
26
27
static int
27
28
nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
28
29
{
29
30
        int res;
30
31
        do {
31
32
                res = rpc_call_sync(clnt, msg, flags);
32
 
                if (res != -EJUKEBOX)
 
33
                if (res != -EJUKEBOX && res != -EKEYEXPIRED)
33
34
                        break;
34
35
                schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
35
36
                res = -ERESTARTSYS;
42
43
static int
43
44
nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
44
45
{
45
 
        if (task->tk_status != -EJUKEBOX)
 
46
        if (task->tk_status != -EJUKEBOX && task->tk_status != -EKEYEXPIRED)
46
47
                return 0;
47
 
        nfs_inc_stats(inode, NFSIOS_DELAY);
 
48
        if (task->tk_status == -EJUKEBOX)
 
49
                nfs_inc_stats(inode, NFSIOS_DELAY);
48
50
        task->tk_status = 0;
49
51
        rpc_restart_call(task);
50
52
        rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
142
144
nfs3_proc_lookup(struct inode *dir, struct qstr *name,
143
145
                 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
144
146
{
145
 
        struct nfs_fattr        dir_attr;
146
147
        struct nfs3_diropargs   arg = {
147
148
                .fh             = NFS_FH(dir),
148
149
                .name           = name->name,
149
150
                .len            = name->len
150
151
        };
151
152
        struct nfs3_diropres    res = {
152
 
                .dir_attr       = &dir_attr,
153
153
                .fh             = fhandle,
154
154
                .fattr          = fattr
155
155
        };
161
161
        int                     status;
162
162
 
163
163
        dprintk("NFS call  lookup %s\n", name->name);
164
 
        nfs_fattr_init(&dir_attr);
 
164
        res.dir_attr = nfs_alloc_fattr();
 
165
        if (res.dir_attr == NULL)
 
166
                return -ENOMEM;
 
167
 
165
168
        nfs_fattr_init(fattr);
166
169
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
167
 
        nfs_refresh_inode(dir, &dir_attr);
 
170
        nfs_refresh_inode(dir, res.dir_attr);
168
171
        if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
169
172
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
170
173
                msg.rpc_argp = fhandle;
171
174
                msg.rpc_resp = fattr;
172
175
                status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
173
176
        }
 
177
        nfs_free_fattr(res.dir_attr);
174
178
        dprintk("NFS reply lookup: %d\n", status);
175
179
        return status;
176
180
}
177
181
 
178
182
static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
179
183
{
180
 
        struct nfs_fattr        fattr;
181
184
        struct nfs3_accessargs  arg = {
182
185
                .fh             = NFS_FH(inode),
183
186
        };
184
 
        struct nfs3_accessres   res = {
185
 
                .fattr          = &fattr,
186
 
        };
 
187
        struct nfs3_accessres   res;
187
188
        struct rpc_message msg = {
188
189
                .rpc_proc       = &nfs3_procedures[NFS3PROC_ACCESS],
189
190
                .rpc_argp       = &arg,
191
192
                .rpc_cred       = entry->cred,
192
193
        };
193
194
        int mode = entry->mask;
194
 
        int status;
 
195
        int status = -ENOMEM;
195
196
 
196
197
        dprintk("NFS call  access\n");
197
198
 
208
209
                if (mode & MAY_EXEC)
209
210
                        arg.access |= NFS3_ACCESS_EXECUTE;
210
211
        }
211
 
        nfs_fattr_init(&fattr);
 
212
 
 
213
        res.fattr = nfs_alloc_fattr();
 
214
        if (res.fattr == NULL)
 
215
                goto out;
 
216
 
212
217
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
213
 
        nfs_refresh_inode(inode, &fattr);
 
218
        nfs_refresh_inode(inode, res.fattr);
214
219
        if (status == 0) {
215
220
                entry->mask = 0;
216
221
                if (res.access & NFS3_ACCESS_READ)
220
225
                if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
221
226
                        entry->mask |= MAY_EXEC;
222
227
        }
 
228
        nfs_free_fattr(res.fattr);
 
229
out:
223
230
        dprintk("NFS reply access: %d\n", status);
224
231
        return status;
225
232
}
227
234
static int nfs3_proc_readlink(struct inode *inode, struct page *page,
228
235
                unsigned int pgbase, unsigned int pglen)
229
236
{
230
 
        struct nfs_fattr        fattr;
 
237
        struct nfs_fattr        *fattr;
231
238
        struct nfs3_readlinkargs args = {
232
239
                .fh             = NFS_FH(inode),
233
240
                .pgbase         = pgbase,
237
244
        struct rpc_message msg = {
238
245
                .rpc_proc       = &nfs3_procedures[NFS3PROC_READLINK],
239
246
                .rpc_argp       = &args,
240
 
                .rpc_resp       = &fattr,
241
247
        };
242
 
        int                     status;
 
248
        int status = -ENOMEM;
243
249
 
244
250
        dprintk("NFS call  readlink\n");
245
 
        nfs_fattr_init(&fattr);
 
251
        fattr = nfs_alloc_fattr();
 
252
        if (fattr == NULL)
 
253
                goto out;
 
254
        msg.rpc_resp = fattr;
 
255
 
246
256
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
247
 
        nfs_refresh_inode(inode, &fattr);
 
257
        nfs_refresh_inode(inode, fattr);
 
258
        nfs_free_fattr(fattr);
 
259
out:
248
260
        dprintk("NFS reply readlink: %d\n", status);
249
261
        return status;
250
262
}
301
313
 */
302
314
static int
303
315
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
304
 
                 int flags, struct nameidata *nd)
 
316
                 int flags, struct nfs_open_context *ctx)
305
317
{
306
318
        struct nfs3_createdata *data;
307
319
        mode_t mode = sattr->ia_mode;
394
406
                .rpc_argp = &arg,
395
407
                .rpc_resp = &res,
396
408
        };
397
 
        int                     status;
 
409
        int status = -ENOMEM;
398
410
 
399
411
        dprintk("NFS call  remove %s\n", name->name);
400
 
        nfs_fattr_init(&res.dir_attr);
 
412
        res.dir_attr = nfs_alloc_fattr();
 
413
        if (res.dir_attr == NULL)
 
414
                goto out;
 
415
 
401
416
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
402
 
        nfs_post_op_update_inode(dir, &res.dir_attr);
 
417
        nfs_post_op_update_inode(dir, res.dir_attr);
 
418
        nfs_free_fattr(res.dir_attr);
 
419
out:
403
420
        dprintk("NFS reply remove: %d\n", status);
404
421
        return status;
405
422
}
417
434
        if (nfs3_async_handle_jukebox(task, dir))
418
435
                return 0;
419
436
        res = task->tk_msg.rpc_resp;
420
 
        nfs_post_op_update_inode(dir, &res->dir_attr);
 
437
        nfs_post_op_update_inode(dir, res->dir_attr);
 
438
        return 1;
 
439
}
 
440
 
 
441
static void
 
442
nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
 
443
{
 
444
        msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
 
445
}
 
446
 
 
447
static int
 
448
nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
 
449
                      struct inode *new_dir)
 
450
{
 
451
        struct nfs_renameres *res;
 
452
 
 
453
        if (nfs3_async_handle_jukebox(task, old_dir))
 
454
                return 0;
 
455
        res = task->tk_msg.rpc_resp;
 
456
 
 
457
        nfs_post_op_update_inode(old_dir, res->old_fattr);
 
458
        nfs_post_op_update_inode(new_dir, res->new_fattr);
421
459
        return 1;
422
460
}
423
461
 
425
463
nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
426
464
                 struct inode *new_dir, struct qstr *new_name)
427
465
{
428
 
        struct nfs_fattr        old_dir_attr, new_dir_attr;
429
 
        struct nfs3_renameargs  arg = {
430
 
                .fromfh         = NFS_FH(old_dir),
431
 
                .fromname       = old_name->name,
432
 
                .fromlen        = old_name->len,
433
 
                .tofh           = NFS_FH(new_dir),
434
 
                .toname         = new_name->name,
435
 
                .tolen          = new_name->len
436
 
        };
437
 
        struct nfs3_renameres   res = {
438
 
                .fromattr       = &old_dir_attr,
439
 
                .toattr         = &new_dir_attr
440
 
        };
 
466
        struct nfs_renameargs   arg = {
 
467
                .old_dir        = NFS_FH(old_dir),
 
468
                .old_name       = old_name,
 
469
                .new_dir        = NFS_FH(new_dir),
 
470
                .new_name       = new_name,
 
471
        };
 
472
        struct nfs_renameres res;
441
473
        struct rpc_message msg = {
442
474
                .rpc_proc       = &nfs3_procedures[NFS3PROC_RENAME],
443
475
                .rpc_argp       = &arg,
444
476
                .rpc_resp       = &res,
445
477
        };
446
 
        int                     status;
 
478
        int status = -ENOMEM;
447
479
 
448
480
        dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
449
 
        nfs_fattr_init(&old_dir_attr);
450
 
        nfs_fattr_init(&new_dir_attr);
 
481
 
 
482
        res.old_fattr = nfs_alloc_fattr();
 
483
        res.new_fattr = nfs_alloc_fattr();
 
484
        if (res.old_fattr == NULL || res.new_fattr == NULL)
 
485
                goto out;
 
486
 
451
487
        status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
452
 
        nfs_post_op_update_inode(old_dir, &old_dir_attr);
453
 
        nfs_post_op_update_inode(new_dir, &new_dir_attr);
 
488
        nfs_post_op_update_inode(old_dir, res.old_fattr);
 
489
        nfs_post_op_update_inode(new_dir, res.new_fattr);
 
490
out:
 
491
        nfs_free_fattr(res.old_fattr);
 
492
        nfs_free_fattr(res.new_fattr);
454
493
        dprintk("NFS reply rename: %d\n", status);
455
494
        return status;
456
495
}
458
497
static int
459
498
nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
460
499
{
461
 
        struct nfs_fattr        dir_attr, fattr;
462
500
        struct nfs3_linkargs    arg = {
463
501
                .fromfh         = NFS_FH(inode),
464
502
                .tofh           = NFS_FH(dir),
465
503
                .toname         = name->name,
466
504
                .tolen          = name->len
467
505
        };
468
 
        struct nfs3_linkres     res = {
469
 
                .dir_attr       = &dir_attr,
470
 
                .fattr          = &fattr
471
 
        };
 
506
        struct nfs3_linkres     res;
472
507
        struct rpc_message msg = {
473
508
                .rpc_proc       = &nfs3_procedures[NFS3PROC_LINK],
474
509
                .rpc_argp       = &arg,
475
510
                .rpc_resp       = &res,
476
511
        };
477
 
        int                     status;
 
512
        int status = -ENOMEM;
478
513
 
479
514
        dprintk("NFS call  link %s\n", name->name);
480
 
        nfs_fattr_init(&dir_attr);
481
 
        nfs_fattr_init(&fattr);
 
515
        res.fattr = nfs_alloc_fattr();
 
516
        res.dir_attr = nfs_alloc_fattr();
 
517
        if (res.fattr == NULL || res.dir_attr == NULL)
 
518
                goto out;
 
519
 
482
520
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
483
 
        nfs_post_op_update_inode(dir, &dir_attr);
484
 
        nfs_post_op_update_inode(inode, &fattr);
 
521
        nfs_post_op_update_inode(dir, res.dir_attr);
 
522
        nfs_post_op_update_inode(inode, res.fattr);
 
523
out:
 
524
        nfs_free_fattr(res.dir_attr);
 
525
        nfs_free_fattr(res.fattr);
485
526
        dprintk("NFS reply link: %d\n", status);
486
527
        return status;
487
528
}
552
593
static int
553
594
nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
554
595
{
555
 
        struct nfs_fattr        dir_attr;
 
596
        struct nfs_fattr        *dir_attr;
556
597
        struct nfs3_diropargs   arg = {
557
598
                .fh             = NFS_FH(dir),
558
599
                .name           = name->name,
561
602
        struct rpc_message msg = {
562
603
                .rpc_proc       = &nfs3_procedures[NFS3PROC_RMDIR],
563
604
                .rpc_argp       = &arg,
564
 
                .rpc_resp       = &dir_attr,
565
605
        };
566
 
        int                     status;
 
606
        int status = -ENOMEM;
567
607
 
568
608
        dprintk("NFS call  rmdir %s\n", name->name);
569
 
        nfs_fattr_init(&dir_attr);
 
609
        dir_attr = nfs_alloc_fattr();
 
610
        if (dir_attr == NULL)
 
611
                goto out;
 
612
 
 
613
        msg.rpc_resp = dir_attr;
570
614
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
571
 
        nfs_post_op_update_inode(dir, &dir_attr);
 
615
        nfs_post_op_update_inode(dir, dir_attr);
 
616
        nfs_free_fattr(dir_attr);
 
617
out:
572
618
        dprintk("NFS reply rmdir: %d\n", status);
573
619
        return status;
574
620
}
584
630
 */
585
631
static int
586
632
nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
587
 
                  u64 cookie, struct page *page, unsigned int count, int plus)
 
633
                  u64 cookie, struct page **pages, unsigned int count, int plus)
588
634
{
589
635
        struct inode            *dir = dentry->d_inode;
590
 
        struct nfs_fattr        dir_attr;
591
636
        __be32                  *verf = NFS_COOKIEVERF(dir);
592
637
        struct nfs3_readdirargs arg = {
593
638
                .fh             = NFS_FH(dir),
595
640
                .verf           = {verf[0], verf[1]},
596
641
                .plus           = plus,
597
642
                .count          = count,
598
 
                .pages          = &page
 
643
                .pages          = pages
599
644
        };
600
645
        struct nfs3_readdirres  res = {
601
 
                .dir_attr       = &dir_attr,
602
646
                .verf           = verf,
603
647
                .plus           = plus
604
648
        };
608
652
                .rpc_resp       = &res,
609
653
                .rpc_cred       = cred
610
654
        };
611
 
        int                     status;
 
655
        int status = -ENOMEM;
612
656
 
613
657
        if (plus)
614
658
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
616
660
        dprintk("NFS call  readdir%s %d\n",
617
661
                        plus? "plus" : "", (unsigned int) cookie);
618
662
 
619
 
        nfs_fattr_init(&dir_attr);
 
663
        res.dir_attr = nfs_alloc_fattr();
 
664
        if (res.dir_attr == NULL)
 
665
                goto out;
 
666
 
620
667
        status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
621
668
 
622
669
        nfs_invalidate_atime(dir);
 
670
        nfs_refresh_inode(dir, res.dir_attr);
623
671
 
624
 
        nfs_refresh_inode(dir, &dir_attr);
625
 
        dprintk("NFS reply readdir: %d\n", status);
 
672
        nfs_free_fattr(res.dir_attr);
 
673
out:
 
674
        dprintk("NFS reply readdir%s: %d\n",
 
675
                        plus? "plus" : "", status);
626
676
        return status;
627
677
}
628
678
 
692
742
        dprintk("NFS call  fsstat\n");
693
743
        nfs_fattr_init(stat->fattr);
694
744
        status = rpc_call_sync(server->client, &msg, 0);
695
 
        dprintk("NFS reply statfs: %d\n", status);
 
745
        dprintk("NFS reply fsstat: %d\n", status);
696
746
        return status;
697
747
}
698
748
 
814
864
        .unlink_setup   = nfs3_proc_unlink_setup,
815
865
        .unlink_done    = nfs3_proc_unlink_done,
816
866
        .rename         = nfs3_proc_rename,
 
867
        .rename_setup   = nfs3_proc_rename_setup,
 
868
        .rename_done    = nfs3_proc_rename_done,
817
869
        .link           = nfs3_proc_link,
818
870
        .symlink        = nfs3_proc_symlink,
819
871
        .mkdir          = nfs3_proc_mkdir,