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

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

Version: ~ [ linux-5.3 ] ~ [ linux-5.2.14 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.72 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.143 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.192 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.192 ] ~ [ 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.73 ] ~ [ 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, 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                 entry->mask = 0;
225                 if (res.access & NFS3_ACCESS_READ)
226                         entry->mask |= MAY_READ;
227                 if (res.access & (NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE))
228                         entry->mask |= MAY_WRITE;
229                 if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
230                         entry->mask |= MAY_EXEC;
231         }
232         nfs_free_fattr(res.fattr);
233 out:
234         dprintk("NFS reply access: %d\n", status);
235         return status;
236 }
237 
238 static int nfs3_proc_readlink(struct inode *inode, struct page *page,
239                 unsigned int pgbase, unsigned int pglen)
240 {
241         struct nfs_fattr        *fattr;
242         struct nfs3_readlinkargs args = {
243                 .fh             = NFS_FH(inode),
244                 .pgbase         = pgbase,
245                 .pglen          = pglen,
246                 .pages          = &page
247         };
248         struct rpc_message msg = {
249                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READLINK],
250                 .rpc_argp       = &args,
251         };
252         int status = -ENOMEM;
253 
254         dprintk("NFS call  readlink\n");
255         fattr = nfs_alloc_fattr();
256         if (fattr == NULL)
257                 goto out;
258         msg.rpc_resp = fattr;
259 
260         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
261         nfs_refresh_inode(inode, fattr);
262         nfs_free_fattr(fattr);
263 out:
264         dprintk("NFS reply readlink: %d\n", status);
265         return status;
266 }
267 
268 struct nfs3_createdata {
269         struct rpc_message msg;
270         union {
271                 struct nfs3_createargs create;
272                 struct nfs3_mkdirargs mkdir;
273                 struct nfs3_symlinkargs symlink;
274                 struct nfs3_mknodargs mknod;
275         } arg;
276         struct nfs3_diropres res;
277         struct nfs_fh fh;
278         struct nfs_fattr fattr;
279         struct nfs_fattr dir_attr;
280 };
281 
282 static struct nfs3_createdata *nfs3_alloc_createdata(void)
283 {
284         struct nfs3_createdata *data;
285 
286         data = kzalloc(sizeof(*data), GFP_KERNEL);
287         if (data != NULL) {
288                 data->msg.rpc_argp = &data->arg;
289                 data->msg.rpc_resp = &data->res;
290                 data->res.fh = &data->fh;
291                 data->res.fattr = &data->fattr;
292                 data->res.dir_attr = &data->dir_attr;
293                 nfs_fattr_init(data->res.fattr);
294                 nfs_fattr_init(data->res.dir_attr);
295         }
296         return data;
297 }
298 
299 static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
300 {
301         int status;
302 
303         status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
304         nfs_post_op_update_inode(dir, data->res.dir_attr);
305         if (status == 0)
306                 status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
307         return status;
308 }
309 
310 static void nfs3_free_createdata(struct nfs3_createdata *data)
311 {
312         kfree(data);
313 }
314 
315 /*
316  * Create a regular file.
317  */
318 static int
319 nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
320                  int flags)
321 {
322         struct posix_acl *default_acl, *acl;
323         struct nfs3_createdata *data;
324         int status = -ENOMEM;
325 
326         dprintk("NFS call  create %pd\n", dentry);
327 
328         data = nfs3_alloc_createdata();
329         if (data == NULL)
330                 goto out;
331 
332         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_CREATE];
333         data->arg.create.fh = NFS_FH(dir);
334         data->arg.create.name = dentry->d_name.name;
335         data->arg.create.len = dentry->d_name.len;
336         data->arg.create.sattr = sattr;
337 
338         data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
339         if (flags & O_EXCL) {
340                 data->arg.create.createmode  = NFS3_CREATE_EXCLUSIVE;
341                 data->arg.create.verifier[0] = cpu_to_be32(jiffies);
342                 data->arg.create.verifier[1] = cpu_to_be32(current->pid);
343         }
344 
345         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
346         if (status)
347                 goto out;
348 
349         for (;;) {
350                 status = nfs3_do_create(dir, dentry, data);
351 
352                 if (status != -ENOTSUPP)
353                         break;
354                 /* If the server doesn't support the exclusive creation
355                  * semantics, try again with simple 'guarded' mode. */
356                 switch (data->arg.create.createmode) {
357                         case NFS3_CREATE_EXCLUSIVE:
358                                 data->arg.create.createmode = NFS3_CREATE_GUARDED;
359                                 break;
360 
361                         case NFS3_CREATE_GUARDED:
362                                 data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
363                                 break;
364 
365                         case NFS3_CREATE_UNCHECKED:
366                                 goto out;
367                 }
368                 nfs_fattr_init(data->res.dir_attr);
369                 nfs_fattr_init(data->res.fattr);
370         }
371 
372         if (status != 0)
373                 goto out_release_acls;
374 
375         /* When we created the file with exclusive semantics, make
376          * sure we set the attributes afterwards. */
377         if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) {
378                 dprintk("NFS call  setattr (post-create)\n");
379 
380                 if (!(sattr->ia_valid & ATTR_ATIME_SET))
381                         sattr->ia_valid |= ATTR_ATIME;
382                 if (!(sattr->ia_valid & ATTR_MTIME_SET))
383                         sattr->ia_valid |= ATTR_MTIME;
384 
385                 /* Note: we could use a guarded setattr here, but I'm
386                  * not sure this buys us anything (and I'd have
387                  * to revamp the NFSv3 XDR code) */
388                 status = nfs3_proc_setattr(dentry, data->res.fattr, sattr);
389                 nfs_post_op_update_inode(d_inode(dentry), data->res.fattr);
390                 dprintk("NFS reply setattr (post-create): %d\n", status);
391                 if (status != 0)
392                         goto out_release_acls;
393         }
394 
395         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
396 
397 out_release_acls:
398         posix_acl_release(acl);
399         posix_acl_release(default_acl);
400 out:
401         nfs3_free_createdata(data);
402         dprintk("NFS reply create: %d\n", status);
403         return status;
404 }
405 
406 static int
407 nfs3_proc_remove(struct inode *dir, struct qstr *name)
408 {
409         struct nfs_removeargs arg = {
410                 .fh = NFS_FH(dir),
411                 .name = *name,
412         };
413         struct nfs_removeres res;
414         struct rpc_message msg = {
415                 .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
416                 .rpc_argp = &arg,
417                 .rpc_resp = &res,
418         };
419         int status = -ENOMEM;
420 
421         dprintk("NFS call  remove %s\n", name->name);
422         res.dir_attr = nfs_alloc_fattr();
423         if (res.dir_attr == NULL)
424                 goto out;
425 
426         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
427         nfs_post_op_update_inode(dir, res.dir_attr);
428         nfs_free_fattr(res.dir_attr);
429 out:
430         dprintk("NFS reply remove: %d\n", status);
431         return status;
432 }
433 
434 static void
435 nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
436 {
437         msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
438 }
439 
440 static void nfs3_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
441 {
442         rpc_call_start(task);
443 }
444 
445 static int
446 nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
447 {
448         struct nfs_removeres *res;
449         if (nfs3_async_handle_jukebox(task, dir))
450                 return 0;
451         res = task->tk_msg.rpc_resp;
452         nfs_post_op_update_inode(dir, res->dir_attr);
453         return 1;
454 }
455 
456 static void
457 nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
458 {
459         msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
460 }
461 
462 static void nfs3_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
463 {
464         rpc_call_start(task);
465 }
466 
467 static int
468 nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
469                       struct inode *new_dir)
470 {
471         struct nfs_renameres *res;
472 
473         if (nfs3_async_handle_jukebox(task, old_dir))
474                 return 0;
475         res = task->tk_msg.rpc_resp;
476 
477         nfs_post_op_update_inode(old_dir, res->old_fattr);
478         nfs_post_op_update_inode(new_dir, res->new_fattr);
479         return 1;
480 }
481 
482 static int
483 nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
484 {
485         struct nfs3_linkargs    arg = {
486                 .fromfh         = NFS_FH(inode),
487                 .tofh           = NFS_FH(dir),
488                 .toname         = name->name,
489                 .tolen          = name->len
490         };
491         struct nfs3_linkres     res;
492         struct rpc_message msg = {
493                 .rpc_proc       = &nfs3_procedures[NFS3PROC_LINK],
494                 .rpc_argp       = &arg,
495                 .rpc_resp       = &res,
496         };
497         int status = -ENOMEM;
498 
499         dprintk("NFS call  link %s\n", name->name);
500         res.fattr = nfs_alloc_fattr();
501         res.dir_attr = nfs_alloc_fattr();
502         if (res.fattr == NULL || res.dir_attr == NULL)
503                 goto out;
504 
505         status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
506         nfs_post_op_update_inode(dir, res.dir_attr);
507         nfs_post_op_update_inode(inode, res.fattr);
508 out:
509         nfs_free_fattr(res.dir_attr);
510         nfs_free_fattr(res.fattr);
511         dprintk("NFS reply link: %d\n", status);
512         return status;
513 }
514 
515 static int
516 nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
517                   unsigned int len, struct iattr *sattr)
518 {
519         struct nfs3_createdata *data;
520         int status = -ENOMEM;
521 
522         if (len > NFS3_MAXPATHLEN)
523                 return -ENAMETOOLONG;
524 
525         dprintk("NFS call  symlink %pd\n", dentry);
526 
527         data = nfs3_alloc_createdata();
528         if (data == NULL)
529                 goto out;
530         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK];
531         data->arg.symlink.fromfh = NFS_FH(dir);
532         data->arg.symlink.fromname = dentry->d_name.name;
533         data->arg.symlink.fromlen = dentry->d_name.len;
534         data->arg.symlink.pages = &page;
535         data->arg.symlink.pathlen = len;
536         data->arg.symlink.sattr = sattr;
537 
538         status = nfs3_do_create(dir, dentry, data);
539 
540         nfs3_free_createdata(data);
541 out:
542         dprintk("NFS reply symlink: %d\n", status);
543         return status;
544 }
545 
546 static int
547 nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
548 {
549         struct posix_acl *default_acl, *acl;
550         struct nfs3_createdata *data;
551         int status = -ENOMEM;
552 
553         dprintk("NFS call  mkdir %pd\n", dentry);
554 
555         data = nfs3_alloc_createdata();
556         if (data == NULL)
557                 goto out;
558 
559         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
560         if (status)
561                 goto out;
562 
563         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
564         data->arg.mkdir.fh = NFS_FH(dir);
565         data->arg.mkdir.name = dentry->d_name.name;
566         data->arg.mkdir.len = dentry->d_name.len;
567         data->arg.mkdir.sattr = sattr;
568 
569         status = nfs3_do_create(dir, dentry, data);
570         if (status != 0)
571                 goto out_release_acls;
572 
573         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
574 
575 out_release_acls:
576         posix_acl_release(acl);
577         posix_acl_release(default_acl);
578 out:
579         nfs3_free_createdata(data);
580         dprintk("NFS reply mkdir: %d\n", status);
581         return status;
582 }
583 
584 static int
585 nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
586 {
587         struct nfs_fattr        *dir_attr;
588         struct nfs3_diropargs   arg = {
589                 .fh             = NFS_FH(dir),
590                 .name           = name->name,
591                 .len            = name->len
592         };
593         struct rpc_message msg = {
594                 .rpc_proc       = &nfs3_procedures[NFS3PROC_RMDIR],
595                 .rpc_argp       = &arg,
596         };
597         int status = -ENOMEM;
598 
599         dprintk("NFS call  rmdir %s\n", name->name);
600         dir_attr = nfs_alloc_fattr();
601         if (dir_attr == NULL)
602                 goto out;
603 
604         msg.rpc_resp = dir_attr;
605         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
606         nfs_post_op_update_inode(dir, dir_attr);
607         nfs_free_fattr(dir_attr);
608 out:
609         dprintk("NFS reply rmdir: %d\n", status);
610         return status;
611 }
612 
613 /*
614  * The READDIR implementation is somewhat hackish - we pass the user buffer
615  * to the encode function, which installs it in the receive iovec.
616  * The decode function itself doesn't perform any decoding, it just makes
617  * sure the reply is syntactically correct.
618  *
619  * Also note that this implementation handles both plain readdir and
620  * readdirplus.
621  */
622 static int
623 nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
624                   u64 cookie, struct page **pages, unsigned int count, int plus)
625 {
626         struct inode            *dir = d_inode(dentry);
627         __be32                  *verf = NFS_I(dir)->cookieverf;
628         struct nfs3_readdirargs arg = {
629                 .fh             = NFS_FH(dir),
630                 .cookie         = cookie,
631                 .verf           = {verf[0], verf[1]},
632                 .plus           = plus,
633                 .count          = count,
634                 .pages          = pages
635         };
636         struct nfs3_readdirres  res = {
637                 .verf           = verf,
638                 .plus           = plus
639         };
640         struct rpc_message      msg = {
641                 .rpc_proc       = &nfs3_procedures[NFS3PROC_READDIR],
642                 .rpc_argp       = &arg,
643                 .rpc_resp       = &res,
644                 .rpc_cred       = cred
645         };
646         int status = -ENOMEM;
647 
648         if (plus)
649                 msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
650 
651         dprintk("NFS call  readdir%s %d\n",
652                         plus? "plus" : "", (unsigned int) cookie);
653 
654         res.dir_attr = nfs_alloc_fattr();
655         if (res.dir_attr == NULL)
656                 goto out;
657 
658         status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
659 
660         nfs_invalidate_atime(dir);
661         nfs_refresh_inode(dir, res.dir_attr);
662 
663         nfs_free_fattr(res.dir_attr);
664 out:
665         dprintk("NFS reply readdir%s: %d\n",
666                         plus? "plus" : "", status);
667         return status;
668 }
669 
670 static int
671 nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
672                 dev_t rdev)
673 {
674         struct posix_acl *default_acl, *acl;
675         struct nfs3_createdata *data;
676         int status = -ENOMEM;
677 
678         dprintk("NFS call  mknod %pd %u:%u\n", dentry,
679                         MAJOR(rdev), MINOR(rdev));
680 
681         data = nfs3_alloc_createdata();
682         if (data == NULL)
683                 goto out;
684 
685         status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
686         if (status)
687                 goto out;
688 
689         data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
690         data->arg.mknod.fh = NFS_FH(dir);
691         data->arg.mknod.name = dentry->d_name.name;
692         data->arg.mknod.len = dentry->d_name.len;
693         data->arg.mknod.sattr = sattr;
694         data->arg.mknod.rdev = rdev;
695 
696         switch (sattr->ia_mode & S_IFMT) {
697         case S_IFBLK:
698                 data->arg.mknod.type = NF3BLK;
699                 break;
700         case S_IFCHR:
701                 data->arg.mknod.type = NF3CHR;
702                 break;
703         case S_IFIFO:
704                 data->arg.mknod.type = NF3FIFO;
705                 break;
706         case S_IFSOCK:
707                 data->arg.mknod.type = NF3SOCK;
708                 break;
709         default:
710                 status = -EINVAL;
711                 goto out;
712         }
713 
714         status = nfs3_do_create(dir, dentry, data);
715         if (status != 0)
716                 goto out_release_acls;
717 
718         status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl);
719 
720 out_release_acls:
721         posix_acl_release(acl);
722         posix_acl_release(default_acl);
723 out:
724         nfs3_free_createdata(data);
725         dprintk("NFS reply mknod: %d\n", status);
726         return status;
727 }
728 
729 static int
730 nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
731                  struct nfs_fsstat *stat)
732 {
733         struct rpc_message msg = {
734                 .rpc_proc       = &nfs3_procedures[NFS3PROC_FSSTAT],
735                 .rpc_argp       = fhandle,
736                 .rpc_resp       = stat,
737         };
738         int     status;
739 
740         dprintk("NFS call  fsstat\n");
741         nfs_fattr_init(stat->fattr);
742         status = rpc_call_sync(server->client, &msg, 0);
743         dprintk("NFS reply fsstat: %d\n", status);
744         return status;
745 }
746 
747 static int
748 do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
749                  struct nfs_fsinfo *info)
750 {
751         struct rpc_message msg = {
752                 .rpc_proc       = &nfs3_procedures[NFS3PROC_FSINFO],
753                 .rpc_argp       = fhandle,
754                 .rpc_resp       = info,
755         };
756         int     status;
757 
758         dprintk("NFS call  fsinfo\n");
759         nfs_fattr_init(info->fattr);
760         status = rpc_call_sync(client, &msg, 0);
761         dprintk("NFS reply fsinfo: %d\n", status);
762         return status;
763 }
764 
765 /*
766  * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
767  * nfs_create_server
768  */
769 static int
770 nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
771                    struct nfs_fsinfo *info)
772 {
773         int     status;
774 
775         status = do_proc_fsinfo(server->client, fhandle, info);
776         if (status && server->nfs_client->cl_rpcclient != server->client)
777                 status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
778         return status;
779 }
780 
781 static int
782 nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
783                    struct nfs_pathconf *info)
784 {
785         struct rpc_message msg = {
786                 .rpc_proc       = &nfs3_procedures[NFS3PROC_PATHCONF],
787                 .rpc_argp       = fhandle,
788                 .rpc_resp       = info,
789         };
790         int     status;
791 
792         dprintk("NFS call  pathconf\n");
793         nfs_fattr_init(info->fattr);
794         status = rpc_call_sync(server->client, &msg, 0);
795         dprintk("NFS reply pathconf: %d\n", status);
796         return status;
797 }
798 
799 static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
800 {
801         struct inode *inode = hdr->inode;
802 
803         if (hdr->pgio_done_cb != NULL)
804                 return hdr->pgio_done_cb(task, hdr);
805 
806         if (nfs3_async_handle_jukebox(task, inode))
807                 return -EAGAIN;
808 
809         nfs_invalidate_atime(inode);
810         nfs_refresh_inode(inode, &hdr->fattr);
811         return 0;
812 }
813 
814 static void nfs3_proc_read_setup(struct nfs_pgio_header *hdr,
815                                  struct rpc_message *msg)
816 {
817         msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
818 }
819 
820 static int nfs3_proc_pgio_rpc_prepare(struct rpc_task *task,
821                                       struct nfs_pgio_header *hdr)
822 {
823         rpc_call_start(task);
824         return 0;
825 }
826 
827 static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
828 {
829         struct inode *inode = hdr->inode;
830 
831         if (hdr->pgio_done_cb != NULL)
832                 return hdr->pgio_done_cb(task, hdr);
833 
834         if (nfs3_async_handle_jukebox(task, inode))
835                 return -EAGAIN;
836         if (task->tk_status >= 0)
837                 nfs_writeback_update_inode(hdr);
838         return 0;
839 }
840 
841 static void nfs3_proc_write_setup(struct nfs_pgio_header *hdr,
842                                   struct rpc_message *msg)
843 {
844         msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
845 }
846 
847 static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
848 {
849         rpc_call_start(task);
850 }
851 
852 static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
853 {
854         if (data->commit_done_cb != NULL)
855                 return data->commit_done_cb(task, data);
856 
857         if (nfs3_async_handle_jukebox(task, data->inode))
858                 return -EAGAIN;
859         nfs_refresh_inode(data->inode, data->res.fattr);
860         return 0;
861 }
862 
863 static void nfs3_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)
864 {
865         msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
866 }
867 
868 static int
869 nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
870 {
871         struct inode *inode = file_inode(filp);
872 
873         return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
874 }
875 
876 static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
877 {
878         return 0;
879 }
880 
881 static int nfs3_return_delegation(struct inode *inode)
882 {
883         nfs_wb_all(inode);
884         return 0;
885 }
886 
887 static const struct inode_operations nfs3_dir_inode_operations = {
888         .create         = nfs_create,
889         .lookup         = nfs_lookup,
890         .link           = nfs_link,
891         .unlink         = nfs_unlink,
892         .symlink        = nfs_symlink,
893         .mkdir          = nfs_mkdir,
894         .rmdir          = nfs_rmdir,
895         .mknod          = nfs_mknod,
896         .rename         = nfs_rename,
897         .permission     = nfs_permission,
898         .getattr        = nfs_getattr,
899         .setattr        = nfs_setattr,
900 #ifdef CONFIG_NFS_V3_ACL
901         .listxattr      = nfs3_listxattr,
902         .getxattr       = generic_getxattr,
903         .setxattr       = generic_setxattr,
904         .removexattr    = generic_removexattr,
905         .get_acl        = nfs3_get_acl,
906         .set_acl        = nfs3_set_acl,
907 #endif
908 };
909 
910 static const struct inode_operations nfs3_file_inode_operations = {
911         .permission     = nfs_permission,
912         .getattr        = nfs_getattr,
913         .setattr        = nfs_setattr,
914 #ifdef CONFIG_NFS_V3_ACL
915         .listxattr      = nfs3_listxattr,
916         .getxattr       = generic_getxattr,
917         .setxattr       = generic_setxattr,
918         .removexattr    = generic_removexattr,
919         .get_acl        = nfs3_get_acl,
920         .set_acl        = nfs3_set_acl,
921 #endif
922 };
923 
924 const struct nfs_rpc_ops nfs_v3_clientops = {
925         .version        = 3,                    /* protocol version */
926         .dentry_ops     = &nfs_dentry_operations,
927         .dir_inode_ops  = &nfs3_dir_inode_operations,
928         .file_inode_ops = &nfs3_file_inode_operations,
929         .file_ops       = &nfs_file_operations,
930         .getroot        = nfs3_proc_get_root,
931         .submount       = nfs_submount,
932         .try_mount      = nfs_try_mount,
933         .getattr        = nfs3_proc_getattr,
934         .setattr        = nfs3_proc_setattr,
935         .lookup         = nfs3_proc_lookup,
936         .access         = nfs3_proc_access,
937         .readlink       = nfs3_proc_readlink,
938         .create         = nfs3_proc_create,
939         .remove         = nfs3_proc_remove,
940         .unlink_setup   = nfs3_proc_unlink_setup,
941         .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare,
942         .unlink_done    = nfs3_proc_unlink_done,
943         .rename_setup   = nfs3_proc_rename_setup,
944         .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare,
945         .rename_done    = nfs3_proc_rename_done,
946         .link           = nfs3_proc_link,
947         .symlink        = nfs3_proc_symlink,
948         .mkdir          = nfs3_proc_mkdir,
949         .rmdir          = nfs3_proc_rmdir,
950         .readdir        = nfs3_proc_readdir,
951         .mknod          = nfs3_proc_mknod,
952         .statfs         = nfs3_proc_statfs,
953         .fsinfo         = nfs3_proc_fsinfo,
954         .pathconf       = nfs3_proc_pathconf,
955         .decode_dirent  = nfs3_decode_dirent,
956         .pgio_rpc_prepare = nfs3_proc_pgio_rpc_prepare,
957         .read_setup     = nfs3_proc_read_setup,
958         .read_done      = nfs3_read_done,
959         .write_setup    = nfs3_proc_write_setup,
960         .write_done     = nfs3_write_done,
961         .commit_setup   = nfs3_proc_commit_setup,
962         .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
963         .commit_done    = nfs3_commit_done,
964         .lock           = nfs3_proc_lock,
965         .clear_acl_cache = forget_all_cached_acls,
966         .close_context  = nfs_close_context,
967         .have_delegation = nfs3_have_delegation,
968         .return_delegation = nfs3_return_delegation,
969         .alloc_client   = nfs_alloc_client,
970         .init_client    = nfs_init_client,
971         .free_client    = nfs_free_client,
972         .create_server  = nfs3_create_server,
973         .clone_server   = nfs3_clone_server,
974 };
975 

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