~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfs/nfs4proc.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  fs/nfs/nfs4proc.c
  3  *
  4  *  Client-side procedure declarations for NFSv4.
  5  *
  6  *  Copyright (c) 2002 The Regents of the University of Michigan.
  7  *  All rights reserved.
  8  *
  9  *  Kendrick Smith <kmsmith@umich.edu>
 10  *  Andy Adamson   <andros@umich.edu>
 11  *
 12  *  Redistribution and use in source and binary forms, with or without
 13  *  modification, are permitted provided that the following conditions
 14  *  are met:
 15  *
 16  *  1. Redistributions of source code must retain the above copyright
 17  *     notice, this list of conditions and the following disclaimer.
 18  *  2. Redistributions in binary form must reproduce the above copyright
 19  *     notice, this list of conditions and the following disclaimer in the
 20  *     documentation and/or other materials provided with the distribution.
 21  *  3. Neither the name of the University nor the names of its
 22  *     contributors may be used to endorse or promote products derived
 23  *     from this software without specific prior written permission.
 24  *
 25  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 26  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 27  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 28  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 29  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 30  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 31  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 32  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 33  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 34  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 35  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 36  */
 37 
 38 #include <linux/mm.h>
 39 #include <linux/utsname.h>
 40 #include <linux/errno.h>
 41 #include <linux/string.h>
 42 #include <linux/sunrpc/clnt.h>
 43 #include <linux/nfs.h>
 44 #include <linux/nfs4.h>
 45 #include <linux/nfs_fs.h>
 46 #include <linux/nfs_page.h>
 47 #include <linux/smp_lock.h>
 48 
 49 #define NFSDBG_FACILITY         NFSDBG_PROC
 50 
 51 #define GET_OP(cp,name)         &cp->ops[cp->req_nops].u.name
 52 #define OPNUM(cp)               cp->ops[cp->req_nops].opnum
 53 
 54 extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
 55 extern struct rpc_procinfo nfs4_procedures[];
 56 
 57 extern nfs4_stateid zero_stateid;
 58 
 59 static spinlock_t renew_lock = SPIN_LOCK_UNLOCKED;
 60 
 61 static void
 62 nfs4_setup_compound(struct nfs4_compound *cp, struct nfs4_op *ops,
 63                     struct nfs_server *server, char *tag)
 64 {
 65         memset(cp, 0, sizeof(*cp));
 66         cp->ops = ops;
 67         cp->server = server;
 68 }
 69 
 70 static void
 71 nfs4_setup_access(struct nfs4_compound *cp, u32 req_access, u32 *resp_supported, u32 *resp_access)
 72 {
 73         struct nfs4_access *access = GET_OP(cp, access);
 74         
 75         access->ac_req_access = req_access;
 76         access->ac_resp_supported = resp_supported;
 77         access->ac_resp_access = resp_access;
 78         
 79         OPNUM(cp) = OP_ACCESS;
 80         cp->req_nops++;
 81 }
 82 
 83 static void
 84 nfs4_setup_create_dir(struct nfs4_compound *cp, struct qstr *name,
 85                       struct iattr *sattr, struct nfs4_change_info *info)
 86 {
 87         struct nfs4_create *create = GET_OP(cp, create);
 88         
 89         create->cr_ftype = NF4DIR;
 90         create->cr_namelen = name->len;
 91         create->cr_name = name->name;
 92         create->cr_attrs = sattr;
 93         create->cr_cinfo = info;
 94         
 95         OPNUM(cp) = OP_CREATE;
 96         cp->req_nops++;
 97 }
 98 
 99 static void
100 nfs4_setup_create_symlink(struct nfs4_compound *cp, struct qstr *name,
101                           struct qstr *linktext, struct iattr *sattr,
102                           struct nfs4_change_info *info)
103 {
104         struct nfs4_create *create = GET_OP(cp, create);
105 
106         create->cr_ftype = NF4LNK;
107         create->cr_textlen = linktext->len;
108         create->cr_text = linktext->name;
109         create->cr_namelen = name->len;
110         create->cr_name = name->name;
111         create->cr_attrs = sattr;
112         create->cr_cinfo = info;
113 
114         OPNUM(cp) = OP_CREATE;
115         cp->req_nops++;
116 }
117 
118 static void
119 nfs4_setup_create_special(struct nfs4_compound *cp, struct qstr *name,
120                             dev_t dev, struct iattr *sattr,
121                             struct nfs4_change_info *info)
122 {
123         int mode = sattr->ia_mode;
124         struct nfs4_create *create = GET_OP(cp, create);
125 
126         BUG_ON(!(sattr->ia_valid & ATTR_MODE));
127         BUG_ON(!S_ISFIFO(mode) && !S_ISBLK(mode) && !S_ISCHR(mode) && !S_ISSOCK(mode));
128         
129         if (S_ISFIFO(mode))
130                 create->cr_ftype = NF4FIFO;
131         else if (S_ISBLK(mode)) {
132                 create->cr_ftype = NF4BLK;
133                 create->cr_specdata1 = MAJOR(dev);
134                 create->cr_specdata2 = MINOR(dev);
135         }
136         else if (S_ISCHR(mode)) {
137                 create->cr_ftype = NF4CHR;
138                 create->cr_specdata1 = MAJOR(dev);
139                 create->cr_specdata2 = MINOR(dev);
140         }
141         else
142                 create->cr_ftype = NF4SOCK;
143         
144         create->cr_namelen = name->len;
145         create->cr_name = name->name;
146         create->cr_attrs = sattr;
147         create->cr_cinfo = info;
148 
149         OPNUM(cp) = OP_CREATE;
150         cp->req_nops++;
151 }
152 
153 /*
154  * This is our standard bitmap for GETATTR requests.
155  */
156 u32 nfs4_fattr_bitmap[2] = {
157         FATTR4_WORD0_TYPE
158         | FATTR4_WORD0_CHANGE
159         | FATTR4_WORD0_SIZE
160         | FATTR4_WORD0_FSID
161         | FATTR4_WORD0_FILEID,
162         FATTR4_WORD1_MODE
163         | FATTR4_WORD1_NUMLINKS
164         | FATTR4_WORD1_OWNER
165         | FATTR4_WORD1_OWNER_GROUP
166         | FATTR4_WORD1_RAWDEV
167         | FATTR4_WORD1_SPACE_USED
168         | FATTR4_WORD1_TIME_ACCESS
169         | FATTR4_WORD1_TIME_METADATA
170         | FATTR4_WORD1_TIME_MODIFY
171 };
172 
173 u32 nfs4_statfs_bitmap[2] = {
174         FATTR4_WORD0_FILES_AVAIL
175         | FATTR4_WORD0_FILES_FREE
176         | FATTR4_WORD0_FILES_TOTAL,
177         FATTR4_WORD1_SPACE_AVAIL
178         | FATTR4_WORD1_SPACE_FREE
179         | FATTR4_WORD1_SPACE_TOTAL
180 };
181 
182 u32 nfs4_fsinfo_bitmap[2] = {
183         FATTR4_WORD0_MAXFILESIZE
184         | FATTR4_WORD0_MAXREAD
185         | FATTR4_WORD0_MAXWRITE
186         | FATTR4_WORD0_LEASE_TIME,
187         0
188 };
189 
190 u32 nfs4_pathconf_bitmap[2] = {
191         FATTR4_WORD0_MAXLINK
192         | FATTR4_WORD0_MAXNAME,
193         0
194 };
195 
196 /* mount bitmap: fattr bitmap + lease time */
197 u32 nfs4_mount_bitmap[2] = {
198         FATTR4_WORD0_TYPE
199         | FATTR4_WORD0_CHANGE
200         | FATTR4_WORD0_SIZE
201         | FATTR4_WORD0_FSID
202         | FATTR4_WORD0_FILEID
203         | FATTR4_WORD0_LEASE_TIME,
204         FATTR4_WORD1_MODE
205         | FATTR4_WORD1_NUMLINKS
206         | FATTR4_WORD1_OWNER
207         | FATTR4_WORD1_OWNER_GROUP
208         | FATTR4_WORD1_RAWDEV
209         | FATTR4_WORD1_SPACE_USED
210         | FATTR4_WORD1_TIME_ACCESS
211         | FATTR4_WORD1_TIME_METADATA
212         | FATTR4_WORD1_TIME_MODIFY
213 };
214 
215 static inline void
216 __nfs4_setup_getattr(struct nfs4_compound *cp, u32 *bitmap,
217                      struct nfs_fattr *fattr,
218                      struct nfs_fsstat *fsstat,
219                      struct nfs_fsinfo *fsinfo,
220                      struct nfs_pathconf *pathconf)
221 {
222         struct nfs4_getattr *getattr = GET_OP(cp, getattr);
223 
224         getattr->gt_bmval = bitmap;
225         getattr->gt_attrs = fattr;
226         getattr->gt_fsstat = fsstat;
227         getattr->gt_fsinfo = fsinfo;
228         getattr->gt_pathconf = pathconf;
229 
230         OPNUM(cp) = OP_GETATTR;
231         cp->req_nops++;
232 }
233 
234 static void
235 nfs4_setup_getattr(struct nfs4_compound *cp,
236                 struct nfs_fattr *fattr)
237 {
238         __nfs4_setup_getattr(cp, nfs4_fattr_bitmap, fattr,
239                         NULL, NULL, NULL);
240 }
241 
242 static void
243 nfs4_setup_getrootattr(struct nfs4_compound *cp,
244                 struct nfs_fattr *fattr,
245                 struct nfs_fsinfo *fsinfo)
246 {
247         __nfs4_setup_getattr(cp, nfs4_mount_bitmap,
248                         fattr, NULL, fsinfo, NULL);
249 }
250 
251 static void
252 nfs4_setup_statfs(struct nfs4_compound *cp,
253                 struct nfs_fsstat *fsstat)
254 {
255         __nfs4_setup_getattr(cp, nfs4_statfs_bitmap,
256                         NULL, fsstat, NULL, NULL);
257 }
258 
259 static void
260 nfs4_setup_fsinfo(struct nfs4_compound *cp,
261                 struct nfs_fsinfo *fsinfo)
262 {
263         __nfs4_setup_getattr(cp, nfs4_fsinfo_bitmap,
264                         NULL, NULL, fsinfo, NULL);
265 }
266 
267 static void
268 nfs4_setup_pathconf(struct nfs4_compound *cp,
269                 struct nfs_pathconf *pathconf)
270 {
271         __nfs4_setup_getattr(cp, nfs4_pathconf_bitmap,
272                         NULL, NULL, NULL, pathconf);
273 }
274 
275 static void
276 nfs4_setup_getfh(struct nfs4_compound *cp, struct nfs_fh *fhandle)
277 {
278         struct nfs4_getfh *getfh = GET_OP(cp, getfh);
279 
280         getfh->gf_fhandle = fhandle;
281 
282         OPNUM(cp) = OP_GETFH;
283         cp->req_nops++;
284 }
285 
286 static void
287 nfs4_setup_link(struct nfs4_compound *cp, struct qstr *name,
288                 struct nfs4_change_info *info)
289 {
290         struct nfs4_link *link = GET_OP(cp, link);
291 
292         link->ln_namelen = name->len;
293         link->ln_name = name->name;
294         link->ln_cinfo = info;
295 
296         OPNUM(cp) = OP_LINK;
297         cp->req_nops++;
298 }
299 
300 static void
301 nfs4_setup_lookup(struct nfs4_compound *cp, struct qstr *q)
302 {
303         struct nfs4_lookup *lookup = GET_OP(cp, lookup);
304 
305         lookup->lo_name = q;
306 
307         OPNUM(cp) = OP_LOOKUP;
308         cp->req_nops++;
309 }
310 
311 static void
312 nfs4_setup_putfh(struct nfs4_compound *cp, struct nfs_fh *fhandle)
313 {
314         struct nfs4_putfh *putfh = GET_OP(cp, putfh);
315 
316         putfh->pf_fhandle = fhandle;
317 
318         OPNUM(cp) = OP_PUTFH;
319         cp->req_nops++;
320 }
321 
322 static void
323 nfs4_setup_putrootfh(struct nfs4_compound *cp)
324 {
325         OPNUM(cp) = OP_PUTROOTFH;
326         cp->req_nops++;
327 }
328 
329 static void
330 nfs4_setup_readdir(struct nfs4_compound *cp, u64 cookie, u32 *verifier,
331                      struct page **pages, unsigned int bufsize, struct dentry *dentry)
332 {
333         u32 *start, *p;
334         struct nfs4_readdir *readdir = GET_OP(cp, readdir);
335 
336         BUG_ON(bufsize < 80);
337         readdir->rd_cookie = (cookie > 2) ? cookie : 0;
338         memcpy(&readdir->rd_req_verifier, verifier, sizeof(readdir->rd_req_verifier));
339         readdir->rd_count = bufsize;
340         readdir->rd_bmval[0] = FATTR4_WORD0_FILEID;
341         readdir->rd_bmval[1] = 0;
342         readdir->rd_pages = pages;
343         readdir->rd_pgbase = 0;
344         
345         OPNUM(cp) = OP_READDIR;
346         cp->req_nops++;
347 
348         if (cookie >= 2)
349                 return;
350         
351         /*
352          * NFSv4 servers do not return entries for '.' and '..'
353          * Therefore, we fake these entries here.  We let '.'
354          * have cookie 0 and '..' have cookie 1.  Note that
355          * when talking to the server, we always send cookie 0
356          * instead of 1 or 2.
357          */
358         start = p = (u32 *)kmap_atomic(*pages, KM_USER0);
359         
360         if (cookie == 0) {
361                 *p++ = xdr_one;                                  /* next */
362                 *p++ = xdr_zero;                   /* cookie, first word */
363                 *p++ = xdr_one;                   /* cookie, second word */
364                 *p++ = xdr_one;                             /* entry len */
365                 memcpy(p, ".\0\0\0", 4);                        /* entry */
366                 p++;
367                 *p++ = xdr_one;                         /* bitmap length */
368                 *p++ = htonl(FATTR4_WORD0_FILEID);             /* bitmap */
369                 *p++ = htonl(8);              /* attribute buffer length */
370                 p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_inode));
371         }
372         
373         *p++ = xdr_one;                                  /* next */
374         *p++ = xdr_zero;                   /* cookie, first word */
375         *p++ = xdr_two;                   /* cookie, second word */
376         *p++ = xdr_two;                             /* entry len */
377         memcpy(p, "..\0\0", 4);                         /* entry */
378         p++;
379         *p++ = xdr_one;                         /* bitmap length */
380         *p++ = htonl(FATTR4_WORD0_FILEID);             /* bitmap */
381         *p++ = htonl(8);              /* attribute buffer length */
382         p = xdr_encode_hyper(p, NFS_FILEID(dentry->d_parent->d_inode));
383 
384         readdir->rd_pgbase = (char *)p - (char *)start;
385         readdir->rd_count -= readdir->rd_pgbase;
386         kunmap_atomic(start, KM_USER0);
387 }
388 
389 static void
390 nfs4_setup_readlink(struct nfs4_compound *cp, int count, struct page **pages)
391 {
392         struct nfs4_readlink *readlink = GET_OP(cp, readlink);
393 
394         readlink->rl_count = count;
395         readlink->rl_pages = pages;
396 
397         OPNUM(cp) = OP_READLINK;
398         cp->req_nops++;
399 }
400 
401 static void
402 nfs4_setup_remove(struct nfs4_compound *cp, struct qstr *name, struct nfs4_change_info *cinfo)
403 {
404         struct nfs4_remove *remove = GET_OP(cp, remove);
405 
406         remove->rm_namelen = name->len;
407         remove->rm_name = name->name;
408         remove->rm_cinfo = cinfo;
409 
410         OPNUM(cp) = OP_REMOVE;
411         cp->req_nops++;
412 }
413 
414 static void
415 nfs4_setup_rename(struct nfs4_compound *cp, struct qstr *old, struct qstr *new,
416                   struct nfs4_change_info *old_cinfo, struct nfs4_change_info *new_cinfo)
417 {
418         struct nfs4_rename *rename = GET_OP(cp, rename);
419 
420         rename->rn_oldnamelen = old->len;
421         rename->rn_oldname = old->name;
422         rename->rn_newnamelen = new->len;
423         rename->rn_newname = new->name;
424         rename->rn_src_cinfo = old_cinfo;
425         rename->rn_dst_cinfo = new_cinfo;
426 
427         OPNUM(cp) = OP_RENAME;
428         cp->req_nops++;
429 }
430 
431 static void
432 nfs4_setup_renew(struct nfs4_compound *cp)
433 {
434         struct nfs4_client **client_state = GET_OP(cp, renew);
435 
436         *client_state = cp->server->nfs4_state;
437 
438         OPNUM(cp) = OP_RENEW;
439         cp->req_nops++;
440         cp->renew_index = cp->req_nops;
441 }
442 
443 static void
444 nfs4_setup_restorefh(struct nfs4_compound *cp)
445 {
446         OPNUM(cp) = OP_RESTOREFH;
447         cp->req_nops++;
448 }
449 
450 static void
451 nfs4_setup_savefh(struct nfs4_compound *cp)
452 {
453         OPNUM(cp) = OP_SAVEFH;
454         cp->req_nops++;
455 }
456 
457 static void
458 nfs4_setup_setclientid(struct nfs4_compound *cp, u32 program, unsigned short port)
459 {
460         struct nfs4_setclientid *setclientid = GET_OP(cp, setclientid);
461         struct nfs_server *server = cp->server;
462         struct timespec tv;
463         u32 *p;
464 
465         tv = CURRENT_TIME;
466         p = (u32 *)setclientid->sc_verifier.data;
467         *p++ = tv.tv_sec;
468         *p++ = tv.tv_nsec;
469         setclientid->sc_name = server->ip_addr;
470         sprintf(setclientid->sc_netid, "udp");
471         sprintf(setclientid->sc_uaddr, "%s.%d.%d", server->ip_addr, port >> 8, port & 255);
472         setclientid->sc_prog = program;
473         setclientid->sc_cb_ident = 0;
474         setclientid->sc_state = server->nfs4_state;
475         
476         OPNUM(cp) = OP_SETCLIENTID;
477         cp->req_nops++;
478 }
479 
480 static void
481 nfs4_setup_setclientid_confirm(struct nfs4_compound *cp)
482 {
483         struct nfs4_client **client_state = GET_OP(cp, setclientid_confirm);
484 
485         *client_state = cp->server->nfs4_state;
486 
487         OPNUM(cp) = OP_SETCLIENTID_CONFIRM;
488         cp->req_nops++;
489         cp->renew_index = cp->req_nops;
490 }
491 
492 static void
493 renew_lease(struct nfs_server *server, unsigned long timestamp)
494 {
495         spin_lock(&renew_lock);
496         if (time_before(server->last_renewal,timestamp))
497                 server->last_renewal = timestamp;
498         spin_unlock(&renew_lock);
499 }
500 
501 static inline void
502 process_lease(struct nfs4_compound *cp)
503 {
504         /*
505          * Generic lease processing: If this operation contains a
506          * lease-renewing operation, and it succeeded, update the RENEW time
507          * in the superblock.  Instead of the current time, we use the time
508          * when the request was sent out.  (All we know is that the lease was
509          * renewed sometime between then and now, and we have to assume the
510          * worst case.)
511          *
512          * Notes:
513          *   (1) renewd doesn't acquire the spinlock when messing with
514          *     server->last_renewal; this is OK since rpciod always runs
515          *     under the BKL.
516          *   (2) cp->timestamp was set at the end of XDR encode.
517          */
518         if (!cp->renew_index)
519                 return;
520         if (!cp->toplevel_status || cp->resp_nops > cp->renew_index)
521                 renew_lease(cp->server, cp->timestamp);
522 }
523 
524 static int
525 nfs4_call_compound(struct nfs4_compound *cp, struct rpc_cred *cred, int flags)
526 {
527         int status;
528         struct rpc_message msg = {
529                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND],
530                 .rpc_argp = cp,
531                 .rpc_resp = cp,
532                 .rpc_cred = cred,
533         };
534 
535         status = rpc_call_sync(cp->server->client, &msg, flags);
536         if (!status)
537                 process_lease(cp);
538         
539         return status;
540 }
541 
542 static inline void
543 process_cinfo(struct nfs4_change_info *info, struct nfs_fattr *fattr)
544 {
545         BUG_ON((fattr->valid & NFS_ATTR_FATTR) == 0);
546         BUG_ON((fattr->valid & NFS_ATTR_FATTR_V4) == 0);
547         
548         if (fattr->change_attr == info->after) {
549                 fattr->pre_change_attr = info->before;
550                 fattr->valid |= NFS_ATTR_PRE_CHANGE;
551                 fattr->timestamp = jiffies;
552         }
553 }
554 
555 struct nfs4_state *
556 nfs4_do_open(struct inode *dir, struct qstr *name, int flags, struct iattr *sattr, struct rpc_cred *cred)
557 {
558         struct nfs4_state_owner  *sp;
559         struct nfs4_state     *state = NULL;
560         struct nfs_server       *server = NFS_SERVER(dir);
561         struct inode *inode = NULL;
562         struct nfs4_change_info d_cinfo;
563         int                     status;
564         struct nfs_fattr        d_attr = {
565                 .valid          = 0,
566         };
567         struct nfs_fattr        f_attr = {
568                 .valid          = 0,
569         };
570         struct nfs4_getattr     f_getattr = {
571                 .gt_bmval       = nfs4_fattr_bitmap,
572                 .gt_attrs       = &f_attr,
573         };
574         struct nfs4_getattr     d_getattr = {
575                 .gt_bmval       = nfs4_fattr_bitmap,
576                 .gt_attrs       = &d_attr,
577         };
578         struct nfs_openargs o_arg = {
579                 .fh             = NFS_FH(dir),
580                 .share_access   = flags & (FMODE_READ|FMODE_WRITE),
581                 .clientid       = NFS_SERVER(dir)->nfs4_state->cl_clientid,
582                 .opentype       = (flags & O_CREAT) ? NFS4_OPEN_CREATE : NFS4_OPEN_NOCREATE,
583                 .createmode     = (flags & O_EXCL) ? NFS4_CREATE_EXCLUSIVE : NFS4_CREATE_UNCHECKED,
584                 .name           = name,
585                 .f_getattr      = &f_getattr,
586                 .d_getattr      = &d_getattr,
587                 .server         = server,
588         };
589         struct nfs_openres o_res = {
590                 .cinfo          = &d_cinfo,
591                 .f_getattr      = &f_getattr,
592                 .d_getattr      = &d_getattr,
593                 .server         = server,
594         };
595         struct rpc_message msg = {
596                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_OPEN],
597                 .rpc_argp       = &o_arg,
598                 .rpc_resp       = &o_res,
599                 .rpc_cred       = cred,
600         };
601 
602         status = -ENOMEM;
603         if (!(sp = nfs4_get_state_owner(NFS_SERVER(dir), cred))) {
604                 dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
605                 goto out;
606         }
607         if (o_arg.createmode & NFS4_CREATE_EXCLUSIVE){
608                 u32 *p = (u32 *) o_arg.u.verifier.data;
609                 p[0] = jiffies;
610                 p[1] = current->pid;
611         } else if (o_arg.createmode == NFS4_CREATE_UNCHECKED) {
612                 o_arg.u.attrs = sattr;
613         }
614         /* Serialization for the sequence id */
615         down(&sp->so_sema);
616         o_arg.seqid = sp->so_seqid;
617         o_arg.id = sp->so_id;
618 
619         status = rpc_call_sync(server->client, &msg, 0);
620         if (status) {
621                 goto out_up;
622         }
623         nfs4_increment_seqid(status, sp);
624         process_cinfo(&d_cinfo, &d_attr);
625         nfs_refresh_inode(dir, &d_attr);
626 
627         status = -ENOMEM;
628         inode = nfs_fhget(dir->i_sb, &o_res.fh, &f_attr);
629         if (!inode)
630                 goto out_up;
631         state = nfs4_get_open_state(inode, sp);
632         if (!state)
633                 goto out_up;
634 
635         if(o_res.rflags & NFS4_OPEN_RESULT_CONFIRM) {
636                 struct nfs_open_confirmargs oc_arg = {
637                         .fh             = &o_res.fh,
638                         .seqid          = sp->so_seqid,
639                 };
640                 struct nfs_open_confirmres oc_res = {
641                         .status         = 0,
642                 };
643                 struct  rpc_message msg = {
644                         .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM],
645                         .rpc_argp       = &oc_arg,
646                         .rpc_resp       = &oc_res,
647                         .rpc_cred       = cred,
648                 };
649 
650                 memcpy(&oc_arg.stateid, &o_res.stateid, sizeof(oc_arg.stateid));
651                 status = rpc_call_sync(server->client, &msg, 0);
652                 if (status)
653                         goto out_up;
654                 nfs4_increment_seqid(status, sp);
655                 memcpy(&state->stateid, &oc_res.stateid, sizeof(state->stateid));
656         } else
657                 memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
658         state->state |= flags & (FMODE_READ|FMODE_WRITE);
659         state->pid = current->pid;
660 
661         up(&sp->so_sema);
662         nfs4_put_state_owner(sp);
663         iput(inode);
664         return state;
665 
666 out_up:
667         up(&sp->so_sema);
668         nfs4_put_state_owner(sp);
669         if (state)
670                 nfs4_put_open_state(state);
671         if (inode)
672                 iput(inode);
673 out:
674         return ERR_PTR(status);
675 }
676 
677 int
678 nfs4_do_setattr(struct nfs_server *server, struct nfs_fattr *fattr,
679                 struct nfs_fh *fhandle, struct iattr *sattr,
680                 struct nfs4_state *state)
681 {
682         struct nfs4_getattr     getattr = {
683                 .gt_bmval       = nfs4_fattr_bitmap,
684                 .gt_attrs       = fattr,
685         };
686         struct nfs_setattrargs  arg = {
687                 .fh             = fhandle,
688                 .iap            = sattr,
689                 .attr           = &getattr,
690                 .server         = server,
691         };
692         struct nfs_setattrres  res = {
693                 .attr           = &getattr,
694                 .server         = server,
695         };
696         struct rpc_message msg = {
697                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_SETATTR],
698                 .rpc_argp       = &arg,
699                 .rpc_resp       = &res,
700         };
701 
702         fattr->valid = 0;
703 
704         if (state)
705                 memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
706         else
707                 memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
708 
709         return(rpc_call_sync(server->client, &msg, 0));
710 }
711 
712 /* 
713  * It is possible for data to be read/written from a mem-mapped file 
714  * after the sys_close call (which hits the vfs layer as a flush).
715  * This means that we can't safely call nfsv4 close on a file until 
716  * the inode is cleared. This in turn means that we are not good
717  * NFSv4 citizens - we do not indicate to the server to update the file's 
718  * share state even when we are done with one of the three share 
719  * stateid's in the inode.
720  *
721  * NOTE: Caller must be holding the sp->so_owner semaphore!
722  */
723 int
724 nfs4_do_close(struct inode *inode, struct nfs4_state *state) 
725 {
726         struct nfs4_state_owner *sp = state->owner;
727         int status = 0;
728         struct nfs_closeargs arg = {
729                 .fh             = NFS_FH(inode),
730         };
731         struct nfs_closeres res = {
732                 .status         = 0,
733         };
734         struct rpc_message msg = {
735                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
736                 .rpc_argp       = &arg,
737                 .rpc_resp       = &res,
738         };
739 
740         memcpy(&arg.stateid, &state->stateid, sizeof(arg.stateid));
741         /* Serialization for the sequence id */
742         arg.seqid = sp->so_seqid,
743         status = rpc_call_sync(NFS_SERVER(inode)->client, &msg, 0);
744 
745         /* hmm. we are done with the inode, and in the process of freeing
746          * the state_owner. we keep this around to process errors
747          */
748         nfs4_increment_seqid(status, sp);
749 
750         return status;
751 }
752 
753 static int
754 nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
755                    struct nfs_fattr *fattr)
756 {
757         struct nfs4_client      *clp;
758         struct nfs4_compound    compound;
759         struct nfs4_op          ops[4];
760         struct nfs_fsinfo       fsinfo;
761         unsigned char *         p;
762         struct qstr             q;
763         int                     status;
764 
765         clp = server->nfs4_state = nfs4_get_client(&server->addr.sin_addr);
766         if (!clp)
767                 return -ENOMEM;
768 
769         down_write(&clp->cl_sem);
770         /* Has the clientid already been initialized? */
771         if (clp->cl_state != NFS4CLNT_NEW) {
772                 /* Yep, so just read the root attributes and the lease time. */
773                 fattr->valid = 0;
774                 nfs4_setup_compound(&compound, ops, server, "getrootfh");
775                 nfs4_setup_putrootfh(&compound);
776                 nfs4_setup_getrootattr(&compound, fattr, &fsinfo);
777                 nfs4_setup_getfh(&compound, fhandle);
778                 if ((status = nfs4_call_compound(&compound, NULL, 0)))
779                         goto out_unlock;
780                 goto no_setclientid;
781         }
782 
783         /* 
784          * SETCLIENTID.
785          * Until delegations are imported, we don't bother setting the program
786          * number and port to anything meaningful.
787          */
788         nfs4_setup_compound(&compound, ops, server, "setclientid");
789         nfs4_setup_setclientid(&compound, 0, 0);
790         if ((status = nfs4_call_compound(&compound, NULL, 0)))
791                 goto out_unlock;
792 
793         /*
794          * SETCLIENTID_CONFIRM, plus root filehandle.
795          * We also get the lease time here.
796          */
797         fattr->valid = 0;
798         nfs4_setup_compound(&compound, ops, server, "setclientid_confirm");
799         nfs4_setup_setclientid_confirm(&compound);
800         nfs4_setup_putrootfh(&compound);
801         nfs4_setup_getrootattr(&compound, fattr, &fsinfo);
802         nfs4_setup_getfh(&compound, fhandle);
803         if ((status = nfs4_call_compound(&compound, NULL, 0)))
804                 goto out_unlock;
805         clp->cl_state = NFS4CLNT_OK;
806 
807 no_setclientid:
808         /*
809          * Now that we have instantiated the clientid and determined
810          * the lease time, we can initialize the renew daemon for this
811          * server.
812          * FIXME: we only need one renewd daemon per server.
813          */
814         server->lease_time = fsinfo.lease_time * HZ;
815         if ((status = nfs4_init_renewd(server)))
816                 goto out_unlock;
817         up_write(&clp->cl_sem);
818         
819         /*
820          * Now we do a separate LOOKUP for each component of the mount path.
821          * The LOOKUPs are done separately so that we can conveniently
822          * catch an ERR_WRONGSEC if it occurs along the way...
823          */
824         p = server->mnt_path;
825         for (;;) {
826                 while (*p == '/')
827                         p++;
828                 if (!*p)
829                         break;
830                 q.name = p;
831                 while (*p && (*p != '/'))
832                         p++;
833                 q.len = p - q.name;
834 
835                 fattr->valid = 0;
836                 nfs4_setup_compound(&compound, ops, server, "mount");
837                 nfs4_setup_putfh(&compound, fhandle);
838                 nfs4_setup_lookup(&compound, &q);
839                 nfs4_setup_getattr(&compound, fattr);
840                 nfs4_setup_getfh(&compound, fhandle);
841                 status = nfs4_call_compound(&compound, NULL, 0);
842                 if (!status)
843                         continue;
844                 if (status == -ENOENT) {
845                         printk(KERN_NOTICE "NFS: mount path %s does not exist!\n", server->mnt_path);
846                         printk(KERN_NOTICE "NFS: suggestion: try mounting '/' instead.\n");
847                 }
848                 break;
849         }
850         return status;
851 out_unlock:
852         up_write(&clp->cl_sem);
853         nfs4_put_client(clp);
854         return status;
855 }
856 
857 static int
858 nfs4_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
859 {
860         struct nfs4_compound compound;
861         struct nfs4_op ops[2];
862 
863         fattr->valid = 0;
864 
865         nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "getattr");
866         nfs4_setup_putfh(&compound, NFS_FH(inode));
867         nfs4_setup_getattr(&compound, fattr);
868         return nfs4_call_compound(&compound, NULL, 0);
869 }
870 
871 /* 
872  * The file is not closed if it is opened due to the a request to change
873  * the size of the file. The open call will not be needed once the
874  * VFS layer lookup-intents are implemented.
875  *
876  * Close is called when the inode is destroyed.
877  * If we haven't opened the file for O_WRONLY, we
878  * need to in the size_change case to obtain a stateid.
879  *
880  * Got race?
881  * Because OPEN is always done by name in nfsv4, it is
882  * possible that we opened a different file by the same
883  * name.  We can recognize this race condition, but we
884  * can't do anything about it besides returning an error.
885  *
886  * This will be fixed with VFS changes (lookup-intent).
887  */
888 static int
889 nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
890                   struct iattr *sattr)
891 {
892         struct inode *          inode = dentry->d_inode;
893         int                     size_change = sattr->ia_valid & ATTR_SIZE;
894         struct nfs4_state       *state = NULL;
895         int                     status;
896 
897         fattr->valid = 0;
898         
899         if (size_change) {
900                 struct rpc_cred *cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
901                 state = nfs4_do_open(dentry->d_parent->d_inode, 
902                                 &dentry->d_name, FMODE_WRITE, NULL, cred);
903                 put_rpccred(cred);
904                 if (IS_ERR(state))
905                         return PTR_ERR(state);
906 
907                 if (state->inode != inode) {
908                         printk(KERN_WARNING "nfs: raced in setattr, returning -EIO\n");
909                         nfs4_put_open_state(state);
910                         return -EIO;
911                 }
912         }
913         status = nfs4_do_setattr(NFS_SERVER(inode), fattr,
914                         NFS_FH(inode), sattr, state);
915         if (state)
916                 nfs4_put_open_state(state);
917         return status;
918 }
919 
920 static int
921 nfs4_proc_lookup(struct inode *dir, struct qstr *name,
922                  struct nfs_fh *fhandle, struct nfs_fattr *fattr)
923 {
924         struct nfs4_compound    compound;
925         struct nfs4_op          ops[5];
926         struct nfs_fattr        dir_attr;
927         int                     status;
928 
929         dir_attr.valid = 0;
930         fattr->valid = 0;
931         
932         dprintk("NFS call  lookup %s\n", name->name);
933         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "lookup");
934         nfs4_setup_putfh(&compound, NFS_FH(dir));
935         nfs4_setup_getattr(&compound, &dir_attr);
936         nfs4_setup_lookup(&compound, name);
937         nfs4_setup_getattr(&compound, fattr);
938         nfs4_setup_getfh(&compound, fhandle);
939         status = nfs4_call_compound(&compound, NULL, 0);
940         dprintk("NFS reply lookup: %d\n", status);
941 
942         if (status >= 0)
943                 status = nfs_refresh_inode(dir, &dir_attr);
944         return status;
945 }
946 
947 static int
948 nfs4_proc_access(struct inode *inode, struct rpc_cred *cred, int mode)
949 {
950         struct nfs4_compound    compound;
951         struct nfs4_op          ops[3];
952         struct nfs_fattr        fattr;
953         u32                     req_access = 0, resp_supported, resp_access;
954         int                     status;
955 
956         fattr.valid = 0;
957 
958         /*
959          * Determine which access bits we want to ask for...
960          */
961         if (mode & MAY_READ)
962                 req_access |= NFS4_ACCESS_READ;
963         if (S_ISDIR(inode->i_mode)) {
964                 if (mode & MAY_WRITE)
965                         req_access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE;
966                 if (mode & MAY_EXEC)
967                         req_access |= NFS4_ACCESS_LOOKUP;
968         }
969         else {
970                 if (mode & MAY_WRITE)
971                         req_access |= NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND;
972                 if (mode & MAY_EXEC)
973                         req_access |= NFS4_ACCESS_EXECUTE;
974         }
975 
976         nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "access");
977         nfs4_setup_putfh(&compound, NFS_FH(inode));
978         nfs4_setup_getattr(&compound, &fattr);
979         nfs4_setup_access(&compound, req_access, &resp_supported, &resp_access);
980         status = nfs4_call_compound(&compound, cred, 0);
981         nfs_refresh_inode(inode, &fattr);
982 
983         if (!status) {
984                 if (req_access != resp_supported) {
985                         printk(KERN_NOTICE "NFS: server didn't support all access bits!\n");
986                         status = -ENOTSUPP;
987                 }
988                 else if (req_access != resp_access)
989                         status = -EACCES;
990         }
991         return status;
992 }
993 
994 /*
995  * TODO: For the time being, we don't try to get any attributes
996  * along with any of the zero-copy operations READ, READDIR,
997  * READLINK, WRITE.
998  *
999  * In the case of the first three, we want to put the GETATTR
1000  * after the read-type operation -- this is because it is hard
1001  * to predict the length of a GETATTR response in v4, and thus
1002  * align the READ data correctly.  This means that the GETATTR
1003  * may end up partially falling into the page cache, and we should
1004  * shift it into the 'tail' of the xdr_buf before processing.
1005  * To do this efficiently, we need to know the total length
1006  * of data received, which doesn't seem to be available outside
1007  * of the RPC layer.
1008  *
1009  * In the case of WRITE, we also want to put the GETATTR after
1010  * the operation -- in this case because we want to make sure
1011  * we get the post-operation mtime and size.  This means that
1012  * we can't use xdr_encode_pages() as written: we need a variant
1013  * of it which would leave room in the 'tail' iovec.
1014  *
1015  * Both of these changes to the XDR layer would in fact be quite
1016  * minor, but I decided to leave them for a subsequent patch.
1017  */
1018 static int
1019 nfs4_proc_readlink(struct inode *inode, struct page *page)
1020 {
1021         struct nfs4_compound    compound;
1022         struct nfs4_op          ops[2];
1023 
1024         nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "readlink");
1025         nfs4_setup_putfh(&compound, NFS_FH(inode));
1026         nfs4_setup_readlink(&compound, PAGE_CACHE_SIZE, &page);
1027         return nfs4_call_compound(&compound, NULL, 0);
1028 }
1029 
1030 static int
1031 nfs4_proc_read(struct nfs_read_data *rdata, struct file *filp)
1032 {
1033         int flags = rdata->flags;
1034         struct inode *inode = rdata->inode;
1035         struct nfs_fattr *fattr = rdata->res.fattr;
1036         struct nfs_server *server = NFS_SERVER(inode);
1037         struct rpc_message msg = {
1038                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_READ],
1039                 .rpc_argp       = &rdata->args,
1040                 .rpc_resp       = &rdata->res,
1041         };
1042         unsigned long timestamp = jiffies;
1043         int status;
1044 
1045         dprintk("NFS call  read %d @ %Ld\n", rdata->args.count,
1046                         (long long) rdata->args.offset);
1047 
1048         /*
1049          * Try first to use O_RDONLY, then O_RDWR stateid.
1050          */
1051         if (filp) {
1052                 struct nfs4_state *state;
1053                 state = (struct nfs4_state *)filp->private_data;
1054                 memcpy(&rdata->args.stateid, &state->stateid, sizeof(rdata->args.stateid));
1055                 msg.rpc_cred = state->owner->so_cred;
1056         } else {
1057                 memcpy(&rdata->args.stateid, &zero_stateid, sizeof(rdata->args.stateid));
1058                 msg.rpc_cred = NFS_I(inode)->mm_cred;
1059         }
1060 
1061         fattr->valid = 0;
1062         status = rpc_call_sync(server->client, &msg, flags);
1063         if (!status) {
1064                 renew_lease(server, timestamp);
1065                 /* Check cache consistency */
1066                 if (fattr->change_attr != NFS_CHANGE_ATTR(inode))
1067                         nfs_zap_caches(inode);
1068         }
1069         dprintk("NFS reply read: %d\n", status);
1070         return status;
1071 }
1072 
1073 static int
1074 nfs4_proc_write(struct nfs_write_data *wdata, struct file *filp)
1075 {
1076         int rpcflags = wdata->flags;
1077         struct inode *inode = wdata->inode;
1078         struct nfs_fattr *fattr = wdata->res.fattr;
1079         struct nfs_server *server = NFS_SERVER(inode);
1080         struct rpc_message msg = {
1081                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
1082                 .rpc_argp       = &wdata->args,
1083                 .rpc_resp       = &wdata->res,
1084         };
1085         int status;
1086 
1087         dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
1088                         (long long) wdata->args.offset);
1089 
1090         /*
1091          * Try first to use O_WRONLY, then O_RDWR stateid.
1092          */
1093         if (filp) {
1094                 struct nfs4_state *state;
1095                 state = (struct nfs4_state *)filp->private_data;
1096                 memcpy(&wdata->args.stateid, &state->stateid, sizeof(wdata->args.stateid));
1097                 msg.rpc_cred = state->owner->so_cred;
1098         } else {
1099                 memcpy(&wdata->args.stateid, &zero_stateid, sizeof(wdata->args.stateid));
1100                 msg.rpc_cred = NFS_I(inode)->mm_cred;
1101         }
1102 
1103         fattr->valid = 0;
1104         status = rpc_call_sync(server->client, &msg, rpcflags);
1105         NFS_CACHEINV(inode);
1106         dprintk("NFS reply write: %d\n", status);
1107         return status;
1108 }
1109 
1110 static int
1111 nfs4_proc_commit(struct nfs_write_data *cdata, struct file *filp)
1112 {
1113         struct inode *inode = cdata->inode;
1114         struct nfs_fattr *fattr = cdata->res.fattr;
1115         struct nfs_server *server = NFS_SERVER(inode);
1116         struct rpc_message msg = {
1117                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
1118                 .rpc_argp       = &cdata->args,
1119                 .rpc_resp       = &cdata->res,
1120         };
1121         int status;
1122 
1123         dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
1124                         (long long) cdata->args.offset);
1125 
1126         /*
1127          * Try first to use O_WRONLY, then O_RDWR stateid.
1128          */
1129         if (filp) {
1130                 struct nfs4_state *state;
1131                 state = (struct nfs4_state *)filp->private_data;
1132                 memcpy(&cdata->args.stateid, &state->stateid, sizeof(cdata->args.stateid));
1133                 msg.rpc_cred = state->owner->so_cred;
1134         } else {
1135                 memcpy(&cdata->args.stateid, &zero_stateid, sizeof(cdata->args.stateid));
1136                 msg.rpc_cred = NFS_I(inode)->mm_cred;
1137         }
1138 
1139         fattr->valid = 0;
1140         status = rpc_call_sync(server->client, &msg, 0);
1141         dprintk("NFS reply commit: %d\n", status);
1142         return status;
1143 }
1144 
1145 /*
1146  * Got race?
1147  * We will need to arrange for the VFS layer to provide an atomic open.
1148  * Until then, this create/open method is prone to inefficiency and race
1149  * conditions due to the lookup, create, and open VFS calls from sys_open()
1150  * placed on the wire.
1151  *
1152  * Given the above sorry state of affairs, I'm simply sending an OPEN.
1153  * The file will be opened again in the subsequent VFS open call
1154  * (nfs4_proc_file_open).
1155  *
1156  * The open for read will just hang around to be used by any process that
1157  * opens the file O_RDONLY. This will all be resolved with the VFS changes.
1158  */
1159 
1160 static struct inode *
1161 nfs4_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
1162                  int flags)
1163 {
1164         struct inode *inode;
1165         struct nfs4_state *state = NULL;
1166         struct rpc_cred *cred;
1167 
1168         cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
1169         state = nfs4_do_open(dir, name, flags, sattr, cred);
1170         put_rpccred(cred);
1171         if (!IS_ERR(state)) {
1172                 inode = igrab(state->inode);
1173                 if (flags & O_EXCL) {
1174                         struct nfs_fattr fattr;
1175                         int status;
1176                         status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
1177                                              NFS_FH(inode), sattr, state);
1178                         if (status != 0) {
1179                                 iput(inode);
1180                                 inode = ERR_PTR(status);
1181                         }
1182                 }
1183                 nfs4_put_open_state(state);
1184         } else
1185                 inode = (struct inode *)state;
1186         return inode;
1187 }
1188 
1189 static int
1190 nfs4_proc_remove(struct inode *dir, struct qstr *name)
1191 {
1192         struct nfs4_compound    compound;
1193         struct nfs4_op          ops[3];
1194         struct nfs4_change_info dir_cinfo;
1195         struct nfs_fattr        dir_attr;
1196         int                     status;
1197 
1198         dir_attr.valid = 0;
1199         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "remove");
1200         nfs4_setup_putfh(&compound, NFS_FH(dir));
1201         nfs4_setup_remove(&compound, name, &dir_cinfo);
1202         nfs4_setup_getattr(&compound, &dir_attr);
1203         status = nfs4_call_compound(&compound, NULL, 0);
1204 
1205         if (!status) {
1206                 process_cinfo(&dir_cinfo, &dir_attr);
1207                 nfs_refresh_inode(dir, &dir_attr);
1208         }
1209         return status;
1210 }
1211 
1212 struct unlink_desc {
1213         struct nfs4_compound    compound;
1214         struct nfs4_op          ops[3];
1215         struct nfs4_change_info cinfo;
1216         struct nfs_fattr        attrs;
1217 };
1218 
1219 static int
1220 nfs4_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
1221 {
1222         struct unlink_desc *    up;
1223         struct nfs4_compound *  cp;
1224 
1225         up = (struct unlink_desc *) kmalloc(sizeof(*up), GFP_KERNEL);
1226         if (!up)
1227                 return -ENOMEM;
1228         cp = &up->compound;
1229         
1230         nfs4_setup_compound(cp, up->ops, NFS_SERVER(dir->d_inode), "unlink_setup");
1231         nfs4_setup_putfh(cp, NFS_FH(dir->d_inode));
1232         nfs4_setup_remove(cp, name, &up->cinfo);
1233         nfs4_setup_getattr(cp, &up->attrs);
1234         
1235         msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND];
1236         msg->rpc_argp = cp;
1237         msg->rpc_resp = cp;
1238         return 0;
1239 }
1240 
1241 static int
1242 nfs4_proc_unlink_done(struct dentry *dir, struct rpc_task *task)
1243 {
1244         struct rpc_message *msg = &task->tk_msg;
1245         struct unlink_desc *up;
1246         
1247         if (msg->rpc_argp) {
1248                 up = (struct unlink_desc *) msg->rpc_argp;
1249                 process_lease(&up->compound);
1250                 process_cinfo(&up->cinfo, &up->attrs);
1251                 nfs_refresh_inode(dir->d_inode, &up->attrs);
1252                 kfree(up);
1253                 msg->rpc_argp = NULL;
1254         }
1255         return 0;
1256 }
1257 
1258 static int
1259 nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
1260                  struct inode *new_dir, struct qstr *new_name)
1261 {
1262         struct nfs4_compound    compound;
1263         struct nfs4_op          ops[7];
1264         struct nfs4_change_info old_cinfo, new_cinfo;
1265         struct nfs_fattr        old_dir_attr, new_dir_attr;
1266         int                     status;
1267 
1268         old_dir_attr.valid = 0;
1269         new_dir_attr.valid = 0;
1270         
1271         nfs4_setup_compound(&compound, ops, NFS_SERVER(old_dir), "rename");
1272         nfs4_setup_putfh(&compound, NFS_FH(old_dir));
1273         nfs4_setup_savefh(&compound);
1274         nfs4_setup_putfh(&compound, NFS_FH(new_dir));
1275         nfs4_setup_rename(&compound, old_name, new_name, &old_cinfo, &new_cinfo);
1276         nfs4_setup_getattr(&compound, &new_dir_attr);
1277         nfs4_setup_restorefh(&compound);
1278         nfs4_setup_getattr(&compound, &old_dir_attr);
1279         status = nfs4_call_compound(&compound, NULL, 0);
1280 
1281         if (!status) {
1282                 process_cinfo(&old_cinfo, &old_dir_attr);
1283                 process_cinfo(&new_cinfo, &new_dir_attr);
1284                 nfs_refresh_inode(old_dir, &old_dir_attr);
1285                 nfs_refresh_inode(new_dir, &new_dir_attr);
1286         }
1287         return status;
1288 }
1289 
1290 static int
1291 nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
1292 {
1293         struct nfs4_compound    compound;
1294         struct nfs4_op          ops[7];
1295         struct nfs4_change_info dir_cinfo;
1296         struct nfs_fattr        dir_attr, fattr;
1297         int                     status;
1298         
1299         dir_attr.valid = 0;
1300         fattr.valid = 0;
1301         
1302         nfs4_setup_compound(&compound, ops, NFS_SERVER(inode), "link");
1303         nfs4_setup_putfh(&compound, NFS_FH(inode));
1304         nfs4_setup_savefh(&compound);
1305         nfs4_setup_putfh(&compound, NFS_FH(dir));
1306         nfs4_setup_link(&compound, name, &dir_cinfo);
1307         nfs4_setup_getattr(&compound, &dir_attr);
1308         nfs4_setup_restorefh(&compound);
1309         nfs4_setup_getattr(&compound, &fattr);
1310         status = nfs4_call_compound(&compound, NULL, 0);
1311 
1312         if (!status) {
1313                 process_cinfo(&dir_cinfo, &dir_attr);
1314                 nfs_refresh_inode(dir, &dir_attr);
1315                 nfs_refresh_inode(inode, &fattr);
1316         }
1317         return status;
1318 }
1319 
1320 static int
1321 nfs4_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
1322                   struct iattr *sattr, struct nfs_fh *fhandle,
1323                   struct nfs_fattr *fattr)
1324 {
1325         struct nfs4_compound    compound;
1326         struct nfs4_op          ops[7];
1327         struct nfs_fattr        dir_attr;
1328         struct nfs4_change_info dir_cinfo;
1329         int                     status;
1330 
1331         dir_attr.valid = 0;
1332         fattr->valid = 0;
1333         
1334         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "symlink");
1335         nfs4_setup_putfh(&compound, NFS_FH(dir));
1336         nfs4_setup_savefh(&compound);
1337         nfs4_setup_create_symlink(&compound, name, path, sattr, &dir_cinfo);
1338         nfs4_setup_getattr(&compound, fattr);
1339         nfs4_setup_getfh(&compound, fhandle);
1340         nfs4_setup_restorefh(&compound);
1341         nfs4_setup_getattr(&compound, &dir_attr);
1342         status = nfs4_call_compound(&compound, NULL, 0);
1343 
1344         if (!status) {
1345                 process_cinfo(&dir_cinfo, &dir_attr);
1346                 nfs_refresh_inode(dir, &dir_attr);
1347         }
1348         return status;
1349 }
1350 
1351 static int
1352 nfs4_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
1353                 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
1354 {
1355         struct nfs4_compound    compound;
1356         struct nfs4_op          ops[7];
1357         struct nfs_fattr        dir_attr;
1358         struct nfs4_change_info dir_cinfo;
1359         int                     status;
1360 
1361         dir_attr.valid = 0;
1362         fattr->valid = 0;
1363         
1364         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "mkdir");
1365         nfs4_setup_putfh(&compound, NFS_FH(dir));
1366         nfs4_setup_savefh(&compound);
1367         nfs4_setup_create_dir(&compound, name, sattr, &dir_cinfo);
1368         nfs4_setup_getattr(&compound, fattr);
1369         nfs4_setup_getfh(&compound, fhandle);
1370         nfs4_setup_restorefh(&compound);
1371         nfs4_setup_getattr(&compound, &dir_attr);
1372         status = nfs4_call_compound(&compound, NULL, 0);
1373 
1374         if (!status) {
1375                 process_cinfo(&dir_cinfo, &dir_attr);
1376                 nfs_refresh_inode(dir, &dir_attr);
1377         }
1378         return status;
1379 }
1380 
1381 static int
1382 nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
1383                   u64 cookie, struct page *page, unsigned int count, int plus)
1384 {
1385         struct inode            *dir = dentry->d_inode;
1386         struct nfs4_compound    compound;
1387         struct nfs4_op          ops[2];
1388         int                     status;
1389 
1390         lock_kernel();
1391 
1392         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "readdir");
1393         nfs4_setup_putfh(&compound, NFS_FH(dir));
1394         nfs4_setup_readdir(&compound, cookie, NFS_COOKIEVERF(dir), &page, count, dentry);
1395         status = nfs4_call_compound(&compound, cred, 0);
1396 
1397         unlock_kernel();
1398         return status;
1399 }
1400 
1401 static int
1402 nfs4_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
1403                 dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr)
1404 {
1405         struct nfs4_compound    compound;
1406         struct nfs4_op          ops[7];
1407         struct nfs_fattr        dir_attr;
1408         struct nfs4_change_info dir_cinfo;
1409         int                     status;
1410 
1411         dir_attr.valid = 0;
1412         fattr->valid = 0;
1413         
1414         nfs4_setup_compound(&compound, ops, NFS_SERVER(dir), "mknod");
1415         nfs4_setup_putfh(&compound, NFS_FH(dir));
1416         nfs4_setup_savefh(&compound);
1417         nfs4_setup_create_special(&compound, name, rdev,sattr, &dir_cinfo);
1418         nfs4_setup_getattr(&compound, fattr);
1419         nfs4_setup_getfh(&compound, fh);
1420         nfs4_setup_restorefh(&compound);
1421         nfs4_setup_getattr(&compound, &dir_attr);
1422         status = nfs4_call_compound(&compound, NULL, 0);
1423 
1424         if (!status) {
1425                 process_cinfo(&dir_cinfo, &dir_attr);
1426                 nfs_refresh_inode(dir, &dir_attr);
1427         }
1428         return status;
1429 }
1430 
1431 static int
1432 nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
1433                  struct nfs_fsstat *fsstat)
1434 {
1435         struct nfs4_compound compound;
1436         struct nfs4_op ops[2];
1437 
1438         memset(fsstat, 0, sizeof(*fsstat));
1439         nfs4_setup_compound(&compound, ops, server, "statfs");
1440         nfs4_setup_putfh(&compound, fhandle);
1441         nfs4_setup_statfs(&compound, fsstat);
1442         return nfs4_call_compound(&compound, NULL, 0);
1443 }
1444 
1445 static int
1446 nfs4_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
1447                  struct nfs_fsinfo *fsinfo)
1448 {
1449         struct nfs4_compound compound;
1450         struct nfs4_op ops[2];
1451 
1452         memset(fsinfo, 0, sizeof(*fsinfo));
1453         nfs4_setup_compound(&compound, ops, server, "statfs");
1454         nfs4_setup_putfh(&compound, fhandle);
1455         nfs4_setup_fsinfo(&compound, fsinfo);
1456         return nfs4_call_compound(&compound, NULL, 0);
1457 }
1458 
1459 static int
1460 nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
1461                    struct nfs_pathconf *pathconf)
1462 {
1463         struct nfs4_compound compound;
1464         struct nfs4_op ops[2];
1465 
1466         memset(pathconf, 0, sizeof(*pathconf));
1467         nfs4_setup_compound(&compound, ops, server, "statfs");
1468         nfs4_setup_putfh(&compound, fhandle);
1469         nfs4_setup_pathconf(&compound, pathconf);
1470         return nfs4_call_compound(&compound, NULL, 0);
1471 }
1472 
1473 static void
1474 nfs4_read_done(struct rpc_task *task)
1475 {
1476         struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
1477         struct inode *inode = data->inode;
1478         struct nfs_fattr *fattr = data->res.fattr;
1479 
1480         if (task->tk_status > 0)
1481                 renew_lease(NFS_SERVER(inode), data->timestamp);
1482         /* Check cache consistency */
1483         if (fattr->change_attr != NFS_CHANGE_ATTR(inode))
1484                 nfs_zap_caches(inode);
1485         if (fattr->bitmap[1] & FATTR4_WORD1_TIME_ACCESS)
1486                 inode->i_atime = fattr->atime;
1487         /* Call back common NFS readpage processing */
1488         nfs_readpage_result(task);
1489 }
1490 
1491 static void
1492 nfs4_proc_read_setup(struct nfs_read_data *data, unsigned int count)
1493 {
1494         struct rpc_task *task = &data->task;
1495         struct rpc_message msg = {
1496                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ],
1497                 .rpc_argp = &data->args,
1498                 .rpc_resp = &data->res,
1499                 .rpc_cred = data->cred,
1500         };
1501         struct inode *inode = data->inode;
1502         struct nfs_page *req = nfs_list_entry(data->pages.next);
1503         int flags;
1504 
1505         data->args.fh     = NFS_FH(inode);
1506         data->args.offset = req_offset(req);
1507         data->args.pgbase = req->wb_pgbase;
1508         data->args.pages  = data->pagevec;
1509         data->args.count  = count;
1510         data->res.fattr   = &data->fattr;
1511         data->res.count   = count;
1512         data->res.eof     = 0;
1513         data->timestamp   = jiffies;
1514 
1515         if (req->wb_state)
1516                 memcpy(&data->args.stateid, &req->wb_state->stateid, sizeof(data->args.stateid));
1517         else
1518                 memcpy(&data->args.stateid, &zero_stateid, sizeof(data->args.stateid));
1519 
1520         /* N.B. Do we need to test? Never called for swapfile inode */
1521         flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
1522 
1523         /* Finalize the task. */
1524         rpc_init_task(task, NFS_CLIENT(inode), nfs4_read_done, flags);
1525         task->tk_calldata = data;
1526         /* Release requests */
1527         task->tk_release = nfs_readdata_release;
1528 
1529         rpc_call_setup(task, &msg, 0);
1530 }
1531 
1532 static void
1533 nfs4_write_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1534 {
1535         /* Check cache consistency */
1536         if (fattr->pre_change_attr != NFS_CHANGE_ATTR(inode))
1537                 nfs_zap_caches(inode);
1538         NFS_CHANGE_ATTR(inode) = fattr->change_attr;
1539         if (fattr->bitmap[1] & FATTR4_WORD1_SPACE_USED)
1540                 inode->i_blocks = (fattr->du.nfs3.used + 511) >> 9;
1541         if (fattr->bitmap[1] & FATTR4_WORD1_TIME_METADATA)
1542                 inode->i_ctime = fattr->ctime;
1543         if (fattr->bitmap[1] & FATTR4_WORD1_TIME_MODIFY)
1544                 inode->i_mtime = fattr->mtime;
1545 }
1546 
1547 static void
1548 nfs4_write_done(struct rpc_task *task)
1549 {
1550         struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
1551         struct inode *inode = data->inode;
1552         
1553         if (task->tk_status >= 0)
1554                 renew_lease(NFS_SERVER(inode), data->timestamp);
1555         nfs4_write_refresh_inode(inode, data->res.fattr);
1556         /* Call back common NFS writeback processing */
1557         nfs_writeback_done(task);
1558 }
1559 
1560 static void
1561 nfs4_proc_write_setup(struct nfs_write_data *data, unsigned int count, int how)
1562 {
1563         struct rpc_task *task = &data->task;
1564         struct rpc_message msg = {
1565                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE],
1566                 .rpc_argp = &data->args,
1567                 .rpc_resp = &data->res,
1568                 .rpc_cred = data->cred,
1569         };
1570         struct inode *inode = data->inode;
1571         struct nfs_page *req = nfs_list_entry(data->pages.next);
1572         int stable;
1573         int flags;
1574         
1575         if (how & FLUSH_STABLE) {
1576                 if (!NFS_I(inode)->ncommit)
1577                         stable = NFS_FILE_SYNC;
1578                 else
1579                         stable = NFS_DATA_SYNC;
1580         } else
1581                 stable = NFS_UNSTABLE;
1582 
1583         data->args.fh     = NFS_FH(inode);
1584         data->args.offset = req_offset(req);
1585         data->args.pgbase = req->wb_pgbase;
1586         data->args.count  = count;
1587         data->args.stable = stable;
1588         data->args.pages  = data->pagevec;
1589         data->res.fattr   = &data->fattr;
1590         data->res.count   = count;
1591         data->res.verf    = &data->verf;
1592         data->timestamp   = jiffies;
1593 
1594         if (req->wb_state)
1595                 memcpy(&data->args.stateid, &req->wb_state->stateid, sizeof(data->args.stateid));
1596         else
1597                 memcpy(&data->args.stateid, &zero_stateid, sizeof(data->args.stateid));
1598 
1599         /* Set the initial flags for the task.  */
1600         flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
1601 
1602         /* Finalize the task. */
1603         rpc_init_task(task, NFS_CLIENT(inode), nfs4_write_done, flags);
1604         task->tk_calldata = data;
1605         /* Release requests */
1606         task->tk_release = nfs_writedata_release;
1607 
1608         rpc_call_setup(task, &msg, 0);
1609 }
1610 
1611 static void
1612 nfs4_commit_done(struct rpc_task *task)
1613 {
1614         struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
1615         
1616         nfs4_write_refresh_inode(data->inode, data->res.fattr);
1617         /* Call back common NFS writeback processing */
1618         nfs_commit_done(task);
1619 }
1620 
1621 static void
1622 nfs4_proc_commit_setup(struct nfs_write_data *data, u64 start, u32 len, int how)
1623 {
1624         struct rpc_task *task = &data->task;
1625         struct rpc_message msg = {
1626                 .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT],
1627                 .rpc_argp = &data->args,
1628                 .rpc_resp = &data->res,
1629                 .rpc_cred = data->cred,
1630         };      
1631         struct inode *inode = data->inode;
1632         int flags;
1633         
1634         data->args.fh     = NFS_FH(data->inode);
1635         data->args.offset = start;
1636         data->args.count  = len;
1637         data->res.count   = len;
1638         data->res.fattr   = &data->fattr;
1639         data->res.verf    = &data->verf;
1640         
1641         /* Set the initial flags for the task.  */
1642         flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
1643 
1644         /* Finalize the task. */
1645         rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags);
1646         task->tk_calldata = data;
1647         /* Release requests */
1648         task->tk_release = nfs_commit_release;
1649         
1650         rpc_call_setup(task, &msg, 0);  
1651 }
1652 
1653 /*
1654  * nfs4_proc_renew(): This is not one of the nfs_rpc_ops; it is a special
1655  * standalone procedure for queueing an asynchronous RENEW.
1656  */
1657 struct renew_desc {
1658         struct rpc_task         task;
1659         struct nfs4_compound    compound;
1660         struct nfs4_op          ops[1];
1661 };
1662 
1663 static void
1664 renew_done(struct rpc_task *task)
1665 {
1666         struct nfs4_compound *cp = (struct nfs4_compound *) task->tk_msg.rpc_argp;
1667         process_lease(cp);
1668 }
1669 
1670 static void
1671 renew_release(struct rpc_task *task)
1672 {
1673         kfree(task->tk_calldata);
1674 }
1675 
1676 int
1677 nfs4_proc_renew(struct nfs_server *server)
1678 {
1679         struct renew_desc *rp;
1680         struct rpc_task *task;
1681         struct nfs4_compound *cp;
1682         struct rpc_message msg = {
1683                 .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_COMPOUND],
1684         };
1685 
1686         rp = (struct renew_desc *) kmalloc(sizeof(*rp), GFP_KERNEL);
1687         if (!rp)
1688                 return -ENOMEM;
1689         cp = &rp->compound;
1690         task = &rp->task;
1691         
1692         nfs4_setup_compound(cp, rp->ops, server, "renew");
1693         nfs4_setup_renew(cp);
1694         
1695         msg.rpc_argp = cp;
1696         msg.rpc_resp = cp;
1697         rpc_init_task(task, server->client, renew_done, RPC_TASK_ASYNC);
1698         rpc_call_setup(task, &msg, 0);
1699         task->tk_calldata = rp;
1700         task->tk_release = renew_release;
1701         
1702         return rpc_execute(task);
1703 }
1704 
1705 /*
1706  * We will need to arrange for the VFS layer to provide an atomic open.
1707  * Until then, this open method is prone to inefficiency and race conditions
1708  * due to the lookup, potential create, and open VFS calls from sys_open()
1709  * placed on the wire.
1710  */
1711 static int
1712 nfs4_proc_file_open(struct inode *inode, struct file *filp)
1713 {
1714         struct dentry *dentry = filp->f_dentry;
1715         struct inode *dir = dentry->d_parent->d_inode;
1716         struct rpc_cred *cred;
1717         struct nfs4_state *state;
1718         int flags = filp->f_flags;
1719         int status = 0;
1720 
1721         dprintk("nfs4_proc_file_open: starting on (%.*s/%.*s)\n",
1722                                (int)dentry->d_parent->d_name.len,
1723                                dentry->d_parent->d_name.name,
1724                                (int)dentry->d_name.len, dentry->d_name.name);
1725 
1726         if ((flags + 1) & O_ACCMODE)
1727                 flags++;
1728 
1729         lock_kernel();
1730 
1731 /*
1732 * We have already opened the file "O_EXCL" in nfs4_proc_create!!
1733 * This ugliness will go away with lookup-intent...
1734 */
1735         cred = rpcauth_lookupcred(NFS_SERVER(inode)->client->cl_auth, 0);
1736         state = nfs4_do_open(dir, &dentry->d_name, flags, NULL, cred);
1737         if (IS_ERR(state)) {
1738                 status = PTR_ERR(state);
1739                 state = NULL;
1740         } else if (filp->f_mode & FMODE_WRITE)
1741                 nfs_set_mmcred(inode, cred);
1742         if (inode != filp->f_dentry->d_inode) {
1743                 printk(KERN_WARNING "NFS: v4 raced in function %s\n", __FUNCTION__);
1744                 status = -EIO; /* ERACE actually */
1745                 nfs4_put_open_state(state);
1746                 state = NULL;
1747         }
1748         filp->private_data = state;
1749         put_rpccred(cred);
1750         unlock_kernel();
1751         return status;
1752 }
1753 
1754 /*
1755  * Release our state
1756  */
1757 static int
1758 nfs4_proc_file_release(struct inode *inode, struct file *filp)
1759 {
1760         struct nfs4_state *state = (struct nfs4_state *)filp->private_data;
1761 
1762         if (state)
1763                 nfs4_put_open_state(state);
1764         return 0;
1765 }
1766 
1767 /*
1768  * Set up the nfspage struct with the right state info and credentials
1769  */
1770 static void
1771 nfs4_request_init(struct nfs_page *req, struct file *filp)
1772 {
1773         struct nfs4_state *state;
1774 
1775         if (!filp) {
1776                 req->wb_cred = get_rpccred(NFS_I(req->wb_inode)->mm_cred);
1777                 req->wb_state = NULL;
1778                 return;
1779         }
1780         state = (struct nfs4_state *)filp->private_data;
1781         req->wb_state = state;
1782         req->wb_cred = get_rpccred(state->owner->so_cred);
1783 }
1784 
1785 
1786 static int
1787 nfs4_request_compatible(struct nfs_page *req, struct file *filp, struct page *page)
1788 {
1789         struct nfs4_state *state = NULL;
1790         struct rpc_cred *cred = NULL;
1791 
1792         if (req->wb_file != filp)
1793                 return 0;
1794         if (req->wb_page != page)
1795                 return 0;
1796         state = (struct nfs4_state *)filp->private_data;
1797         if (req->wb_state != state)
1798                 return 0;
1799         cred = state->owner->so_cred;
1800         if (req->wb_cred != cred)
1801                 return 0;
1802         return 1;
1803 }
1804 
1805 struct nfs_rpc_ops      nfs_v4_clientops = {
1806         .version        = 4,                    /* protocol version */
1807         .getroot        = nfs4_proc_get_root,
1808         .getattr        = nfs4_proc_getattr,
1809         .setattr        = nfs4_proc_setattr,
1810         .lookup         = nfs4_proc_lookup,
1811         .access         = nfs4_proc_access,
1812         .readlink       = nfs4_proc_readlink,
1813         .read           = nfs4_proc_read,
1814         .write          = nfs4_proc_write,
1815         .commit         = nfs4_proc_commit,
1816         .create         = nfs4_proc_create,
1817         .remove         = nfs4_proc_remove,
1818         .unlink_setup   = nfs4_proc_unlink_setup,
1819         .unlink_done    = nfs4_proc_unlink_done,
1820         .rename         = nfs4_proc_rename,
1821         .link           = nfs4_proc_link,
1822         .symlink        = nfs4_proc_symlink,
1823         .mkdir          = nfs4_proc_mkdir,
1824         .rmdir          = nfs4_proc_remove,
1825         .readdir        = nfs4_proc_readdir,
1826         .mknod          = nfs4_proc_mknod,
1827         .statfs         = nfs4_proc_statfs,
1828         .fsinfo         = nfs4_proc_fsinfo,
1829         .pathconf       = nfs4_proc_pathconf,
1830         .decode_dirent  = nfs4_decode_dirent,
1831         .read_setup     = nfs4_proc_read_setup,
1832         .write_setup    = nfs4_proc_write_setup,
1833         .commit_setup   = nfs4_proc_commit_setup,
1834         .file_open      = nfs4_proc_file_open,
1835         .file_release   = nfs4_proc_file_release,
1836         .request_init   = nfs4_request_init,
1837         .request_compatible = nfs4_request_compatible,
1838 };
1839 
1840 /*
1841  * Local variables:
1842  *  c-basic-offset: 8
1843  * End:
1844  */
1845 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp