ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / nfs / nfs3proc.c
1 /*
2  *  linux/fs/nfs/nfs3proc.c
3  *
4  *  Client-side NFSv3 procedures stubs.
5  *
6  *  Copyright (C) 1997, Olaf Kirch
7  */
8
9 #include <linux/mm.h>
10 #include <linux/utsname.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/sunrpc/clnt.h>
14 #include <linux/nfs.h>
15 #include <linux/nfs3.h>
16 #include <linux/nfs_fs.h>
17 #include <linux/nfs_page.h>
18 #include <linux/lockd/bind.h>
19 #include <linux/smp_lock.h>
20
21 #define NFSDBG_FACILITY         NFSDBG_PROC
22
23 extern struct rpc_procinfo nfs3_procedures[];
24
25 /* A wrapper to handle the EJUKEBOX error message */
26 static int
27 nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
28 {
29         sigset_t oldset;
30         int res;
31         rpc_clnt_sigmask(clnt, &oldset);
32         do {
33                 res = rpc_call_sync(clnt, msg, flags);
34                 if (res != -EJUKEBOX)
35                         break;
36                 set_current_state(TASK_INTERRUPTIBLE);
37                 schedule_timeout(NFS_JUKEBOX_RETRY_TIME);
38                 res = -ERESTARTSYS;
39         } while (!signalled());
40         rpc_clnt_sigunmask(clnt, &oldset);
41         return res;
42 }
43
44 static inline int
45 nfs3_rpc_call_wrapper(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
46 {
47         struct rpc_message msg = {
48                 .rpc_proc       = &nfs3_procedures[proc],
49                 .rpc_argp       = argp,
50                 .rpc_resp       = resp,
51         };
52         return nfs3_rpc_wrapper(clnt, &msg, flags);
53 }
54
55 #define rpc_call(clnt, proc, argp, resp, flags) \
56                 nfs3_rpc_call_wrapper(clnt, proc, argp, resp, flags)
57 #define rpc_call_sync(clnt, msg, flags) \
58                 nfs3_rpc_wrapper(clnt, msg, flags)
59
60 static int
61 nfs3_async_handle_jukebox(struct rpc_task *task)
62 {
63         if (task->tk_status != -EJUKEBOX)
64                 return 0;
65         task->tk_status = 0;
66         rpc_restart_call(task);
67         rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
68         return 1;
69 }
70
71 static struct rpc_cred *
72 nfs_cred(struct inode *inode, struct file *filp)
73 {
74         struct rpc_cred *cred = NULL;
75
76         if (filp)
77                 cred = (struct rpc_cred *)filp->private_data;
78         if (!cred)
79                 cred = NFS_I(inode)->mm_cred;
80         return cred;
81 }
82
83 /*
84  * Bare-bones access to getattr: this is for nfs_read_super.
85  */
86 static int
87 nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
88                    struct nfs_fsinfo *info)
89 {
90         int     status;
91
92         dprintk("%s: call  fsinfo\n", __FUNCTION__);
93         info->fattr->valid = 0;
94         status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
95         dprintk("%s: reply fsinfo %d\n", __FUNCTION__, status);
96         if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
97                 status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0);
98                 dprintk("%s: reply getattr %d\n", __FUNCTION__, status);
99         }
100         return status;
101 }
102
103 /*
104  * One function for each procedure in the NFS protocol.
105  */
106 static int
107 nfs3_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
108 {
109         int     status;
110
111         dprintk("NFS call  getattr\n");
112         fattr->valid = 0;
113         status = rpc_call(NFS_CLIENT(inode), NFS3PROC_GETATTR,
114                           NFS_FH(inode), fattr, 0);
115         dprintk("NFS reply getattr\n");
116         return status;
117 }
118
119 static int
120 nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
121                         struct iattr *sattr)
122 {
123         struct inode *inode = dentry->d_inode;
124         struct nfs3_sattrargs   arg = {
125                 .fh             = NFS_FH(inode),
126                 .sattr          = sattr,
127         };
128         int     status;
129
130         dprintk("NFS call  setattr\n");
131         fattr->valid = 0;
132         status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
133         dprintk("NFS reply setattr\n");
134         return status;
135 }
136
137 static int
138 nfs3_proc_lookup(struct inode *dir, struct qstr *name,
139                  struct nfs_fh *fhandle, struct nfs_fattr *fattr)
140 {
141         struct nfs_fattr        dir_attr;
142         struct nfs3_diropargs   arg = {
143                 .fh             = NFS_FH(dir),
144                 .name           = name->name,
145                 .len            = name->len
146         };
147         struct nfs3_diropres    res = {
148                 .dir_attr       = &dir_attr,
149                 .fh             = fhandle,
150                 .fattr          = fattr
151         };
152         int                     status;
153
154         dprintk("NFS call  lookup %s\n", name->name);
155         dir_attr.valid = 0;
156         fattr->valid = 0;
157         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
158         if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
159                 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
160                          fhandle, fattr, 0);
161         dprintk("NFS reply lookup: %d\n", status);
162         if (status >= 0)
163                 status = nfs_refresh_inode(dir, &dir_attr);
164         return status;
165 }
166
167 static int
168 nfs3_proc_access(struct inode *inode, struct rpc_cred *cred, int mode)
169 {
170         struct nfs_fattr        fattr;
171         struct nfs3_accessargs  arg = {
172                 .fh             = NFS_FH(inode),
173         };
174         struct nfs3_accessres   res = {
175                 .fattr          = &fattr,
176         };
177         struct rpc_message msg = {
178                 .rpc_proc       = &nfs3_procedures[NFS3PROC_ACCESS],
179                 .rpc_argp       = &arg,
180                 .rpc_resp       = &res,
181                 .rpc_cred       = cred
182         };
183         int     status;
184
185         dprintk("NFS call  access\n");
186         fattr.valid = 0;
187
188         if (mode & MAY_READ)
189                 arg.access |= NFS3_ACCESS_READ;
190         if (S_ISDIR(inode->i_mode)) {
191                 if (mode & MAY_WRITE)
192                         arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
193                 if (mode & MAY_EXEC)
194                         arg.access |= NFS3_ACCESS_LOOKUP;
195         } else {
196                 if (mode & MAY_WRITE)
197                         arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
198                 if (mode & MAY_EXEC)
199                         arg.access |= NFS3_ACCESS_EXECUTE;
200         }
201         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
202         nfs_refresh_inode(inode, &fattr);
203         dprintk("NFS reply access\n");
204
205         if (status == 0 && (arg.access & res.access) != arg.access)
206                 status = -EACCES;
207         return status;
208 }
209
210 static int
211 nfs3_proc_readlink(struct inode *inode, struct page *page)
212 {
213         struct nfs_fattr        fattr;
214         struct nfs3_readlinkargs args = {
215                 .fh             = NFS_FH(inode),
216                 .count          = PAGE_CACHE_SIZE,
217                 .pages          = &page
218         };
219         int                     status;
220
221         dprintk("NFS call  readlink\n");
222         fattr.valid = 0;
223         status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
224                           &args, &fattr, 0);
225         nfs_refresh_inode(inode, &fattr);
226         dprintk("NFS reply readlink: %d\n", status);
227         return status;
228 }
229
230 static int
231 nfs3_proc_read(struct nfs_read_data *rdata, struct file *filp)
232 {
233         int                     flags = rdata->flags;
234         struct inode *          inode = rdata->inode;
235         struct nfs_fattr *      fattr = rdata->res.fattr;
236         struct rpc_message      msg = {
237                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READ],
238                 .rpc_argp       = &rdata->args,
239                 .rpc_resp       = &rdata->res,
240         };
241         int                     status;
242
243         dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
244                         (long long) rdata->args.offset);
245         fattr->valid = 0;
246         msg.rpc_cred = nfs_cred(inode, filp);
247         status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
248         if (status >= 0)
249                 nfs_refresh_inode(inode, fattr);
250         dprintk("NFS reply read: %d\n", status);
251         return status;
252 }
253
254 static int
255 nfs3_proc_write(struct nfs_write_data *wdata, struct file *filp)
256 {
257         int                     rpcflags = wdata->flags;
258         struct inode *          inode = wdata->inode;
259         struct nfs_fattr *      fattr = wdata->res.fattr;
260         struct rpc_message      msg = {
261                 .rpc_proc       = &nfs3_procedures[NFS3PROC_WRITE],
262                 .rpc_argp       = &wdata->args,
263                 .rpc_resp       = &wdata->res,
264         };
265         int                     status;
266
267         dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
268                         (long long) wdata->args.offset);
269         fattr->valid = 0;
270         msg.rpc_cred = nfs_cred(inode, filp);
271         status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
272         if (status >= 0)
273                 nfs_refresh_inode(inode, fattr);
274         dprintk("NFS reply write: %d\n", status);
275         return status < 0? status : wdata->res.count;
276 }
277
278 static int
279 nfs3_proc_commit(struct nfs_write_data *cdata, struct file *filp)
280 {
281         struct inode *          inode = cdata->inode;
282         struct nfs_fattr *      fattr = cdata->res.fattr;
283         struct rpc_message      msg = {
284                 .rpc_proc       = &nfs3_procedures[NFS3PROC_COMMIT],
285                 .rpc_argp       = &cdata->args,
286                 .rpc_resp       = &cdata->res,
287         };
288         int                     status;
289
290         dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
291                         (long long) cdata->args.offset);
292         fattr->valid = 0;
293         msg.rpc_cred = nfs_cred(inode, filp);
294         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
295         if (status >= 0)
296                 nfs_refresh_inode(inode, fattr);
297         dprintk("NFS reply commit: %d\n", status);
298         return status;
299 }
300
301 /*
302  * Create a regular file.
303  * For now, we don't implement O_EXCL.
304  */
305 static struct inode *
306 nfs3_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
307                  int flags)
308 {
309         struct nfs_fh           fhandle;
310         struct nfs_fattr        fattr;
311         struct nfs_fattr        dir_attr;
312         struct nfs3_createargs  arg = {
313                 .fh             = NFS_FH(dir),
314                 .name           = name->name,
315                 .len            = name->len,
316                 .sattr          = sattr,
317         };
318         struct nfs3_diropres    res = {
319                 .dir_attr       = &dir_attr,
320                 .fh             = &fhandle,
321                 .fattr          = &fattr
322         };
323         int                     status;
324
325         dprintk("NFS call  create %s\n", name->name);
326         arg.createmode = NFS3_CREATE_UNCHECKED;
327         if (flags & O_EXCL) {
328                 arg.createmode  = NFS3_CREATE_EXCLUSIVE;
329                 arg.verifier[0] = jiffies;
330                 arg.verifier[1] = current->pid;
331         }
332
333 again:
334         dir_attr.valid = 0;
335         fattr.valid = 0;
336         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
337         nfs_refresh_inode(dir, &dir_attr);
338
339         /* If the server doesn't support the exclusive creation semantics,
340          * try again with simple 'guarded' mode. */
341         if (status == NFSERR_NOTSUPP) {
342                 switch (arg.createmode) {
343                         case NFS3_CREATE_EXCLUSIVE:
344                                 arg.createmode = NFS3_CREATE_GUARDED;
345                                 break;
346
347                         case NFS3_CREATE_GUARDED:
348                                 arg.createmode = NFS3_CREATE_UNCHECKED;
349                                 break;
350
351                         case NFS3_CREATE_UNCHECKED:
352                                 goto exit;
353                 }
354                 goto again;
355         }
356
357 exit:
358         dprintk("NFS reply create: %d\n", status);
359
360         if (status != 0)
361                 goto out;
362         if (fhandle.size == 0 || !(fattr.valid & NFS_ATTR_FATTR)) {
363                 status = nfs3_proc_lookup(dir, name, &fhandle, &fattr);
364                 if (status != 0)
365                         goto out;
366         }
367
368         /* When we created the file with exclusive semantics, make
369          * sure we set the attributes afterwards. */
370         if (arg.createmode == NFS3_CREATE_EXCLUSIVE) {
371                 struct nfs3_sattrargs   arg = {
372                         .fh             = &fhandle,
373                         .sattr          = sattr,
374                 };
375                 dprintk("NFS call  setattr (post-create)\n");
376
377                 if (!(sattr->ia_valid & ATTR_ATIME_SET))
378                         sattr->ia_valid |= ATTR_ATIME;
379                 if (!(sattr->ia_valid & ATTR_MTIME_SET))
380                         sattr->ia_valid |= ATTR_MTIME;
381
382                 /* Note: we could use a guarded setattr here, but I'm
383                  * not sure this buys us anything (and I'd have
384                  * to revamp the NFSv3 XDR code) */
385                 fattr.valid = 0;
386                 status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR,
387                                                 &arg, &fattr, 0);
388                 dprintk("NFS reply setattr (post-create): %d\n", status);
389         }
390         if (status == 0) {
391                 struct inode *inode;
392                 inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
393                 if (inode)
394                         return inode;
395                 status = -ENOMEM;
396         }
397 out:
398         return ERR_PTR(status);
399 }
400
401 static int
402 nfs3_proc_remove(struct inode *dir, struct qstr *name)
403 {
404         struct nfs_fattr        dir_attr;
405         struct nfs3_diropargs   arg = {
406                 .fh             = NFS_FH(dir),
407                 .name           = name->name,
408                 .len            = name->len
409         };
410         struct rpc_message      msg = {
411                 .rpc_proc       = &nfs3_procedures[NFS3PROC_REMOVE],
412                 .rpc_argp       = &arg,
413                 .rpc_resp       = &dir_attr,
414         };
415         int                     status;
416
417         dprintk("NFS call  remove %s\n", name->name);
418         dir_attr.valid = 0;
419         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
420         nfs_refresh_inode(dir, &dir_attr);
421         dprintk("NFS reply remove: %d\n", status);
422         return status;
423 }
424
425 static int
426 nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
427 {
428         struct nfs3_diropargs   *arg;
429         struct nfs_fattr        *res;
430
431         arg = (struct nfs3_diropargs *)kmalloc(sizeof(*arg)+sizeof(*res), GFP_KERNEL);
432         if (!arg)
433                 return -ENOMEM;
434         res = (struct nfs_fattr*)(arg + 1);
435         arg->fh = NFS_FH(dir->d_inode);
436         arg->name = name->name;
437         arg->len = name->len;
438         res->valid = 0;
439         msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
440         msg->rpc_argp = arg;
441         msg->rpc_resp = res;
442         return 0;
443 }
444
445 static int
446 nfs3_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
447 {
448         struct rpc_message *msg = &task->tk_msg;
449         struct nfs_fattr        *dir_attr;
450
451         if (nfs3_async_handle_jukebox(task))
452                 return 1;
453         if (msg->rpc_argp) {
454                 dir_attr = (struct nfs_fattr*)msg->rpc_resp;
455                 nfs_refresh_inode(dir->d_inode, dir_attr);
456                 kfree(msg->rpc_argp);
457         }
458         return 0;
459 }
460
461 static int
462 nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
463                  struct inode *new_dir, struct qstr *new_name)
464 {
465         struct nfs_fattr        old_dir_attr, new_dir_attr;
466         struct nfs3_renameargs  arg = {
467                 .fromfh         = NFS_FH(old_dir),
468                 .fromname       = old_name->name,
469                 .fromlen        = old_name->len,
470                 .tofh           = NFS_FH(new_dir),
471                 .toname         = new_name->name,
472                 .tolen          = new_name->len
473         };
474         struct nfs3_renameres   res = {
475                 .fromattr       = &old_dir_attr,
476                 .toattr         = &new_dir_attr
477         };
478         int                     status;
479
480         dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
481         old_dir_attr.valid = 0;
482         new_dir_attr.valid = 0;
483         status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
484         nfs_refresh_inode(old_dir, &old_dir_attr);
485         nfs_refresh_inode(new_dir, &new_dir_attr);
486         dprintk("NFS reply rename: %d\n", status);
487         return status;
488 }
489
490 static int
491 nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
492 {
493         struct nfs_fattr        dir_attr, fattr;
494         struct nfs3_linkargs    arg = {
495                 .fromfh         = NFS_FH(inode),
496                 .tofh           = NFS_FH(dir),
497                 .toname         = name->name,
498                 .tolen          = name->len
499         };
500         struct nfs3_linkres     res = {
501                 .dir_attr       = &dir_attr,
502                 .fattr          = &fattr
503         };
504         int                     status;
505
506         dprintk("NFS call  link %s\n", name->name);
507         dir_attr.valid = 0;
508         fattr.valid = 0;
509         status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
510         nfs_refresh_inode(dir, &dir_attr);
511         nfs_refresh_inode(inode, &fattr);
512         dprintk("NFS reply link: %d\n", status);
513         return status;
514 }
515
516 static int
517 nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
518                   struct iattr *sattr, struct nfs_fh *fhandle,
519                   struct nfs_fattr *fattr)
520 {
521         struct nfs_fattr        dir_attr;
522         struct nfs3_symlinkargs arg = {
523                 .fromfh         = NFS_FH(dir),
524                 .fromname       = name->name,
525                 .fromlen        = name->len,
526                 .topath         = path->name,
527                 .tolen          = path->len,
528                 .sattr          = sattr
529         };
530         struct nfs3_diropres    res = {
531                 .dir_attr       = &dir_attr,
532                 .fh             = fhandle,
533                 .fattr          = fattr
534         };
535         int                     status;
536
537         dprintk("NFS call  symlink %s -> %s\n", name->name, path->name);
538         dir_attr.valid = 0;
539         fattr->valid = 0;
540         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
541         nfs_refresh_inode(dir, &dir_attr);
542         dprintk("NFS reply symlink: %d\n", status);
543         return status;
544 }
545
546 static int
547 nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
548                 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
549 {
550         struct nfs_fattr        dir_attr;
551         struct nfs3_mkdirargs   arg = {
552                 .fh             = NFS_FH(dir),
553                 .name           = name->name,
554                 .len            = name->len,
555                 .sattr          = sattr
556         };
557         struct nfs3_diropres    res = {
558                 .dir_attr       = &dir_attr,
559                 .fh             = fhandle,
560                 .fattr          = fattr
561         };
562         int                     status;
563
564         dprintk("NFS call  mkdir %s\n", name->name);
565         dir_attr.valid = 0;
566         fattr->valid = 0;
567         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
568         nfs_refresh_inode(dir, &dir_attr);
569         dprintk("NFS reply mkdir: %d\n", status);
570         return status;
571 }
572
573 static int
574 nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
575 {
576         struct nfs_fattr        dir_attr;
577         struct nfs3_diropargs   arg = {
578                 .fh             = NFS_FH(dir),
579                 .name           = name->name,
580                 .len            = name->len
581         };
582         int                     status;
583
584         dprintk("NFS call  rmdir %s\n", name->name);
585         dir_attr.valid = 0;
586         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
587         nfs_refresh_inode(dir, &dir_attr);
588         dprintk("NFS reply rmdir: %d\n", status);
589         return status;
590 }
591
592 /*
593  * The READDIR implementation is somewhat hackish - we pass the user buffer
594  * to the encode function, which installs it in the receive iovec.
595  * The decode function itself doesn't perform any decoding, it just makes
596  * sure the reply is syntactically correct.
597  *
598  * Also note that this implementation handles both plain readdir and
599  * readdirplus.
600  */
601 static int
602 nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
603                   u64 cookie, struct page *page, unsigned int count, int plus)
604 {
605         struct inode            *dir = dentry->d_inode;
606         struct nfs_fattr        dir_attr;
607         u32                     *verf = NFS_COOKIEVERF(dir);
608         struct nfs3_readdirargs arg = {
609                 .fh             = NFS_FH(dir),
610                 .cookie         = cookie,
611                 .verf           = {verf[0], verf[1]},
612                 .plus           = plus,
613                 .count          = count,
614                 .pages          = &page
615         };
616         struct nfs3_readdirres  res = {
617                 .dir_attr       = &dir_attr,
618                 .verf           = verf,
619                 .plus           = plus
620         };
621         struct rpc_message      msg = {
622                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READDIR],
623                 .rpc_argp       = &arg,
624                 .rpc_resp       = &res,
625                 .rpc_cred       = cred
626         };
627         int                     status;
628
629         lock_kernel();
630
631         if (plus)
632                 msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
633
634         dprintk("NFS call  readdir%s %d\n",
635                         plus? "plus" : "", (unsigned int) cookie);
636
637         dir_attr.valid = 0;
638         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
639         nfs_refresh_inode(dir, &dir_attr);
640         dprintk("NFS reply readdir: %d\n", status);
641         unlock_kernel();
642         return status;
643 }
644
645 static int
646 nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
647                 dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr)
648 {
649         struct nfs_fattr        dir_attr;
650         struct nfs3_mknodargs   arg = {
651                 .fh             = NFS_FH(dir),
652                 .name           = name->name,
653                 .len            = name->len,
654                 .sattr          = sattr,
655                 .rdev           = rdev
656         };
657         struct nfs3_diropres    res = {
658                 .dir_attr       = &dir_attr,
659                 .fh             = fh,
660                 .fattr          = fattr
661         };
662         int                     status;
663
664         switch (sattr->ia_mode & S_IFMT) {
665         case S_IFBLK:   arg.type = NF3BLK;  break;
666         case S_IFCHR:   arg.type = NF3CHR;  break;
667         case S_IFIFO:   arg.type = NF3FIFO; break;
668         case S_IFSOCK:  arg.type = NF3SOCK; break;
669         default:        return -EINVAL;
670         }
671
672         dprintk("NFS call  mknod %s %u:%u\n", name->name,
673                         MAJOR(rdev), MINOR(rdev));
674         dir_attr.valid = 0;
675         fattr->valid = 0;
676         status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
677         nfs_refresh_inode(dir, &dir_attr);
678         dprintk("NFS reply mknod: %d\n", status);
679         return status;
680 }
681
682 static int
683 nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
684                  struct nfs_fsstat *stat)
685 {
686         int     status;
687
688         dprintk("NFS call  fsstat\n");
689         stat->fattr->valid = 0;
690         status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, stat, 0);
691         dprintk("NFS reply statfs: %d\n", status);
692         return status;
693 }
694
695 static int
696 nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
697                  struct nfs_fsinfo *info)
698 {
699         int     status;
700
701         dprintk("NFS call  fsinfo\n");
702         info->fattr->valid = 0;
703         status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
704         dprintk("NFS reply fsinfo: %d\n", status);
705         return status;
706 }
707
708 static int
709 nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
710                    struct nfs_pathconf *info)
711 {
712         int     status;
713
714         dprintk("NFS call  pathconf\n");
715         info->fattr->valid = 0;
716         status = rpc_call(server->client, NFS3PROC_PATHCONF, fhandle, info, 0);
717         dprintk("NFS reply pathconf: %d\n", status);
718         return status;
719 }
720
721 extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
722
723 static void
724 nfs3_read_done(struct rpc_task *task)
725 {
726         struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
727
728         if (nfs3_async_handle_jukebox(task))
729                 return;
730         /* Call back common NFS readpage processing */
731         if (task->tk_status >= 0)
732                 nfs_refresh_inode(data->inode, &data->fattr);
733         nfs_readpage_result(task);
734 }
735
736 static void
737 nfs3_proc_read_setup(struct nfs_read_data *data)
738 {
739         struct rpc_task         *task = &data->task;
740         struct inode            *inode = data->inode;
741         int                     flags;
742         struct rpc_message      msg = {
743                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READ],
744                 .rpc_argp       = &data->args,
745                 .rpc_resp       = &data->res,
746                 .rpc_cred       = data->cred,
747         };
748
749         /* N.B. Do we need to test? Never called for swapfile inode */
750         flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
751
752         /* Finalize the task. */
753         rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags);
754         rpc_call_setup(task, &msg, 0);
755 }
756
757 static void
758 nfs3_write_done(struct rpc_task *task)
759 {
760         struct nfs_write_data *data;
761
762         if (nfs3_async_handle_jukebox(task))
763                 return;
764         data = (struct nfs_write_data *)task->tk_calldata;
765         if (task->tk_status >= 0)
766                 nfs_refresh_inode(data->inode, data->res.fattr);
767         nfs_writeback_done(task);
768 }
769
770 static void
771 nfs3_proc_write_setup(struct nfs_write_data *data, int how)
772 {
773         struct rpc_task         *task = &data->task;
774         struct inode            *inode = data->inode;
775         int                     stable;
776         int                     flags;
777         struct rpc_message      msg = {
778                 .rpc_proc       = &nfs3_procedures[NFS3PROC_WRITE],
779                 .rpc_argp       = &data->args,
780                 .rpc_resp       = &data->res,
781                 .rpc_cred       = data->cred,
782         };
783
784         if (how & FLUSH_STABLE) {
785                 if (!NFS_I(inode)->ncommit)
786                         stable = NFS_FILE_SYNC;
787                 else
788                         stable = NFS_DATA_SYNC;
789         } else
790                 stable = NFS_UNSTABLE;
791         data->args.stable = stable;
792
793         /* Set the initial flags for the task.  */
794         flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
795
796         /* Finalize the task. */
797         rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags);
798         rpc_call_setup(task, &msg, 0);
799 }
800
801 static void
802 nfs3_commit_done(struct rpc_task *task)
803 {
804         struct nfs_write_data *data;
805
806         if (nfs3_async_handle_jukebox(task))
807                 return;
808         data = (struct nfs_write_data *)task->tk_calldata;
809         if (task->tk_status >= 0)
810                 nfs_refresh_inode(data->inode, data->res.fattr);
811         nfs_commit_done(task);
812 }
813
814 static void
815 nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
816 {
817         struct rpc_task         *task = &data->task;
818         struct inode            *inode = data->inode;
819         int                     flags;
820         struct rpc_message      msg = {
821                 .rpc_proc       = &nfs3_procedures[NFS3PROC_COMMIT],
822                 .rpc_argp       = &data->args,
823                 .rpc_resp       = &data->res,
824                 .rpc_cred       = data->cred,
825         };
826
827         /* Set the initial flags for the task.  */
828         flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
829
830         /* Finalize the task. */
831         rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags);
832         rpc_call_setup(task, &msg, 0);
833 }
834
835 /*
836  * Set up the nfspage struct with the right credentials
837  */
838 void
839 nfs3_request_init(struct nfs_page *req, struct file *filp)
840 {
841         req->wb_cred = get_rpccred(nfs_cred(req->wb_inode, filp));
842 }
843
844 static int
845 nfs3_request_compatible(struct nfs_page *req, struct file *filp, struct page *page)
846 {
847         if (req->wb_file != filp)
848                 return 0;
849         if (req->wb_page != page)
850                 return 0;
851         if (req->wb_cred != nfs_file_cred(filp))
852                 return 0;
853         return 1;
854 }
855
856 static int
857 nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
858 {
859         return nlmclnt_proc(filp->f_dentry->d_inode, cmd, fl);
860 }
861
862 struct nfs_rpc_ops      nfs_v3_clientops = {
863         .version        = 3,                    /* protocol version */
864         .dentry_ops     = &nfs_dentry_operations,
865         .dir_inode_ops  = &nfs_dir_inode_operations,
866         .getroot        = nfs3_proc_get_root,
867         .getattr        = nfs3_proc_getattr,
868         .setattr        = nfs3_proc_setattr,
869         .lookup         = nfs3_proc_lookup,
870         .access         = nfs3_proc_access,
871         .readlink       = nfs3_proc_readlink,
872         .read           = nfs3_proc_read,
873         .write          = nfs3_proc_write,
874         .commit         = nfs3_proc_commit,
875         .create         = nfs3_proc_create,
876         .remove         = nfs3_proc_remove,
877         .unlink_setup   = nfs3_proc_unlink_setup,
878         .unlink_done    = nfs3_proc_unlink_done,
879         .rename         = nfs3_proc_rename,
880         .link           = nfs3_proc_link,
881         .symlink        = nfs3_proc_symlink,
882         .mkdir          = nfs3_proc_mkdir,
883         .rmdir          = nfs3_proc_rmdir,
884         .readdir        = nfs3_proc_readdir,
885         .mknod          = nfs3_proc_mknod,
886         .statfs         = nfs3_proc_statfs,
887         .fsinfo         = nfs3_proc_fsinfo,
888         .pathconf       = nfs3_proc_pathconf,
889         .decode_dirent  = nfs3_decode_dirent,
890         .read_setup     = nfs3_proc_read_setup,
891         .write_setup    = nfs3_proc_write_setup,
892         .commit_setup   = nfs3_proc_commit_setup,
893         .file_open      = nfs_open,
894         .file_release   = nfs_release,
895         .request_init   = nfs3_request_init,
896         .request_compatible = nfs3_request_compatible,
897         .lock           = nfs3_proc_lock,
898 };