The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/nfsd/nfs3proc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * linux/fs/nfsd/nfs3proc.c
    3  *
    4  * Process version 3 NFS requests.
    5  *
    6  * Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de>
    7  */
    8 
    9 #include <linux/linkage.h>
   10 #include <linux/sched.h>
   11 #include <linux/errno.h>
   12 #include <linux/locks.h>
   13 #include <linux/fs.h>
   14 #include <linux/ext2_fs.h>
   15 #include <linux/stat.h>
   16 #include <linux/fcntl.h>
   17 #include <linux/net.h>
   18 #include <linux/in.h>
   19 #include <linux/version.h>
   20 #include <linux/unistd.h>
   21 #include <linux/slab.h>
   22 #include <linux/major.h>
   23 
   24 #include <linux/sunrpc/svc.h>
   25 #include <linux/nfsd/nfsd.h>
   26 #include <linux/nfsd/cache.h>
   27 #include <linux/nfsd/xdr3.h>
   28 #include <linux/nfs3.h>
   29 
   30 #define NFSDDBG_FACILITY                NFSDDBG_PROC
   31 
   32 #define RETURN_STATUS(st)       { resp->status = (st); return (st); }
   33 
   34 static int      nfs3_ftypes[] = {
   35         0,                      /* NF3NON */
   36         S_IFREG,                /* NF3REG */
   37         S_IFDIR,                /* NF3DIR */
   38         S_IFBLK,                /* NF3BLK */
   39         S_IFCHR,                /* NF3CHR */
   40         S_IFLNK,                /* NF3LNK */
   41         S_IFSOCK,               /* NF3SOCK */
   42         S_IFIFO,                /* NF3FIFO */
   43 };
   44 
   45 /*
   46  * Reserve room in the send buffer
   47  */
   48 static void
   49 svcbuf_reserve(struct svc_buf *buf, u32 **ptr, int *len, int nr)
   50 {
   51         *ptr = buf->buf + nr;
   52         *len = buf->buflen - buf->len - nr;
   53 }
   54 
   55 /*
   56  * NULL call.
   57  */
   58 static int
   59 nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
   60 {
   61         return nfs_ok;
   62 }
   63 
   64 /*
   65  * Get a file's attributes
   66  */
   67 static int
   68 nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
   69                                            struct nfsd3_attrstat *resp)
   70 {
   71         int     nfserr;
   72 
   73         dprintk("nfsd: GETATTR(3)  %s\n",
   74                                 SVCFH_fmt(&argp->fh));
   75 
   76         fh_copy(&resp->fh, &argp->fh);
   77         nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
   78         RETURN_STATUS(nfserr);
   79 }
   80 
   81 /*
   82  * Set a file's attributes
   83  */
   84 static int
   85 nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
   86                                            struct nfsd3_attrstat  *resp)
   87 {
   88         int     nfserr;
   89 
   90         dprintk("nfsd: SETATTR(3)  %s\n",
   91                                 SVCFH_fmt(&argp->fh));
   92 
   93         fh_copy(&resp->fh, &argp->fh);
   94         nfserr = nfsd_setattr(rqstp, &resp->fh, &argp->attrs,
   95                               argp->check_guard, argp->guardtime);
   96         RETURN_STATUS(nfserr);
   97 }
   98 
   99 /*
  100  * Look up a path name component
  101  */
  102 static int
  103 nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
  104                                           struct nfsd3_diropres  *resp)
  105 {
  106         int     nfserr;
  107 
  108         dprintk("nfsd: LOOKUP(3)   %s %.*s\n",
  109                                 SVCFH_fmt(&argp->fh),
  110                                 argp->len,
  111                                 argp->name);
  112 
  113         fh_copy(&resp->dirfh, &argp->fh);
  114         fh_init(&resp->fh, NFS3_FHSIZE);
  115 
  116         nfserr = nfsd_lookup(rqstp, &resp->dirfh,
  117                                     argp->name,
  118                                     argp->len,
  119                                     &resp->fh);
  120         RETURN_STATUS(nfserr);
  121 }
  122 
  123 /*
  124  * Check file access
  125  */
  126 static int
  127 nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
  128                                           struct nfsd3_accessres *resp)
  129 {
  130         int     nfserr;
  131 
  132         dprintk("nfsd: ACCESS(3)   %s 0x%x\n",
  133                                 SVCFH_fmt(&argp->fh),
  134                                 argp->access);
  135 
  136         fh_copy(&resp->fh, &argp->fh);
  137         resp->access = argp->access;
  138         nfserr = nfsd_access(rqstp, &resp->fh, &resp->access);
  139         RETURN_STATUS(nfserr);
  140 }
  141 
  142 /*
  143  * Read a symlink.
  144  */
  145 static int
  146 nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd_fhandle     *argp,
  147                                            struct nfsd3_readlinkres *resp)
  148 {
  149         u32             *path;
  150         int             dummy, nfserr;
  151 
  152         dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));
  153 
  154         /* Reserve room for status, post_op_attr, and path length */
  155         svcbuf_reserve(&rqstp->rq_resbuf, &path, &dummy,
  156                                 1 + NFS3_POST_OP_ATTR_WORDS + 1);
  157 
  158         /* Read the symlink. */
  159         fh_copy(&resp->fh, &argp->fh);
  160         resp->len = NFS3_MAXPATHLEN;
  161         nfserr = nfsd_readlink(rqstp, &resp->fh, (char *) path, &resp->len);
  162         RETURN_STATUS(nfserr);
  163 }
  164 
  165 /*
  166  * Read a portion of a file.
  167  */
  168 static int
  169 nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
  170                                         struct nfsd3_readres  *resp)
  171 {
  172         u32 *   buffer;
  173         int     nfserr, avail;
  174 
  175         dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
  176                                 SVCFH_fmt(&argp->fh),
  177                                 (unsigned long) argp->count,
  178                                 (unsigned long) argp->offset);
  179 
  180         /* Obtain buffer pointer for payload.
  181          * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof)
  182          * + 1 (xdr opaque byte count) = 26
  183          */
  184         svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &avail,
  185                         1 + NFS3_POST_OP_ATTR_WORDS + 3);
  186 
  187         resp->count = argp->count;
  188         if ((avail << 2) < resp->count)
  189                 resp->count = avail << 2;
  190 
  191         svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + argp->count +4);
  192 
  193         fh_copy(&resp->fh, &argp->fh);
  194         nfserr = nfsd_read(rqstp, &resp->fh,
  195                                   argp->offset,
  196                                   (char *) buffer,
  197                                   &resp->count);
  198         if (nfserr == 0) {
  199                 struct inode    *inode = resp->fh.fh_dentry->d_inode;
  200 
  201                 resp->eof = (argp->offset + resp->count) >= inode->i_size;
  202         }
  203 
  204         RETURN_STATUS(nfserr);
  205 }
  206 
  207 /*
  208  * Write data to a file
  209  */
  210 static int
  211 nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
  212                                          struct nfsd3_writeres  *resp)
  213 {
  214         int     nfserr;
  215 
  216         dprintk("nfsd: WRITE(3)    %s %d bytes at %ld%s\n",
  217                                 SVCFH_fmt(&argp->fh),
  218                                 argp->len,
  219                                 (unsigned long) argp->offset,
  220                                 argp->stable? " stable" : "");
  221 
  222         fh_copy(&resp->fh, &argp->fh);
  223         resp->committed = argp->stable;
  224         nfserr = nfsd_write(rqstp, &resp->fh,
  225                                    argp->offset,
  226                                    argp->data,
  227                                    argp->len,
  228                                    &resp->committed);
  229         resp->count = argp->count;
  230         RETURN_STATUS(nfserr);
  231 }
  232 
  233 /*
  234  * With NFSv3, CREATE processing is a lot easier than with NFSv2.
  235  * At least in theory; we'll see how it fares in practice when the
  236  * first reports about SunOS compatibility problems start to pour in...
  237  */
  238 static int
  239 nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
  240                                           struct nfsd3_diropres   *resp)
  241 {
  242         svc_fh          *dirfhp, *newfhp = NULL;
  243         struct iattr    *attr;
  244         u32             nfserr;
  245 
  246         dprintk("nfsd: CREATE(3)   %s %.*s\n",
  247                                 SVCFH_fmt(&argp->fh),
  248                                 argp->len,
  249                                 argp->name);
  250 
  251         dirfhp = fh_copy(&resp->dirfh, &argp->fh);
  252         newfhp = fh_init(&resp->fh, NFS3_FHSIZE);
  253         attr   = &argp->attrs;
  254 
  255         /* Get the directory inode */
  256         nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_CREATE);
  257         if (nfserr)
  258                 RETURN_STATUS(nfserr);
  259 
  260         /* Unfudge the mode bits */
  261         attr->ia_mode &= ~S_IFMT;
  262         if (!(attr->ia_valid & ATTR_MODE)) { 
  263                 attr->ia_valid |= ATTR_MODE;
  264                 attr->ia_mode = S_IFREG;
  265         } else {
  266                 attr->ia_mode = (attr->ia_mode & ~S_IFMT) | S_IFREG;
  267         }
  268 
  269         /* Now create the file and set attributes */
  270         nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
  271                                 attr, newfhp,
  272                                 argp->createmode, argp->verf);
  273 
  274         RETURN_STATUS(nfserr);
  275 }
  276 
  277 /*
  278  * Make directory. This operation is not idempotent.
  279  */
  280 static int
  281 nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
  282                                          struct nfsd3_diropres   *resp)
  283 {
  284         int     nfserr;
  285 
  286         dprintk("nfsd: MKDIR(3)    %s %.*s\n",
  287                                 SVCFH_fmt(&argp->fh),
  288                                 argp->len,
  289                                 argp->name);
  290 
  291         argp->attrs.ia_valid &= ~ATTR_SIZE;
  292         fh_copy(&resp->dirfh, &argp->fh);
  293         fh_init(&resp->fh, NFS3_FHSIZE);
  294         nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
  295                                     &argp->attrs, S_IFDIR, 0, &resp->fh);
  296 
  297         RETURN_STATUS(nfserr);
  298 }
  299 
  300 static int
  301 nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
  302                                            struct nfsd3_diropres    *resp)
  303 {
  304         int     nfserr;
  305 
  306         dprintk("nfsd: SYMLINK(3)  %s %.*s -> %.*s\n",
  307                                 SVCFH_fmt(&argp->ffh),
  308                                 argp->flen, argp->fname,
  309                                 argp->tlen, argp->tname);
  310 
  311         fh_copy(&resp->dirfh, &argp->ffh);
  312         fh_init(&resp->fh, NFS3_FHSIZE);
  313         nfserr = nfsd_symlink(rqstp, &resp->dirfh, argp->fname, argp->flen,
  314                                                    argp->tname, argp->tlen,
  315                                                    &resp->fh, &argp->attrs);
  316         RETURN_STATUS(nfserr);
  317 }
  318 
  319 /*
  320  * Make socket/fifo/device.
  321  */
  322 static int
  323 nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
  324                                          struct nfsd3_diropres  *resp)
  325 {
  326         int     nfserr, type;
  327         dev_t   rdev = 0;
  328 
  329         dprintk("nfsd: MKNOD(3)    %s %.*s\n",
  330                                 SVCFH_fmt(&argp->fh),
  331                                 argp->len,
  332                                 argp->name);
  333 
  334         fh_copy(&resp->dirfh, &argp->fh);
  335         fh_init(&resp->fh, NFS3_FHSIZE);
  336 
  337         if (argp->ftype == 0 || argp->ftype >= NF3BAD)
  338                 RETURN_STATUS(nfserr_inval);
  339         if (argp->ftype == NF3CHR || argp->ftype == NF3BLK) {
  340                 if ((argp->ftype == NF3CHR && argp->major >= MAX_CHRDEV)
  341                     || (argp->ftype == NF3BLK && argp->major >= MAX_BLKDEV)
  342                     || argp->minor > 0xFF)
  343                         RETURN_STATUS(nfserr_inval);
  344                 rdev = MKDEV(argp->major, argp->minor);
  345         } else
  346                 if (argp->ftype != NF3SOCK && argp->ftype != NF3FIFO)
  347                         RETURN_STATUS(nfserr_inval);
  348 
  349         type = nfs3_ftypes[argp->ftype];
  350         nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
  351                                     &argp->attrs, type, rdev, &resp->fh);
  352 
  353         RETURN_STATUS(nfserr);
  354 }
  355 
  356 /*
  357  * Remove file/fifo/socket etc.
  358  */
  359 static int
  360 nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
  361                                           struct nfsd3_attrstat  *resp)
  362 {
  363         int     nfserr;
  364 
  365         dprintk("nfsd: REMOVE(3)   %s %.*s\n",
  366                                 SVCFH_fmt(&argp->fh),
  367                                 argp->len,
  368                                 argp->name);
  369 
  370         /* Unlink. -S_IFDIR means file must not be a directory */
  371         fh_copy(&resp->fh, &argp->fh);
  372         nfserr = nfsd_unlink(rqstp, &resp->fh, -S_IFDIR, argp->name, argp->len);
  373         RETURN_STATUS(nfserr);
  374 }
  375 
  376 /*
  377  * Remove a directory
  378  */
  379 static int
  380 nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
  381                                          struct nfsd3_attrstat  *resp)
  382 {
  383         int     nfserr;
  384 
  385         dprintk("nfsd: RMDIR(3)    %s %.*s\n",
  386                                 SVCFH_fmt(&argp->fh),
  387                                 argp->len,
  388                                 argp->name);
  389 
  390         fh_copy(&resp->fh, &argp->fh);
  391         nfserr = nfsd_unlink(rqstp, &resp->fh, S_IFDIR, argp->name, argp->len);
  392         RETURN_STATUS(nfserr);
  393 }
  394 
  395 static int
  396 nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
  397                                           struct nfsd3_renameres  *resp)
  398 {
  399         int     nfserr;
  400 
  401         dprintk("nfsd: RENAME(3)   %s %.*s ->\n",
  402                                 SVCFH_fmt(&argp->ffh),
  403                                 argp->flen,
  404                                 argp->fname);
  405         dprintk("nfsd: -> %s %.*s\n",
  406                                 SVCFH_fmt(&argp->tfh),
  407                                 argp->tlen,
  408                                 argp->tname);
  409 
  410         fh_copy(&resp->ffh, &argp->ffh);
  411         fh_copy(&resp->tfh, &argp->tfh);
  412         nfserr = nfsd_rename(rqstp, &resp->ffh, argp->fname, argp->flen,
  413                                     &resp->tfh, argp->tname, argp->tlen);
  414         RETURN_STATUS(nfserr);
  415 }
  416 
  417 static int
  418 nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
  419                                         struct nfsd3_linkres  *resp)
  420 {
  421         int     nfserr;
  422 
  423         dprintk("nfsd: LINK(3)     %s ->\n",
  424                                 SVCFH_fmt(&argp->ffh));
  425         dprintk("nfsd:   -> %s %.*s\n",
  426                                 SVCFH_fmt(&argp->tfh),
  427                                 argp->tlen,
  428                                 argp->tname);
  429 
  430         fh_copy(&resp->fh,  &argp->ffh);
  431         fh_copy(&resp->tfh, &argp->tfh);
  432         nfserr = nfsd_link(rqstp, &resp->tfh, argp->tname, argp->tlen,
  433                                   &resp->fh);
  434         RETURN_STATUS(nfserr);
  435 }
  436 
  437 /*
  438  * Read a portion of a directory.
  439  */
  440 static int
  441 nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
  442                                            struct nfsd3_readdirres  *resp)
  443 {
  444         u32 *           buffer;
  445         int             nfserr, count;
  446         unsigned int    want;
  447 
  448         dprintk("nfsd: READDIR(3)  %s %d bytes at %d\n",
  449                                 SVCFH_fmt(&argp->fh),
  450                                 argp->count, (u32) argp->cookie);
  451 
  452         /* Reserve buffer space for status, attributes and verifier */
  453         svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &count,
  454                                 1 + NFS3_POST_OP_ATTR_WORDS + 2);
  455 
  456         /* Make sure we've room for the NULL ptr & eof flag, and shrink to
  457          * client read size */
  458         if ((count -= 2) > (want = (argp->count >> 2) - 2))
  459                 count = want;
  460 
  461         /* Read directory and encode entries on the fly */
  462         fh_copy(&resp->fh, &argp->fh);
  463         nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t) argp->cookie, 
  464                                         nfs3svc_encode_entry,
  465                                         buffer, &count, argp->verf);
  466         memcpy(resp->verf, argp->verf, 8);
  467         resp->count = count;
  468 
  469         RETURN_STATUS(nfserr);
  470 }
  471 
  472 /*
  473  * Read a portion of a directory, including file handles and attrs.
  474  * For now, we choose to ignore the dircount parameter.
  475  */
  476 static int
  477 nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
  478                                                struct nfsd3_readdirres  *resp)
  479 {
  480         u32 *   buffer;
  481         int     nfserr, count, want;
  482 
  483         dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n",
  484                                 SVCFH_fmt(&argp->fh),
  485                                 argp->count, (u32) argp->cookie);
  486 
  487         /* Reserve buffer space for status, attributes and verifier */
  488         svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &count,
  489                                 1 + NFS3_POST_OP_ATTR_WORDS + 2);
  490 
  491         /* Make sure we've room for the NULL ptr & eof flag, and shrink to
  492          * client read size */
  493         if ((count -= 2) > (want = argp->count >> 2))
  494                 count = want;
  495 
  496         /* Read directory and encode entries on the fly */
  497         fh_copy(&resp->fh, &argp->fh);
  498         nfserr = nfsd_readdir(rqstp, &resp->fh, (loff_t) argp->cookie, 
  499                                         nfs3svc_encode_entry_plus,
  500                                         buffer, &count, argp->verf);
  501         memcpy(resp->verf, argp->verf, 8);
  502         resp->count = count;
  503 
  504         RETURN_STATUS(nfserr);
  505 }
  506 
  507 /*
  508  * Get file system stats
  509  */
  510 static int
  511 nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
  512                                            struct nfsd3_fsstatres *resp)
  513 {
  514         int     nfserr;
  515 
  516         dprintk("nfsd: FSSTAT(3)   %s\n",
  517                                 SVCFH_fmt(&argp->fh));
  518 
  519         nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
  520         fh_put(&argp->fh);
  521         RETURN_STATUS(nfserr);
  522 }
  523 
  524 /*
  525  * Get file system info
  526  */
  527 static int
  528 nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
  529                                            struct nfsd3_fsinfores *resp)
  530 {
  531         int     nfserr;
  532 
  533         dprintk("nfsd: FSINFO(3)   %s\n",
  534                                 SVCFH_fmt(&argp->fh));
  535 
  536         resp->f_rtmax  = NFSSVC_MAXBLKSIZE;
  537         resp->f_rtpref = NFSSVC_MAXBLKSIZE;
  538         resp->f_rtmult = PAGE_SIZE;
  539         resp->f_wtmax  = NFSSVC_MAXBLKSIZE;
  540         resp->f_wtpref = NFSSVC_MAXBLKSIZE;
  541         resp->f_wtmult = PAGE_SIZE;
  542         resp->f_dtpref = PAGE_SIZE;
  543         resp->f_maxfilesize = ~(u32) 0;
  544         resp->f_properties = NFS3_FSF_DEFAULT;
  545 
  546         nfserr = fh_verify(rqstp, &argp->fh, 0, MAY_NOP);
  547 
  548         /* Check special features of the file system. May request
  549          * different read/write sizes for file systems known to have
  550          * problems with large blocks */
  551         if (nfserr == 0) {
  552                 struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb;
  553 
  554                 /* Note that we don't care for remote fs's here */
  555                 if (sb->s_magic == 0x4d44 /* MSDOS_SUPER_MAGIC */) {
  556                         resp->f_properties = NFS3_FSF_BILLYBOY;
  557                 }
  558                 resp->f_maxfilesize = sb->s_maxbytes;
  559         }
  560 
  561         fh_put(&argp->fh);
  562         RETURN_STATUS(nfserr);
  563 }
  564 
  565 /*
  566  * Get pathconf info for the specified file
  567  */
  568 static int
  569 nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
  570                                              struct nfsd3_pathconfres *resp)
  571 {
  572         int     nfserr;
  573 
  574         dprintk("nfsd: PATHCONF(3) %s\n",
  575                                 SVCFH_fmt(&argp->fh));
  576 
  577         /* Set default pathconf */
  578         resp->p_link_max = 255;         /* at least */
  579         resp->p_name_max = 255;         /* at least */
  580         resp->p_no_trunc = 0;
  581         resp->p_chown_restricted = 1;
  582         resp->p_case_insensitive = 0;
  583         resp->p_case_preserving = 1;
  584 
  585         nfserr = fh_verify(rqstp, &argp->fh, 0, MAY_NOP);
  586 
  587         if (nfserr == 0) {
  588                 struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb;
  589 
  590                 /* Note that we don't care for remote fs's here */
  591                 switch (sb->s_magic) {
  592                 case EXT2_SUPER_MAGIC:
  593                         resp->p_link_max = EXT2_LINK_MAX;
  594                         resp->p_name_max = EXT2_NAME_LEN;
  595                         break;
  596                 case 0x4d44:    /* MSDOS_SUPER_MAGIC */
  597                         resp->p_case_insensitive = 1;
  598                         resp->p_case_preserving  = 0;
  599                         break;
  600                 }
  601         }
  602 
  603         fh_put(&argp->fh);
  604         RETURN_STATUS(nfserr);
  605 }
  606 
  607 
  608 /*
  609  * Commit a file (range) to stable storage.
  610  */
  611 static int
  612 nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp,
  613                                            struct nfsd3_commitres  *resp)
  614 {
  615         int     nfserr;
  616 
  617         dprintk("nfsd: COMMIT(3)   %s %d@%ld\n",
  618                                 SVCFH_fmt(&argp->fh),
  619                                 argp->count,
  620                                 (unsigned long) argp->offset);
  621 
  622         if (argp->offset > NFS_OFFSET_MAX)
  623                 RETURN_STATUS(nfserr_inval);
  624 
  625         fh_copy(&resp->fh, &argp->fh);
  626         nfserr = nfsd_commit(rqstp, &resp->fh, argp->offset, argp->count);
  627 
  628         RETURN_STATUS(nfserr);
  629 }
  630 
  631 
  632 /*
  633  * NFSv3 Server procedures.
  634  * Only the results of non-idempotent operations are cached.
  635  */
  636 #define nfs3svc_decode_voidargs         NULL
  637 #define nfs3svc_release_void            NULL
  638 #define nfs3svc_decode_fhandleargs      nfs3svc_decode_fhandle
  639 #define nfs3svc_encode_attrstatres      nfs3svc_encode_attrstat
  640 #define nfs3svc_encode_wccstatres       nfs3svc_encode_wccstat
  641 #define nfsd3_mkdirargs                 nfsd3_createargs
  642 #define nfsd3_readdirplusargs           nfsd3_readdirargs
  643 #define nfsd3_fhandleargs               nfsd_fhandle
  644 #define nfsd3_fhandleres                nfsd3_attrstat
  645 #define nfsd3_attrstatres               nfsd3_attrstat
  646 #define nfsd3_wccstatres                nfsd3_attrstat
  647 #define nfsd3_createres                 nfsd3_diropres
  648 #define nfsd3_voidres                   nfsd3_voidargs
  649 struct nfsd3_voidargs { int dummy; };
  650 
  651 #define PROC(name, argt, rest, relt, cache, respsize)   \
  652  { (svc_procfunc) nfsd3_proc_##name,            \
  653    (kxdrproc_t) nfs3svc_decode_##argt##args,    \
  654    (kxdrproc_t) nfs3svc_encode_##rest##res,     \
  655    (kxdrproc_t) nfs3svc_release_##relt,         \
  656    sizeof(struct nfsd3_##argt##args),           \
  657    sizeof(struct nfsd3_##rest##res),            \
  658    0,                                           \
  659    cache,                                       \
  660    respsize,                                    \
  661  }
  662 
  663 #define ST 1            /* status*/
  664 #define FH 17           /* filehandle with length */
  665 #define AT 21           /* attributes */
  666 #define pAT (1+AT)      /* post attributes - conditional */
  667 #define WC (7+pAT)      /* WCC attributes */
  668 
  669 struct svc_procedure            nfsd_procedures3[22] = {
  670   PROC(null,     void,          void,           void,    RC_NOCACHE, ST),
  671   PROC(getattr,  fhandle,       attrstat,       fhandle, RC_NOCACHE, ST+AT),
  672   PROC(setattr,  sattr,         wccstat,        fhandle,  RC_REPLBUFF, ST+WC),
  673   PROC(lookup,   dirop,         dirop,          fhandle2, RC_NOCACHE, ST+FH+pAT+pAT),
  674   PROC(access,   access,        access,         fhandle,  RC_NOCACHE, ST+pAT+1),
  675   PROC(readlink, fhandle,       readlink,       fhandle,  RC_NOCACHE, ST+pAT+1+NFS3_MAXPATHLEN/4),
  676   PROC(read,     read,          read,           fhandle, RC_NOCACHE, ST+pAT+4+NFSSVC_MAXBLKSIZE),
  677   PROC(write,    write,         write,          fhandle,  RC_REPLBUFF, ST+WC+4),
  678   PROC(create,   create,        create,         fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
  679   PROC(mkdir,    mkdir,         create,         fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
  680   PROC(symlink,  symlink,       create,         fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
  681   PROC(mknod,    mknod,         create,         fhandle2, RC_REPLBUFF, ST+(1+FH+pAT)+WC),
  682   PROC(remove,   dirop,         wccstat,        fhandle,  RC_REPLBUFF, ST+WC),
  683   PROC(rmdir,    dirop,         wccstat,        fhandle,  RC_REPLBUFF, ST+WC),
  684   PROC(rename,   rename,        rename,         fhandle2, RC_REPLBUFF, ST+WC+WC),
  685   PROC(link,     link,          link,           fhandle2, RC_REPLBUFF, ST+pAT+WC),
  686   PROC(readdir,  readdir,       readdir,        fhandle,  RC_NOCACHE, 0),
  687   PROC(readdirplus,readdirplus, readdir,        fhandle,  RC_NOCACHE, 0),
  688   PROC(fsstat,   fhandle,       fsstat,         void,     RC_NOCACHE, ST+pAT+2*6+1),
  689   PROC(fsinfo,   fhandle,       fsinfo,         void,     RC_NOCACHE, ST+pAT+12),
  690   PROC(pathconf, fhandle,       pathconf,       void,     RC_NOCACHE, ST+pAT+6),
  691   PROC(commit,   commit,        commit,         fhandle,  RC_NOCACHE, ST+WC+2),
  692 };

Cache object: fe4db88b34082aa8efe896765dc05fdd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.