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

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

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.10 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.83 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.153 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.200 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.200 ] ~ [ 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.76 ] ~ [ 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-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ 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  *  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/errno.h>
 11 #include <linux/string.h>
 12 #include <linux/sunrpc/clnt.h>
 13 #include <linux/slab.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/nfs_mount.h>
 20 #include <linux/freezer.h>
 21 #include <linux/xattr.h>
 22 
 23 #include "iostat.h"
 24 #include "internal.h"
 25 #include "nfs3_fs.h"
 26 
 27 #define NFSDBG_FACILITY         NFSDBG_PROC
 28 
 29 /* A wrapper to handle the EJUKEBOX error messages */
 30 static int
 31 nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
 32 {
 33         int res;
 34         do {
 35                 res = rpc_call_sync(clnt, msg, flags);
 36                 if (res != -EJUKEBOX)
 37                         break;
 38                 freezable_schedule_timeout_killable_unsafe(NFS_JUKEBOX_RETRY_TIME);
 39                 res = -ERESTARTSYS;
 40         } while (!fatal_signal_pending(current));
 41         return res;
 42 }
 43 
 44 #define rpc_call_sync(clnt, msg, flags) nfs3_rpc_wrapper(clnt, msg, flags)
 45 
 46 static int
 47 nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
 48 {
 49         if (task->tk_status != -EJUKEBOX)
 50                 return 0;
 51         if (task->tk_status == -EJUKEBOX)
 52                 nfs_inc_stats(inode, NFSIOS_DELAY);
 53         task->tk_status = 0;
 54         rpc_restart_call(task);
 55         rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
 56         return 1;
 57 }
 58 
 59 static int
 60 do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
 61                  struct nfs_fsinfo *info)
 62 {
 63         struct rpc_message msg = {
 64                 .rpc_proc       = &nfs3_procedures[NFS3PROC_FSINFO],
 65                 .rpc_argp       = fhandle,
 66                 .rpc_resp       = info,
 67         };
 68         int     status;
 69 
 70         dprintk("%s: call  fsinfo\n", __func__);
 71         nfs_fattr_init(info->fattr);
 72         status = rpc_call_sync(client, &msg, 0);
 73         dprintk("%s: reply fsinfo: %d\n", __func__, status);
 74         if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
 75                 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
 76                 msg.rpc_resp = info->fattr;
 77                 status = rpc_call_sync(client, &msg, 0);
 78                 dprintk("%s: reply getattr: %d\n", __func__, status);
 79         }
 80         return status;
 81 }
 82 
 83 /*
 84  * Bare-bones access to getattr: this is for nfs_get_root/nfs_get_sb
 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         status = do_proc_get_root(server->client, fhandle, info);
 93         if (status && server->nfs_client->cl_rpcclient != server->client)
 94                 status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
 95         return status;
 96 }
 97 
 98 /*
 99  * One function for each procedure in the NFS protocol.
100  */
101 static int
102 nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
103                 struct nfs_fattr *fattr, struct nfs4_label *label)
104 {
105         struct rpc_message msg = {
106                 .rpc_proc       = &nfs3_procedures[NFS3PROC_GETATTR],
107                 .rpc_argp       = fhandle,
108                 .rpc_resp       = fattr,
109         };
110         int     status;
111 
112         dprintk("NFS call  getattr\n");
113         nfs_fattr_init(fattr);
114         status = rpc_call_sync(server->client, &msg, 0);
115         dprintk("NFS reply getattr: %d\n", status);
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 = d_inode(dentry);
124         struct nfs3_sattrargs   arg = {
125                 .fh             = NFS_FH(inode),
126                 .sattr          = sattr,
127         };
128         struct rpc_message msg = {
129                 .rpc_proc       = &nfs3_procedures[NFS3PROC_SETATTR],
130                 .rpc_argp       = &arg,
131                 .rpc_resp       = fattr,
132         };
133         int     status;
134 
135         dprintk("NFS call  setattr\n");
136         if (sattr->ia_valid & ATTR_FILE)
137                 msg.rpc_cred = nfs_file_cred(sattr->ia_file);
138         nfs_fattr_init(fattr);
139         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
140         if (status == 0)
141                 nfs_setattr_update_inode(inode, sattr, fattr);
142         dprintk("NFS reply setattr: %d\n", status);
143         return status;
144 }
145 
146 static int
147 nfs3_proc_lookup(struct inode *dir, const struct qstr *name,
148                  struct nfs_fh *fhandle, struct nfs_fattr *fattr,
149                  struct nfs4_label *label)
150 {
151         struct nfs3_diropargs   arg = {
152                 .fh             = NFS_FH(dir),
153                 .name           = name->name,
154                 .len            = name->len
155         };
156         struct nfs3_diropres    res = {
157                 .fh             = fhandle,
158                 .fattr          = fattr
159         };
160         struct rpc_message msg = {
161                 .rpc_proc       = &nfs3_procedures[NFS3PROC_LOOKUP],
162                 .rpc_argp       = &arg,
163                 .rpc_resp       = &res,
164         };
165         int                     status;
166 
167         dprintk("NFS call  lookup %s\n", name->name);
168         res.dir_attr = nfs_alloc_fattr();
169         if (res.dir_attr == NULL)
170                 return -ENOMEM;
171 
172         nfs_fattr_init(fattr);
173         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
174         nfs_refresh_inode(dir, res.dir_attr);
175         if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
176                 msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
177                 msg.rpc_argp = fhandle;
178                 msg.rpc_resp = fattr;
179                 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
180         }
181         nfs_free_fattr(res.dir_attr);
182         dprintk("NFS reply lookup: %d\n", status);
183         return status;
184 }
185 
186 static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
187 {
188         struct nfs3_accessargs  arg = {
189                 .fh             = NFS_FH(inode),
190         };
191         struct nfs3_accessres   res;
192         struct rpc_message msg = {
193                 .rpc_proc       = &nfs3_procedures[NFS3PROC_ACCESS],
194                 .rpc_argp       = &arg,
195                 .rpc_resp       = &res,
196                 .rpc_cred       = entry->cred,
197         };
198         int mode = entry->mask;
199         int status = -ENOMEM;
200 
201         dprintk("NFS call  access\n");
202 
203         if (mode & MAY_READ)
204                 arg.access |= NFS3_ACCESS_READ;
205         if (S_ISDIR(inode->i_mode)) {
206                 if (mode & MAY_WRITE)
207                         arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
208                 if (mode & MAY_EXEC)
209                         arg.access |= NFS3_ACCESS_LOOKUP;
210         } else {
211                 if (mode & MAY_WRITE)
212                         arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
213                 if (mode & MAY_EXEC)
214                         arg.access |= NFS3_ACCESS_EXECUTE;
215         }
216 
217         res.fattr = nfs_alloc_fattr();
218         if (res.fattr == NULL)
219                 goto out;
220 
221         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
222         nfs_refresh_inode(inode, res.fattr);
223         if (status == 0)
224                 nfs_access_set_mask(entry, res.access);
225         nfs_free_fattr(res.fattr);
226 out:
227         dprintk("NFS reply access: %d\n", status);
228         return status;
229 }
230 
231 static int nfs3_proc_readlink(struct inode *inode, struct page *page,
232                 unsigned int pgbase, unsigned int pglen)
233 {
234         struct nfs_fattr        *fattr;
235         struct nfs3_readlinkargs args = {
236                 .fh             = NFS_FH(inode),
237                 .pgbase         = pgbase,
238                 .pglen          = pglen,
239                 .pages          = &page
240         };
241         struct rpc_message msg = {
242                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READLINK],
243                 .rpc_argp       = &args,
244         };
245         int status = -ENOMEM;
246 
247         dprintk("NFS call  readlink\n");
248         fattr = nfs_alloc_fattr();
249         if (fattr == NULL)
250                 goto out;
251         msg.rpc_resp = fattr;
252 
253         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
254         nfs_refresh_inode(inode, fattr);
255         nfs_free_fattr(fattr);
256 out:
257         dprintk("NFS reply readlink: %d\n", status);
258         return status;
259 }
260 
261 struct nfs3_createdata {
262         struct rpc_message msg;
263         union {
264                 struct nfs3_createargs create;
265                 struct nfs3_mkdirargs mkdir;
266                 struct nfs3_symlinkargs symlink;
267                 struct nfs3_mknodargs mknod;
268         } arg;
269         struct nfs3_diropres res;
270         struct nfs_fh fh;
271         struct nfs_fattr fattr;
272         struct nfs_fattr dir_attr;
273 };
274 
275 static struct nfs3_createdata *nfs3_alloc_createdata(void)
276 {
277         struct nfs3_createdata *data;
278 
279         data = kzalloc(sizeof(*data), GFP_KERNEL);
280         if (data != NULL) {
281                 data->msg.rpc_argp = &data->arg;
282                 data->msg.rpc_resp = &data->res;
283                 data->res.fh = &data->fh;
284                 data->res.fattr = &data->fattr;
285                 data->res.dir_attr = &data->dir_attr;
286                 nfs_fattr_init(data->res.fattr);
287                 nfs_fattr_init(data->res.dir_attr);
288         }
289         return data;
290 }
291 
292 static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
293 {
294         int status;
295 
296         status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
297         nfs_post_op_update_inode(dir, data->res.dir_attr);
298         if (status == 0)
299                 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
300         return status;
301 }
302 
303 static void nfs3_free_createdata(struct nfs3_createdata *data)
304 {
305         kfree(data);
306 }
307 
308 /*
309  * Create a regular file.
310  */
311 static int
312 nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
313                  int flags)
314 {
315         struct posix_acl *default_acl, *acl;
316         struct nfs3_createdata *data;
317         int status = -ENOMEM;
318 
319         dprintk("NFS call  create %pd\n", dentry);
320 
321         data = nfs3_alloc_createdata();
322         if (data == NULL)
323                 goto out;
324 
325         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_CREATE];
326         data->arg.create.fh = NFS_FH(dir);
327         data->arg.create.name = dentry->d_name.name;
328         data->arg.create.len = dentry->d_name.len;
329         data->arg.create.sattr = sattr;
330 
331         data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
332         if (flags & O_EXCL) {
333                 data->arg.create.createmode  = NFS3_CREATE_EXCLUSIVE;
334                 data->arg.create.verifier[0] = cpu_to_be32(jiffies);
335                 data->arg.create.verifier[1] = cpu_to_be32(current->pid);
336         }
337 
338         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
339         if (status)
340                 goto out;
341 
342         for (;;) {
343                 status = nfs3_do_create(dir, dentry, data);
344 
345                 if (status != -ENOTSUPP)
346                         break;
347                 /* If the server doesn't support the exclusive creation
348                  * semantics, try again with simple 'guarded' mode. */
349                 switch (data->arg.create.createmode) {
350                         case NFS3_CREATE_EXCLUSIVE:
351                                 data->arg.create.createmode = NFS3_CREATE_GUARDED;
352                                 break;
353 
354                         case NFS3_CREATE_GUARDED:
355                                 data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
356                                 break;
357 
358                         case NFS3_CREATE_UNCHECKED:
359                                 goto out;
360                 }
361                 nfs_fattr_init(data->res.dir_attr);
362                 nfs_fattr_init(data->res.fattr);
363         }
364 
365         if (status != 0)
366                 goto out_release_acls;
367 
368         /* When we created the file with exclusive semantics, make
369          * sure we set the attributes afterwards. */
370         if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) {
371                 dprintk("NFS call  setattr (post-create)\n");
372 
373                 if (!(sattr->ia_valid & ATTR_ATIME_SET))
374                         sattr->ia_valid |= ATTR_ATIME;
375                 if (!(sattr->ia_valid & ATTR_MTIME_SET))
376                         sattr->ia_valid |= ATTR_MTIME;
377 
378                 /* Note: we could use a guarded setattr here, but I'm
379                  * not sure this buys us anything (and I'd have
380                  * to revamp the NFSv3 XDR code) */
381                 status = nfs3_proc_setattr(dentry, data->res.fattr, sattr);
382                 nfs_post_op_update_inode(d_inode(dentry), data->res.fattr);
383                 dprintk("NFS reply setattr (post-create): %d\n", status);
384                 if (status != 0)
385                         goto out_release_acls;
386         }
387 
388         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
389 
390 out_release_acls:
391         posix_acl_release(acl);
392         posix_acl_release(default_acl);
393 out:
394         nfs3_free_createdata(data);
395         dprintk("NFS reply create: %d\n", status);
396         return status;
397 }
398 
399 static int
400 nfs3_proc_remove(struct inode *dir, const struct qstr *name)
401 {
402         struct nfs_removeargs arg = {
403                 .fh = NFS_FH(dir),
404                 .name = *name,
405         };
406         struct nfs_removeres res;
407         struct rpc_message msg = {
408                 .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
409                 .rpc_argp = &arg,
410                 .rpc_resp = &res,
411         };
412         int status = -ENOMEM;
413 
414         dprintk("NFS call  remove %s\n", name->name);
415         res.dir_attr = nfs_alloc_fattr();
416         if (res.dir_attr == NULL)
417                 goto out;
418 
419         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
420         nfs_post_op_update_inode(dir, res.dir_attr);
421         nfs_free_fattr(res.dir_attr);
422 out:
423         dprintk("NFS reply remove: %d\n", status);
424         return status;
425 }
426 
427 static void
428 nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
429 {
430         msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
431 }
432 
433 static void nfs3_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
434 {
435         rpc_call_start(task);
436 }
437 
438 static int
439 nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
440 {
441         struct nfs_removeres *res;
442         if (nfs3_async_handle_jukebox(task, dir))
443                 return 0;
444         res = task->tk_msg.rpc_resp;
445         nfs_post_op_update_inode(dir, res->dir_attr);
446         return 1;
447 }
448 
449 static void
450 nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
451 {
452         msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
453 }
454 
455 static void nfs3_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
456 {
457         rpc_call_start(task);
458 }
459 
460 static int
461 nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
462                       struct inode *new_dir)
463 {
464         struct nfs_renameres *res;
465 
466         if (nfs3_async_handle_jukebox(task, old_dir))
467                 return 0;
468         res = task->tk_msg.rpc_resp;
469 
470         nfs_post_op_update_inode(old_dir, res->old_fattr);
471         nfs_post_op_update_inode(new_dir, res->new_fattr);
472         return 1;
473 }
474 
475 static int
476 nfs3_proc_link(struct inode *inode, struct inode *dir, const struct qstr *name)
477 {
478         struct nfs3_linkargs    arg = {
479                 .fromfh         = NFS_FH(inode),
480                 .tofh           = NFS_FH(dir),
481                 .toname         = name->name,
482                 .tolen          = name->len
483         };
484         struct nfs3_linkres     res;
485         struct rpc_message msg = {
486                 .rpc_proc       = &nfs3_procedures[NFS3PROC_LINK],
487                 .rpc_argp       = &arg,
488                 .rpc_resp       = &res,
489         };
490         int status = -ENOMEM;
491 
492         dprintk("NFS call  link %s\n", name->name);
493         res.fattr = nfs_alloc_fattr();
494         res.dir_attr = nfs_alloc_fattr();
495         if (res.fattr == NULL || res.dir_attr == NULL)
496                 goto out;
497 
498         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
499         nfs_post_op_update_inode(dir, res.dir_attr);
500         nfs_post_op_update_inode(inode, res.fattr);
501 out:
502         nfs_free_fattr(res.dir_attr);
503         nfs_free_fattr(res.fattr);
504         dprintk("NFS reply link: %d\n", status);
505         return status;
506 }
507 
508 static int
509 nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
510                   unsigned int len, struct iattr *sattr)
511 {
512         struct nfs3_createdata *data;
513         int status = -ENOMEM;
514 
515         if (len > NFS3_MAXPATHLEN)
516                 return -ENAMETOOLONG;
517 
518         dprintk("NFS call  symlink %pd\n", dentry);
519 
520         data = nfs3_alloc_createdata();
521         if (data == NULL)
522                 goto out;
523         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK];
524         data->arg.symlink.fromfh = NFS_FH(dir);
525         data->arg.symlink.fromname = dentry->d_name.name;
526         data->arg.symlink.fromlen = dentry->d_name.len;
527         data->arg.symlink.pages = &page;
528         data->arg.symlink.pathlen = len;
529         data->arg.symlink.sattr = sattr;
530 
531         status = nfs3_do_create(dir, dentry, data);
532 
533         nfs3_free_createdata(data);
534 out:
535         dprintk("NFS reply symlink: %d\n", status);
536         return status;
537 }
538 
539 static int
540 nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
541 {
542         struct posix_acl *default_acl, *acl;
543         struct nfs3_createdata *data;
544         int status = -ENOMEM;
545 
546         dprintk("NFS call  mkdir %pd\n", dentry);
547 
548         data = nfs3_alloc_createdata();
549         if (data == NULL)
550                 goto out;
551 
552         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
553         if (status)
554                 goto out;
555 
556         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
557         data->arg.mkdir.fh = NFS_FH(dir);
558         data->arg.mkdir.name = dentry->d_name.name;
559         data->arg.mkdir.len = dentry->d_name.len;
560         data->arg.mkdir.sattr = sattr;
561 
562         status = nfs3_do_create(dir, dentry, data);
563         if (status != 0)
564                 goto out_release_acls;
565 
566         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
567 
568 out_release_acls:
569         posix_acl_release(acl);
570         posix_acl_release(default_acl);
571 out:
572         nfs3_free_createdata(data);
573         dprintk("NFS reply mkdir: %d\n", status);
574         return status;
575 }
576 
577 static int
578 nfs3_proc_rmdir(struct inode *dir, const struct qstr *name)
579 {
580         struct nfs_fattr        *dir_attr;
581         struct nfs3_diropargs   arg = {
582                 .fh             = NFS_FH(dir),
583                 .name           = name->name,
584                 .len            = name->len
585         };
586         struct rpc_message msg = {
587                 .rpc_proc       = &nfs3_procedures[NFS3PROC_RMDIR],
588                 .rpc_argp       = &arg,
589         };
590         int status = -ENOMEM;
591 
592         dprintk("NFS call  rmdir %s\n", name->name);
593         dir_attr = nfs_alloc_fattr();
594         if (dir_attr == NULL)
595                 goto out;
596 
597         msg.rpc_resp = dir_attr;
598         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
599         nfs_post_op_update_inode(dir, dir_attr);
600         nfs_free_fattr(dir_attr);
601 out:
602         dprintk("NFS reply rmdir: %d\n", status);
603         return status;
604 }
605 
606 /*
607  * The READDIR implementation is somewhat hackish - we pass the user buffer
608  * to the encode function, which installs it in the receive iovec.
609  * The decode function itself doesn't perform any decoding, it just makes
610  * sure the reply is syntactically correct.
611  *
612  * Also note that this implementation handles both plain readdir and
613  * readdirplus.
614  */
615 static int
616 nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
617                   u64 cookie, struct page **pages, unsigned int count, bool plus)
618 {
619         struct inode            *dir = d_inode(dentry);
620         __be32                  *verf = NFS_I(dir)->cookieverf;
621         struct nfs3_readdirargs arg = {
622                 .fh             = NFS_FH(dir),
623                 .cookie         = cookie,
624                 .verf           = {verf[0], verf[1]},
625                 .plus           = plus,
626                 .count          = count,
627                 .pages          = pages
628         };
629         struct nfs3_readdirres  res = {
630                 .verf           = verf,
631                 .plus           = plus
632         };
633         struct rpc_message      msg = {
634                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READDIR],
635                 .rpc_argp       = &arg,
636                 .rpc_resp       = &res,
637                 .rpc_cred       = cred
638         };
639         int status = -ENOMEM;
640 
641         if (plus)
642                 msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
643 
644         dprintk("NFS call  readdir%s %d\n",
645                         plus? "plus" : "", (unsigned int) cookie);
646 
647         res.dir_attr = nfs_alloc_fattr();
648         if (res.dir_attr == NULL)
649                 goto out;
650 
651         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
652 
653         nfs_invalidate_atime(dir);
654         nfs_refresh_inode(dir, res.dir_attr);
655 
656         nfs_free_fattr(res.dir_attr);
657 out:
658         dprintk("NFS reply readdir%s: %d\n",
659                         plus? "plus" : "", status);
660         return status;
661 }
662 
663 static int
664 nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
665                 dev_t rdev)
666 {
667         struct posix_acl *default_acl, *acl;
668         struct nfs3_createdata *data;
669         int status = -ENOMEM;
670 
671         dprintk("NFS call  mknod %pd %u:%u\n", dentry,
672                         MAJOR(rdev), MINOR(rdev));
673 
674         data = nfs3_alloc_createdata();
675         if (data == NULL)
676                 goto out;
677 
678         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
679         if (status)
680                 goto out;
681 
682         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
683         data->arg.mknod.fh = NFS_FH(dir);
684         data->arg.mknod.name = dentry->d_name.name;
685         data->arg.mknod.len = dentry->d_name.len;
686         data->arg.mknod.sattr = sattr;
687         data->arg.mknod.rdev = rdev;
688 
689         switch (sattr->ia_mode & S_IFMT) {
690         case S_IFBLK:
691                 data->arg.mknod.type = NF3BLK;
692                 break;
693         case S_IFCHR:
694                 data->arg.mknod.type = NF3CHR;
695                 break;
696         case S_IFIFO:
697                 data->arg.mknod.type = NF3FIFO;
698                 break;
699         case S_IFSOCK:
700                 data->arg.mknod.type = NF3SOCK;
701                 break;
702         default:
703                 status = -EINVAL;
704                 goto out;
705         }
706 
707         status = nfs3_do_create(dir, dentry, data);
708         if (status != 0)
709                 goto out_release_acls;
710 
711         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
712 
713 out_release_acls:
714         posix_acl_release(acl);
715         posix_acl_release(default_acl);
716 out:
717         nfs3_free_createdata(data);
718         dprintk("NFS reply mknod: %d\n", status);
719         return status;
720 }
721 
722 static int
723 nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
724                  struct nfs_fsstat *stat)
725 {
726         struct rpc_message msg = {
727                 .rpc_proc       = &nfs3_procedures[NFS3PROC_FSSTAT],
728                 .rpc_argp       = fhandle,
729                 .rpc_resp       = stat,
730         };
731         int     status;
732 
733         dprintk("NFS call  fsstat\n");
734         nfs_fattr_init(stat->fattr);
735         status = rpc_call_sync(server->client, &msg, 0);
736         dprintk("NFS reply fsstat: %d\n", status);
737         return status;
738 }
739 
740 static int
741 do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
742                  struct nfs_fsinfo *info)
743 {
744         struct rpc_message msg = {
745                 .rpc_proc       = &nfs3_procedures[NFS3PROC_FSINFO],
746                 .rpc_argp       = fhandle,
747                 .rpc_resp       = info,
748         };
749         int     status;
750 
751         dprintk("NFS call  fsinfo\n");
752         nfs_fattr_init(info->fattr);
753         status = rpc_call_sync(client, &msg, 0);
754         dprintk("NFS reply fsinfo: %d\n", status);
755         return status;
756 }
757 
758 /*
759  * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
760  * nfs_create_server
761  */
762 static int
763 nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
764                    struct nfs_fsinfo *info)
765 {
766         int     status;
767 
768         status = do_proc_fsinfo(server->client, fhandle, info);
769         if (status && server->nfs_client->cl_rpcclient != server->client)
770                 status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
771         return status;
772 }
773 
774 static int
775 nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
776                    struct nfs_pathconf *info)
777 {
778         struct rpc_message msg = {
779                 .rpc_proc       = &nfs3_procedures[NFS3PROC_PATHCONF],
780                 .rpc_argp       = fhandle,
781                 .rpc_resp       = info,
782         };
783         int     status;
784 
785         dprintk("NFS call  pathconf\n");
786         nfs_fattr_init(info->fattr);
787         status = rpc_call_sync(server->client, &msg, 0);
788         dprintk("NFS reply pathconf: %d\n", status);
789         return status;
790 }
791 
792 static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
793 {
794         struct inode *inode = hdr->inode;
795 
796         if (hdr->pgio_done_cb != NULL)
797                 return hdr->pgio_done_cb(task, hdr);
798 
799         if (nfs3_async_handle_jukebox(task, inode))
800                 return -EAGAIN;
801 
802         nfs_invalidate_atime(inode);
803         nfs_refresh_inode(inode, &hdr->fattr);
804         return 0;
805 }
806 
807 static void nfs3_proc_read_setup(struct nfs_pgio_header *hdr,
808                                  struct rpc_message *msg)
809 {
810         msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
811 }
812 
813 static int nfs3_proc_pgio_rpc_prepare(struct rpc_task *task,
814                                       struct nfs_pgio_header *hdr)
815 {
816         rpc_call_start(task);
817         return 0;
818 }
819 
820 static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
821 {
822         struct inode *inode = hdr->inode;
823 
824         if (hdr->pgio_done_cb != NULL)
825                 return hdr->pgio_done_cb(task, hdr);
826 
827         if (nfs3_async_handle_jukebox(task, inode))
828                 return -EAGAIN;
829         if (task->tk_status >= 0)
830                 nfs_writeback_update_inode(hdr);
831         return 0;
832 }
833 
834 static void nfs3_proc_write_setup(struct nfs_pgio_header *hdr,
835                                   struct rpc_message *msg)
836 {
837         msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
838 }
839 
840 static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
841 {
842         rpc_call_start(task);
843 }
844 
845 static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
846 {
847         if (data->commit_done_cb != NULL)
848                 return data->commit_done_cb(task, data);
849 
850         if (nfs3_async_handle_jukebox(task, data->inode))
851                 return -EAGAIN;
852         nfs_refresh_inode(data->inode, data->res.fattr);
853         return 0;
854 }
855 
856 static void nfs3_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)
857 {
858         msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
859 }
860 
861 static void nfs3_nlm_alloc_call(void *data)
862 {
863         struct nfs_lock_context *l_ctx = data;
864         if (l_ctx && test_bit(NFS_CONTEXT_UNLOCK, &l_ctx->open_context->flags)) {
865                 get_nfs_open_context(l_ctx->open_context);
866                 nfs_get_lock_context(l_ctx->open_context);
867         }
868 }
869 
870 static bool nfs3_nlm_unlock_prepare(struct rpc_task *task, void *data)
871 {
872         struct nfs_lock_context *l_ctx = data;
873         if (l_ctx && test_bit(NFS_CONTEXT_UNLOCK, &l_ctx->open_context->flags))
874                 return nfs_async_iocounter_wait(task, l_ctx);
875         return false;
876 
877 }
878 
879 static void nfs3_nlm_release_call(void *data)
880 {
881         struct nfs_lock_context *l_ctx = data;
882         struct nfs_open_context *ctx;
883         if (l_ctx && test_bit(NFS_CONTEXT_UNLOCK, &l_ctx->open_context->flags)) {
884                 ctx = l_ctx->open_context;
885                 nfs_put_lock_context(l_ctx);
886                 put_nfs_open_context(ctx);
887         }
888 }
889 
890 const struct nlmclnt_operations nlmclnt_fl_close_lock_ops = {
891         .nlmclnt_alloc_call = nfs3_nlm_alloc_call,
892         .nlmclnt_unlock_prepare = nfs3_nlm_unlock_prepare,
893         .nlmclnt_release_call = nfs3_nlm_release_call,
894 };
895 
896 static int
897 nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
898 {
899         struct inode *inode = file_inode(filp);
900         struct nfs_lock_context *l_ctx = NULL;
901         struct nfs_open_context *ctx = nfs_file_open_context(filp);
902         int status;
903 
904         if (fl->fl_flags & FL_CLOSE) {
905                 l_ctx = nfs_get_lock_context(ctx);
906                 if (IS_ERR(l_ctx))
907                         l_ctx = NULL;
908                 else
909                         set_bit(NFS_CONTEXT_UNLOCK, &ctx->flags);
910         }
911 
912         status = nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl, l_ctx);
913 
914         if (l_ctx)
915                 nfs_put_lock_context(l_ctx);
916 
917         return status;
918 }
919 
920 static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
921 {
922         return 0;
923 }
924 
925 static int nfs3_return_delegation(struct inode *inode)
926 {
927         nfs_wb_all(inode);
928         return 0;
929 }
930 
931 static const struct inode_operations nfs3_dir_inode_operations = {
932         .create         = nfs_create,
933         .lookup         = nfs_lookup,
934         .link           = nfs_link,
935         .unlink         = nfs_unlink,
936         .symlink        = nfs_symlink,
937         .mkdir          = nfs_mkdir,
938         .rmdir          = nfs_rmdir,
939         .mknod          = nfs_mknod,
940         .rename         = nfs_rename,
941         .permission     = nfs_permission,
942         .getattr        = nfs_getattr,
943         .setattr        = nfs_setattr,
944 #ifdef CONFIG_NFS_V3_ACL
945         .listxattr      = nfs3_listxattr,
946         .get_acl        = nfs3_get_acl,
947         .set_acl        = nfs3_set_acl,
948 #endif
949 };
950 
951 static const struct inode_operations nfs3_file_inode_operations = {
952         .permission     = nfs_permission,
953         .getattr        = nfs_getattr,
954         .setattr        = nfs_setattr,
955 #ifdef CONFIG_NFS_V3_ACL
956         .listxattr      = nfs3_listxattr,
957         .get_acl        = nfs3_get_acl,
958         .set_acl        = nfs3_set_acl,
959 #endif
960 };
961 
962 const struct nfs_rpc_ops nfs_v3_clientops = {
963         .version        = 3,                    /* protocol version */
964         .dentry_ops     = &nfs_dentry_operations,
965         .dir_inode_ops  = &nfs3_dir_inode_operations,
966         .file_inode_ops = &nfs3_file_inode_operations,
967         .file_ops       = &nfs_file_operations,
968         .nlmclnt_ops    = &nlmclnt_fl_close_lock_ops,
969         .getroot        = nfs3_proc_get_root,
970         .submount       = nfs_submount,
971         .try_mount      = nfs_try_mount,
972         .getattr        = nfs3_proc_getattr,
973         .setattr        = nfs3_proc_setattr,
974         .lookup         = nfs3_proc_lookup,
975         .access         = nfs3_proc_access,
976         .readlink       = nfs3_proc_readlink,
977         .create         = nfs3_proc_create,
978         .remove         = nfs3_proc_remove,
979         .unlink_setup   = nfs3_proc_unlink_setup,
980         .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare,
981         .unlink_done    = nfs3_proc_unlink_done,
982         .rename_setup   = nfs3_proc_rename_setup,
983         .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare,
984         .rename_done    = nfs3_proc_rename_done,
985         .link           = nfs3_proc_link,
986         .symlink        = nfs3_proc_symlink,
987         .mkdir          = nfs3_proc_mkdir,
988         .rmdir          = nfs3_proc_rmdir,
989         .readdir        = nfs3_proc_readdir,
990         .mknod          = nfs3_proc_mknod,
991         .statfs         = nfs3_proc_statfs,
992         .fsinfo         = nfs3_proc_fsinfo,
993         .pathconf       = nfs3_proc_pathconf,
994         .decode_dirent  = nfs3_decode_dirent,
995         .pgio_rpc_prepare = nfs3_proc_pgio_rpc_prepare,
996         .read_setup     = nfs3_proc_read_setup,
997         .read_done      = nfs3_read_done,
998         .write_setup    = nfs3_proc_write_setup,
999         .write_done     = nfs3_write_done,
1000         .commit_setup   = nfs3_proc_commit_setup,
1001         .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
1002         .commit_done    = nfs3_commit_done,
1003         .lock           = nfs3_proc_lock,
1004         .clear_acl_cache = forget_all_cached_acls,
1005         .close_context  = nfs_close_context,
1006         .have_delegation = nfs3_have_delegation,
1007         .return_delegation = nfs3_return_delegation,
1008         .alloc_client   = nfs_alloc_client,
1009         .init_client    = nfs_init_client,
1010         .free_client    = nfs_free_client,
1011         .create_server  = nfs3_create_server,
1012         .clone_server   = nfs3_clone_server,
1013 };
1014 

~ [ 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