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/vfs.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 #define MSNFS   /* HACK HACK */
    2 /*
    3  * linux/fs/nfsd/vfs.c
    4  *
    5  * File operations used by nfsd. Some of these have been ripped from
    6  * other parts of the kernel because they weren't in ksyms.c, others
    7  * are partial duplicates with added or changed functionality.
    8  *
    9  * Note that several functions dget() the dentry upon which they want
   10  * to act, most notably those that create directory entries. Response
   11  * dentry's are dput()'d if necessary in the release callback.
   12  * So if you notice code paths that apparently fail to dput() the
   13  * dentry, don't worry--they have been taken care of.
   14  *
   15  * Copyright (C) 1995-1999 Olaf Kirch <okir@monad.swb.de>
   16  */
   17 
   18 #include <linux/config.h>
   19 #include <linux/version.h>
   20 #include <linux/string.h>
   21 #include <linux/sched.h>
   22 #include <linux/errno.h>
   23 #include <linux/locks.h>
   24 #include <linux/fs.h>
   25 #include <linux/major.h>
   26 #include <linux/ext2_fs.h>
   27 #include <linux/proc_fs.h>
   28 #include <linux/stat.h>
   29 #include <linux/fcntl.h>
   30 #include <linux/net.h>
   31 #include <linux/unistd.h>
   32 #include <linux/slab.h>
   33 #include <linux/in.h>
   34 #define __NO_VERSION__
   35 #include <linux/module.h>
   36 
   37 #include <linux/sunrpc/svc.h>
   38 #include <linux/nfsd/nfsd.h>
   39 #ifdef CONFIG_NFSD_V3
   40 #include <linux/nfs3.h>
   41 #include <linux/nfsd/xdr3.h>
   42 #endif /* CONFIG_NFSD_V3 */
   43 #include <linux/nfsd/nfsfh.h>
   44 #include <linux/quotaops.h>
   45 
   46 #include <asm/uaccess.h>
   47 
   48 #define NFSDDBG_FACILITY                NFSDDBG_FILEOP
   49 #define NFSD_PARANOIA
   50 
   51 
   52 /* We must ignore files (but only files) which might have mandatory
   53  * locks on them because there is no way to know if the accesser has
   54  * the lock.
   55  */
   56 #define IS_ISMNDLK(i)   (S_ISREG((i)->i_mode) && MANDATORY_LOCK(i))
   57 
   58 /*
   59  * This is a cache of readahead params that help us choose the proper
   60  * readahead strategy. Initially, we set all readahead parameters to 0
   61  * and let the VFS handle things.
   62  * If you increase the number of cached files very much, you'll need to
   63  * add a hash table here.
   64  */
   65 struct raparms {
   66         struct raparms          *p_next;
   67         unsigned int            p_count;
   68         ino_t                   p_ino;
   69         dev_t                   p_dev;
   70         unsigned long           p_reada,
   71                                 p_ramax,
   72                                 p_raend,
   73                                 p_ralen,
   74                                 p_rawin;
   75 };
   76 
   77 static struct raparms *         raparml;
   78 static struct raparms *         raparm_cache;
   79 
   80 /*
   81  * Look up one component of a pathname.
   82  * N.B. After this call _both_ fhp and resfh need an fh_put
   83  *
   84  * If the lookup would cross a mountpoint, and the mounted filesystem
   85  * is exported to the client with NFSEXP_CROSSMNT, then the lookup is
   86  * accepted as it stands and the mounted directory is
   87  * returned. Otherwise the covered directory is returned.
   88  * NOTE: this mountpoint crossing is not supported properly by all
   89  *   clients and is explicitly disallowed for NFSv3
   90  *      NeilBrown <neilb@cse.unsw.edu.au>
   91  */
   92 int
   93 nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
   94                                         int len, struct svc_fh *resfh)
   95 {
   96         struct svc_export       *exp;
   97         struct dentry           *dparent;
   98         struct dentry           *dentry;
   99         int                     err;
  100 
  101         dprintk("nfsd: nfsd_lookup(fh %s, %.*s)\n", SVCFH_fmt(fhp), len,name);
  102 
  103         /* Obtain dentry and export. */
  104         err = fh_verify(rqstp, fhp, S_IFDIR, MAY_EXEC);
  105         if (err)
  106                 goto out;
  107 
  108         dparent = fhp->fh_dentry;
  109         exp  = fhp->fh_export;
  110 
  111         err = nfserr_acces;
  112 
  113         /* Lookup the name, but don't follow links */
  114         if (isdotent(name, len)) {
  115                 if (len==1)
  116                         dentry = dget(dparent);
  117                 else if (dparent != exp->ex_dentry)
  118                         dentry = dget(dparent->d_parent);
  119                 else if (!EX_CROSSMNT(exp))
  120                         dentry = dget(dparent); /* .. == . just like at / */
  121                 else {
  122                         /* checking mountpoint crossing is very different when stepping up */
  123                         struct svc_export *exp2 = NULL;
  124                         struct dentry *dp;
  125                         struct vfsmount *mnt = mntget(exp->ex_mnt);
  126                         dentry = dget(dparent);
  127                         while(follow_up(&mnt, &dentry))
  128                                 ;
  129                         dp = dget(dentry->d_parent);
  130                         dput(dentry);
  131                         dentry = dp;
  132                         for ( ; exp2 == NULL && dp->d_parent != dp;
  133                               dp=dp->d_parent)
  134                                 exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
  135                         if (exp2==NULL) {
  136                                 dput(dentry);
  137                                 dentry = dget(dparent);
  138                         } else {
  139                                 exp = exp2;
  140                         }
  141                         mntput(mnt);
  142                 }
  143         } else {
  144                 fh_lock(fhp);
  145                 dentry = lookup_one_len(name, dparent, len);
  146                 err = PTR_ERR(dentry);
  147                 if (IS_ERR(dentry))
  148                         goto out_nfserr;
  149                 /*
  150                  * check if we have crossed a mount point ...
  151                  */
  152                 if (d_mountpoint(dentry)) {
  153                         struct svc_export *exp2 = NULL;
  154                         struct vfsmount *mnt = mntget(exp->ex_mnt);
  155                         struct dentry *mounts = dget(dentry);
  156                         while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
  157                                 ;
  158                         exp2 = exp_get(rqstp->rq_client,
  159                                        mounts->d_inode->i_dev,
  160                                        mounts->d_inode->i_ino);
  161                         if (exp2 && EX_CROSSMNT(exp2)) {
  162                                 /* successfully crossed mount point */
  163                                 exp = exp2;
  164                                 dput(dentry);
  165                                 dentry = mounts;
  166                         } else
  167                                 dput(mounts);
  168                         mntput(mnt);
  169                 }
  170         }
  171 
  172         if (dentry->d_inode && dentry->d_inode->i_op &&
  173             dentry->d_inode->i_op->revalidate &&
  174             dentry->d_inode->i_op->revalidate(dentry))
  175                 err = nfserr_noent;
  176         else
  177                 err = fh_compose(resfh, exp, dentry, fhp);
  178         if (!err && !dentry->d_inode)
  179                 err = nfserr_noent;
  180 out:
  181         return err;
  182 
  183 out_nfserr:
  184         err = nfserrno(err);
  185         goto out;
  186 }
  187 
  188 /*
  189  * Set various file attributes.
  190  * N.B. After this call fhp needs an fh_put
  191  */
  192 int
  193 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
  194              int check_guard, time_t guardtime)
  195 {
  196         struct dentry   *dentry;
  197         struct inode    *inode;
  198         int             accmode = MAY_SATTR;
  199         int             ftype = 0;
  200         int             imode;
  201         int             err;
  202         int             size_change = 0;
  203 
  204         if (iap->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_SIZE))
  205                 accmode |= MAY_WRITE|MAY_OWNER_OVERRIDE;
  206         if (iap->ia_valid & ATTR_SIZE)
  207                 ftype = S_IFREG;
  208 
  209         /* Get inode */
  210         err = fh_verify(rqstp, fhp, ftype, accmode);
  211         if (err || !iap->ia_valid)
  212                 goto out;
  213 
  214         dentry = fhp->fh_dentry;
  215         inode = dentry->d_inode;
  216 
  217         /* NFSv2 does not differentiate between "set-[ac]time-to-now"
  218          * which only requires access, and "set-[ac]time-to-X" which
  219          * requires ownership.
  220          * So if it looks like it might be "set both to the same time which
  221          * is close to now", and if inode_change_ok fails, then we
  222          * convert to "set to now" instead of "set to explicit time"
  223          *
  224          * We only call inode_change_ok as the last test as technically
  225          * it is not an interface that we should be using.  It is only
  226          * valid if the filesystem does not define it's own i_op->setattr.
  227          */
  228 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
  229 #define MAX_TOUCH_TIME_ERROR (30*60)
  230         if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
  231             && iap->ia_mtime == iap->ia_atime
  232             ) {
  233             /* Looks probable.  Now just make sure time is in the right ballpark.
  234              * Solaris, at least, doesn't seem to care what the time request is.
  235              * We require it be within 30 minutes of now.
  236              */
  237             time_t delta = iap->ia_atime - CURRENT_TIME;
  238             if (delta<0) delta = -delta;
  239             if (delta < MAX_TOUCH_TIME_ERROR &&
  240                 inode_change_ok(inode, iap) != 0) {
  241                 /* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
  242                  * this will cause notify_change to set these times to "now"
  243                  */
  244                 iap->ia_valid &= ~BOTH_TIME_SET;
  245             }
  246         }
  247             
  248         /* The size case is special. It changes the file as well as the attributes.  */
  249         if (iap->ia_valid & ATTR_SIZE) {
  250                 if (iap->ia_size < inode->i_size) {
  251                         err = nfsd_permission(fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);
  252                         if (err)
  253                                 goto out;
  254                 }
  255 
  256                 /*
  257                  * If we are changing the size of the file, then
  258                  * we need to break all leases.
  259                  */
  260                 err = get_lease(inode, FMODE_WRITE);
  261                 if (err)
  262                         goto out_nfserr;
  263 
  264                 err = get_write_access(inode);
  265                 if (err)
  266                         goto out_nfserr;
  267 
  268                 err = locks_verify_truncate(inode, NULL, iap->ia_size);
  269                 if (err) {
  270                         put_write_access(inode);
  271                         goto out_nfserr;
  272                 }
  273                 DQUOT_INIT(inode);
  274         }
  275 
  276         imode = inode->i_mode;
  277         if (iap->ia_valid & ATTR_MODE) {
  278                 iap->ia_mode &= S_IALLUGO;
  279                 imode = iap->ia_mode |= (imode & ~S_IALLUGO);
  280         }
  281 
  282         /* Revoke setuid/setgid bit on chown/chgrp */
  283         if ((iap->ia_valid & ATTR_UID) && (imode & S_ISUID)
  284          && iap->ia_uid != inode->i_uid) {
  285                 iap->ia_valid |= ATTR_MODE;
  286                 iap->ia_mode = imode &= ~S_ISUID;
  287         }
  288         if ((iap->ia_valid & ATTR_GID) && (imode & S_ISGID)
  289          && iap->ia_gid != inode->i_gid) {
  290                 iap->ia_valid |= ATTR_MODE;
  291                 iap->ia_mode = imode &= ~S_ISGID;
  292         }
  293 
  294         /* Change the attributes. */
  295 
  296 
  297         iap->ia_valid |= ATTR_CTIME;
  298 
  299         if (iap->ia_valid & ATTR_SIZE) {
  300                 fh_lock(fhp);
  301                 size_change = 1;
  302         }
  303         err = nfserr_notsync;
  304         if (!check_guard || guardtime == inode->i_ctime) {
  305                 err = notify_change(dentry, iap);
  306                 err = nfserrno(err);
  307         }
  308         if (size_change) {
  309                 fh_unlock(fhp);
  310                 put_write_access(inode);
  311         }
  312         if (!err)
  313                 if (EX_ISSYNC(fhp->fh_export))
  314                         write_inode_now(inode, 1);
  315 out:
  316         return err;
  317 
  318 out_nfserr:
  319         err = nfserrno(err);
  320         goto out;
  321 }
  322 
  323 #ifdef CONFIG_NFSD_V3
  324 /*
  325  * Check server access rights to a file system object
  326  */
  327 struct accessmap {
  328         u32             access;
  329         int             how;
  330 };
  331 static struct accessmap nfs3_regaccess[] = {
  332     {   NFS3_ACCESS_READ,       MAY_READ                        },
  333     {   NFS3_ACCESS_EXECUTE,    MAY_EXEC                        },
  334     {   NFS3_ACCESS_MODIFY,     MAY_WRITE|MAY_TRUNC             },
  335     {   NFS3_ACCESS_EXTEND,     MAY_WRITE                       },
  336 
  337     {   0,                      0                               }
  338 };
  339 
  340 static struct accessmap nfs3_diraccess[] = {
  341     {   NFS3_ACCESS_READ,       MAY_READ                        },
  342     {   NFS3_ACCESS_LOOKUP,     MAY_EXEC                        },
  343     {   NFS3_ACCESS_MODIFY,     MAY_EXEC|MAY_WRITE|MAY_TRUNC    },
  344     {   NFS3_ACCESS_EXTEND,     MAY_EXEC|MAY_WRITE              },
  345     {   NFS3_ACCESS_DELETE,     MAY_REMOVE                      },
  346 
  347     {   0,                      0                               }
  348 };
  349 
  350 static struct accessmap nfs3_anyaccess[] = {
  351         /* Some clients - Solaris 2.6 at least, make an access call
  352          * to the server to check for access for things like /dev/null
  353          * (which really, the server doesn't care about).  So
  354          * We provide simple access checking for them, looking
  355          * mainly at mode bits
  356          */
  357     {   NFS3_ACCESS_READ,       MAY_READ                        },
  358     {   NFS3_ACCESS_EXECUTE,    MAY_EXEC                        },
  359     {   NFS3_ACCESS_MODIFY,     MAY_WRITE                       },
  360     {   NFS3_ACCESS_EXTEND,     MAY_WRITE                       },
  361 
  362     {   0,                      0                               }
  363 };
  364 
  365 int
  366 nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access)
  367 {
  368         struct accessmap        *map;
  369         struct svc_export       *export;
  370         struct dentry           *dentry;
  371         u32                     query, result = 0;
  372         unsigned int            error;
  373 
  374         error = fh_verify(rqstp, fhp, 0, MAY_NOP);
  375         if (error)
  376                 goto out;
  377 
  378         export = fhp->fh_export;
  379         dentry = fhp->fh_dentry;
  380 
  381         if (S_ISREG(dentry->d_inode->i_mode))
  382                 map = nfs3_regaccess;
  383         else if (S_ISDIR(dentry->d_inode->i_mode))
  384                 map = nfs3_diraccess;
  385         else
  386                 map = nfs3_anyaccess;
  387 
  388 
  389         query = *access;
  390         for  (; map->access; map++) {
  391                 if (map->access & query) {
  392                         unsigned int err2;
  393                         err2 = nfsd_permission(export, dentry, map->how);
  394                         switch (err2) {
  395                         case nfs_ok:
  396                                 result |= map->access;
  397                                 break;
  398                                 
  399                         /* the following error codes just mean the access was not allowed,
  400                          * rather than an error occurred */
  401                         case nfserr_rofs:
  402                         case nfserr_acces:
  403                         case nfserr_perm:
  404                                 /* simply don't "or" in the access bit. */
  405                                 break;
  406                         default:
  407                                 error = err2;
  408                                 goto out;
  409                         }
  410                 }
  411         }
  412         *access = result;
  413 
  414  out:
  415         return error;
  416 }
  417 #endif /* CONFIG_NFSD_V3 */
  418 
  419 
  420 
  421 /*
  422  * Open an existing file or directory.
  423  * The access argument indicates the type of open (read/write/lock)
  424  * N.B. After this call fhp needs an fh_put
  425  */
  426 int
  427 nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
  428                         int access, struct file *filp)
  429 {
  430         struct dentry   *dentry;
  431         struct inode    *inode;
  432         int             err;
  433 
  434         /* If we get here, then the client has already done an "open", and (hopefully)
  435          * checked permission - so allow OWNER_OVERRIDE in case a chmod has now revoked
  436          * permission */
  437         err = fh_verify(rqstp, fhp, type, access | MAY_OWNER_OVERRIDE);
  438         if (err)
  439                 goto out;
  440 
  441         dentry = fhp->fh_dentry;
  442         inode = dentry->d_inode;
  443 
  444         /* Disallow access to files with the append-only bit set or
  445          * with mandatory locking enabled
  446          */
  447         err = nfserr_perm;
  448         if (IS_APPEND(inode) || IS_ISMNDLK(inode))
  449                 goto out;
  450         if (!inode->i_fop)
  451                 goto out;
  452 
  453         /*
  454          * Check to see if there are any leases on this file.
  455          * This may block while leases are broken.
  456          */
  457         err = get_lease(inode, (access & MAY_WRITE) ? FMODE_WRITE : 0);
  458         if (err)
  459                 goto out_nfserr;
  460 
  461         if ((access & MAY_WRITE) && (err = get_write_access(inode)) != 0)
  462                 goto out_nfserr;
  463 
  464         memset(filp, 0, sizeof(*filp));
  465         filp->f_op    = fops_get(inode->i_fop);
  466         atomic_set(&filp->f_count, 1);
  467         filp->f_dentry = dentry;
  468         filp->f_vfsmnt = fhp->fh_export->ex_mnt;
  469         if (access & MAY_WRITE) {
  470                 filp->f_flags = O_WRONLY|O_LARGEFILE;
  471                 filp->f_mode  = FMODE_WRITE;
  472                 DQUOT_INIT(inode);
  473         } else {
  474                 filp->f_flags = O_RDONLY|O_LARGEFILE;
  475                 filp->f_mode  = FMODE_READ;
  476         }
  477 
  478         err = 0;
  479         if (filp->f_op && filp->f_op->open) {
  480                 err = filp->f_op->open(inode, filp);
  481                 if (err) {
  482                         fops_put(filp->f_op);
  483                         if (access & MAY_WRITE)
  484                                 put_write_access(inode);
  485 
  486                         /* I nearly added put_filp() call here, but this filp
  487                          * is really on callers stack frame. -DaveM
  488                          */
  489                         atomic_dec(&filp->f_count);
  490                 }
  491         }
  492 out_nfserr:
  493         if (err)
  494                 err = nfserrno(err);
  495 out:
  496         return err;
  497 }
  498 
  499 /*
  500  * Close a file.
  501  */
  502 void
  503 nfsd_close(struct file *filp)
  504 {
  505         struct dentry   *dentry = filp->f_dentry;
  506         struct inode    *inode = dentry->d_inode;
  507 
  508         if (filp->f_op && filp->f_op->release)
  509                 filp->f_op->release(inode, filp);
  510         fops_put(filp->f_op);
  511         if (filp->f_mode & FMODE_WRITE)
  512                 put_write_access(inode);
  513 }
  514 
  515 /*
  516  * Sync a file
  517  * As this calls fsync (not fdatasync) there is no need for a write_inode
  518  * after it.
  519  */
  520 inline void nfsd_dosync(struct file *filp, struct dentry *dp, 
  521                         struct file_operations *fop)
  522 {
  523         struct inode *inode = dp->d_inode;
  524         int (*fsync) (struct file *, struct dentry *, int);
  525 
  526         filemap_fdatasync(inode->i_mapping);
  527         if (fop && (fsync = fop->fsync))
  528                 fsync(filp, dp, 0);
  529         filemap_fdatawait(inode->i_mapping);
  530 }
  531         
  532 
  533 void
  534 nfsd_sync(struct file *filp)
  535 {
  536         struct inode *inode = filp->f_dentry->d_inode;
  537         dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
  538         down(&inode->i_sem);
  539         nfsd_dosync(filp, filp->f_dentry, filp->f_op);
  540         up(&inode->i_sem);
  541 }
  542 
  543 void
  544 nfsd_sync_dir(struct dentry *dp)
  545 {
  546         nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
  547 }
  548 
  549 /*
  550  * Obtain the readahead parameters for the file
  551  * specified by (dev, ino).
  552  */
  553 static inline struct raparms *
  554 nfsd_get_raparms(dev_t dev, ino_t ino)
  555 {
  556         struct raparms  *ra, **rap, **frap = NULL;
  557         int depth = 0;
  558         
  559         for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) {
  560                 if (ra->p_ino == ino && ra->p_dev == dev)
  561                         goto found;
  562                 depth++;
  563                 if (ra->p_count == 0)
  564                         frap = rap;
  565         }
  566         depth = nfsdstats.ra_size*11/10;
  567         if (!frap)
  568                 return NULL;
  569         rap = frap;
  570         ra = *frap;
  571         ra->p_dev = dev;
  572         ra->p_ino = ino;
  573         ra->p_reada = 0;
  574         ra->p_ramax = 0;
  575         ra->p_raend = 0;
  576         ra->p_ralen = 0;
  577         ra->p_rawin = 0;
  578 found:
  579         if (rap != &raparm_cache) {
  580                 *rap = ra->p_next;
  581                 ra->p_next   = raparm_cache;
  582                 raparm_cache = ra;
  583         }
  584         ra->p_count++;
  585         nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
  586         return ra;
  587 }
  588 
  589 /*
  590  * Read data from a file. count must contain the requested read count
  591  * on entry. On return, *count contains the number of bytes actually read.
  592  * N.B. After this call fhp needs an fh_put
  593  */
  594 int
  595 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
  596           char *buf, unsigned long *count)
  597 {
  598         struct raparms  *ra;
  599         mm_segment_t    oldfs;
  600         int             err;
  601         struct file     file;
  602 
  603         err = nfsd_open(rqstp, fhp, S_IFREG, MAY_READ, &file);
  604         if (err)
  605                 goto out;
  606         err = nfserr_perm;
  607         if (!file.f_op->read)
  608                 goto out_close;
  609 #ifdef MSNFS
  610         if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
  611                 (!lock_may_read(file.f_dentry->d_inode, offset, *count)))
  612                 goto out_close;
  613 #endif
  614 
  615         /* Get readahead parameters */
  616         ra = nfsd_get_raparms(fhp->fh_export->ex_dev, fhp->fh_dentry->d_inode->i_ino);
  617         if (ra) {
  618                 file.f_reada = ra->p_reada;
  619                 file.f_ramax = ra->p_ramax;
  620                 file.f_raend = ra->p_raend;
  621                 file.f_ralen = ra->p_ralen;
  622                 file.f_rawin = ra->p_rawin;
  623         }
  624         file.f_pos = offset;
  625 
  626         oldfs = get_fs(); set_fs(KERNEL_DS);
  627         err = file.f_op->read(&file, buf, *count, &file.f_pos);
  628         set_fs(oldfs);
  629 
  630         /* Write back readahead params */
  631         if (ra != NULL) {
  632                 dprintk("nfsd: raparms %ld %ld %ld %ld %ld\n",
  633                         file.f_reada, file.f_ramax, file.f_raend,
  634                         file.f_ralen, file.f_rawin);
  635                 ra->p_reada = file.f_reada;
  636                 ra->p_ramax = file.f_ramax;
  637                 ra->p_raend = file.f_raend;
  638                 ra->p_ralen = file.f_ralen;
  639                 ra->p_rawin = file.f_rawin;
  640                 ra->p_count -= 1;
  641         }
  642 
  643         if (err >= 0) {
  644                 nfsdstats.io_read += err;
  645                 *count = err;
  646                 err = 0;
  647         } else 
  648                 err = nfserrno(err);
  649 out_close:
  650         nfsd_close(&file);
  651 out:
  652         return err;
  653 }
  654 
  655 /*
  656  * Write data to a file.
  657  * The stable flag requests synchronous writes.
  658  * N.B. After this call fhp needs an fh_put
  659  */
  660 int
  661 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
  662                                 char *buf, unsigned long cnt, int *stablep)
  663 {
  664         struct svc_export       *exp;
  665         struct file             file;
  666         struct dentry           *dentry;
  667         struct inode            *inode;
  668         mm_segment_t            oldfs;
  669         int                     err = 0;
  670         int                     stable = *stablep;
  671 
  672         err = nfsd_open(rqstp, fhp, S_IFREG, MAY_WRITE, &file);
  673         if (err)
  674                 goto out;
  675         if (!cnt)
  676                 goto out_close;
  677         err = nfserr_perm;
  678         if (!file.f_op->write)
  679                 goto out_close;
  680 #ifdef MSNFS
  681         if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
  682                 (!lock_may_write(file.f_dentry->d_inode, offset, cnt)))
  683                 goto out_close;
  684 #endif
  685 
  686         dentry = file.f_dentry;
  687         inode = dentry->d_inode;
  688         exp   = fhp->fh_export;
  689 
  690         /*
  691          * Request sync writes if
  692          *  -   the sync export option has been set, or
  693          *  -   the client requested O_SYNC behavior (NFSv3 feature).
  694          *  -   The file system doesn't support fsync().
  695          * When gathered writes have been configured for this volume,
  696          * flushing the data to disk is handled separately below.
  697          */
  698 
  699         if (file.f_op->fsync == 0) {/* COMMIT3 cannot work */
  700                stable = 2;
  701                *stablep = 2; /* FILE_SYNC */
  702         }
  703 
  704         if (!EX_ISSYNC(exp))
  705                 stable = 0;
  706         if (stable && !EX_WGATHER(exp))
  707                 file.f_flags |= O_SYNC;
  708 
  709         file.f_pos = offset;            /* set write offset */
  710 
  711         /* Write the data. */
  712         oldfs = get_fs(); set_fs(KERNEL_DS);
  713         err = file.f_op->write(&file, buf, cnt, &file.f_pos);
  714         if (err >= 0)
  715                 nfsdstats.io_write += cnt;
  716         set_fs(oldfs);
  717 
  718         /* clear setuid/setgid flag after write */
  719         if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) {
  720                 struct iattr    ia;
  721 
  722                 ia.ia_valid = ATTR_MODE;
  723                 ia.ia_mode  = inode->i_mode & ~(S_ISUID | S_ISGID);
  724                 notify_change(dentry, &ia);
  725         }
  726 
  727         if (err >= 0 && stable) {
  728                 static unsigned long    last_ino;
  729                 static kdev_t           last_dev = NODEV;
  730 
  731                 /*
  732                  * Gathered writes: If another process is currently
  733                  * writing to the file, there's a high chance
  734                  * this is another nfsd (triggered by a bulk write
  735                  * from a client's biod). Rather than syncing the
  736                  * file with each write request, we sleep for 10 msec.
  737                  *
  738                  * I don't know if this roughly approximates
  739                  * C. Juszak's idea of gathered writes, but it's a
  740                  * nice and simple solution (IMHO), and it seems to
  741                  * work:-)
  742                  */
  743                 if (EX_WGATHER(exp)) {
  744                         if (atomic_read(&inode->i_writecount) > 1
  745                             || (last_ino == inode->i_ino && last_dev == inode->i_dev)) {
  746                                 dprintk("nfsd: write defer %d\n", current->pid);
  747                                 set_current_state(TASK_UNINTERRUPTIBLE);
  748                                 schedule_timeout((HZ+99)/100);
  749                                 current->state = TASK_RUNNING;
  750                                 dprintk("nfsd: write resume %d\n", current->pid);
  751                         }
  752 
  753                         if (inode->i_state & I_DIRTY) {
  754                                 dprintk("nfsd: write sync %d\n", current->pid);
  755                                 nfsd_sync(&file);
  756                         }
  757 #if 0
  758                         wake_up(&inode->i_wait);
  759 #endif
  760                 }
  761                 last_ino = inode->i_ino;
  762                 last_dev = inode->i_dev;
  763         }
  764 
  765         dprintk("nfsd: write complete err=%d\n", err);
  766         if (err >= 0)
  767                 err = 0;
  768         else 
  769                 err = nfserrno(err);
  770 out_close:
  771         nfsd_close(&file);
  772 out:
  773         return err;
  774 }
  775 
  776 
  777 #ifdef CONFIG_NFSD_V3
  778 /*
  779  * Commit all pending writes to stable storage.
  780  * Strictly speaking, we could sync just the indicated file region here,
  781  * but there's currently no way we can ask the VFS to do so.
  782  *
  783  * Unfortunately we cannot lock the file to make sure we return full WCC
  784  * data to the client, as locking happens lower down in the filesystem.
  785  */
  786 int
  787 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
  788                off_t offset, unsigned long count)
  789 {
  790         struct file     file;
  791         int             err;
  792 
  793         if ((err = nfsd_open(rqstp, fhp, S_IFREG, MAY_WRITE, &file)) != 0)
  794                 return err;
  795         if (EX_ISSYNC(fhp->fh_export)) {
  796                 if (file.f_op && file.f_op->fsync) {
  797                         nfsd_sync(&file);
  798                 } else {
  799                         err = nfserr_notsupp;
  800                 }
  801         }
  802 
  803         nfsd_close(&file);
  804         return err;
  805 }
  806 #endif /* CONFIG_NFSD_V3 */
  807 
  808 /*
  809  * Create a file (regular, directory, device, fifo); UNIX sockets 
  810  * not yet implemented.
  811  * If the response fh has been verified, the parent directory should
  812  * already be locked. Note that the parent directory is left locked.
  813  *
  814  * N.B. Every call to nfsd_create needs an fh_put for _both_ fhp and resfhp
  815  */
  816 int
  817 nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
  818                 char *fname, int flen, struct iattr *iap,
  819                 int type, dev_t rdev, struct svc_fh *resfhp)
  820 {
  821         struct dentry   *dentry, *dchild;
  822         struct inode    *dirp;
  823         int             err;
  824 
  825         err = nfserr_perm;
  826         if (!flen)
  827                 goto out;
  828         err = nfserr_exist;
  829         if (isdotent(fname, flen))
  830                 goto out;
  831 
  832         err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
  833         if (err)
  834                 goto out;
  835 
  836         dentry = fhp->fh_dentry;
  837         dirp = dentry->d_inode;
  838 
  839         err = nfserr_notdir;
  840         if(!dirp->i_op || !dirp->i_op->lookup)
  841                 goto out;
  842         /*
  843          * Check whether the response file handle has been verified yet.
  844          * If it has, the parent directory should already be locked.
  845          */
  846         if (!resfhp->fh_dentry) {
  847                 /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */
  848                 fh_lock(fhp);
  849                 dchild = lookup_one_len(fname, dentry, flen);
  850                 err = PTR_ERR(dchild);
  851                 if (IS_ERR(dchild))
  852                         goto out_nfserr;
  853                 err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
  854                 if (err)
  855                         goto out;
  856         } else {
  857                 /* called from nfsd_proc_create */
  858                 dchild = resfhp->fh_dentry;
  859                 if (!fhp->fh_locked) {
  860                         /* not actually possible */
  861                         printk(KERN_ERR
  862                                 "nfsd_create: parent %s/%s not locked!\n",
  863                                 dentry->d_parent->d_name.name,
  864                                 dentry->d_name.name);
  865                         err = -EIO;
  866                         goto out;
  867                 }
  868         }
  869         /*
  870          * Make sure the child dentry is still negative ...
  871          */
  872         err = nfserr_exist;
  873         if (dchild->d_inode) {
  874                 dprintk("nfsd_create: dentry %s/%s not negative!\n",
  875                         dentry->d_name.name, dchild->d_name.name);
  876                 goto out; 
  877         }
  878 
  879         if (!(iap->ia_valid & ATTR_MODE))
  880                 iap->ia_mode = 0;
  881         iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;
  882 
  883         /*
  884          * Get the dir op function pointer.
  885          */
  886         err = nfserr_perm;
  887         switch (type) {
  888         case S_IFREG:
  889                 err = vfs_create(dirp, dchild, iap->ia_mode);
  890                 break;
  891         case S_IFDIR:
  892                 err = vfs_mkdir(dirp, dchild, iap->ia_mode);
  893                 break;
  894         case S_IFCHR:
  895         case S_IFBLK:
  896         case S_IFIFO:
  897         case S_IFSOCK:
  898                 err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
  899                 break;
  900         default:
  901                 printk("nfsd: bad file type %o in nfsd_create\n", type);
  902                 err = -EINVAL;
  903         }
  904         if (err < 0)
  905                 goto out_nfserr;
  906 
  907         if (EX_ISSYNC(fhp->fh_export)) {
  908                 nfsd_sync_dir(dentry);
  909                 write_inode_now(dchild->d_inode, 1);
  910         }
  911 
  912 
  913         /* Set file attributes. Mode has already been set and
  914          * setting uid/gid works only for root. Irix appears to
  915          * send along the gid when it tries to implement setgid
  916          * directories via NFS.
  917          */
  918         err = 0;
  919         if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0)
  920                 err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
  921         /*
  922          * Update the file handle to get the new inode info.
  923          */
  924         if (!err)
  925                 err = fh_update(resfhp);
  926 out:
  927         return err;
  928 
  929 out_nfserr:
  930         err = nfserrno(err);
  931         goto out;
  932 }
  933 
  934 #ifdef CONFIG_NFSD_V3
  935 /*
  936  * NFSv3 version of nfsd_create
  937  */
  938 int
  939 nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
  940                 char *fname, int flen, struct iattr *iap,
  941                 struct svc_fh *resfhp, int createmode, u32 *verifier)
  942 {
  943         struct dentry   *dentry, *dchild;
  944         struct inode    *dirp;
  945         int             err;
  946         __u32           v_mtime=0, v_atime=0;
  947         int             v_mode=0;
  948 
  949         err = nfserr_perm;
  950         if (!flen)
  951                 goto out;
  952         err = nfserr_exist;
  953         if (isdotent(fname, flen))
  954                 goto out;
  955         if (!(iap->ia_valid & ATTR_MODE))
  956                 iap->ia_mode = 0;
  957         err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
  958         if (err)
  959                 goto out;
  960 
  961         dentry = fhp->fh_dentry;
  962         dirp = dentry->d_inode;
  963 
  964         /* Get all the sanity checks out of the way before
  965          * we lock the parent. */
  966         err = nfserr_notdir;
  967         if(!dirp->i_op || !dirp->i_op->lookup)
  968                 goto out;
  969         fh_lock(fhp);
  970 
  971         /*
  972          * Compose the response file handle.
  973          */
  974         dchild = lookup_one_len(fname, dentry, flen);
  975         err = PTR_ERR(dchild);
  976         if (IS_ERR(dchild))
  977                 goto out_nfserr;
  978 
  979         err = fh_compose(resfhp, fhp->fh_export, dchild, fhp);
  980         if (err)
  981                 goto out;
  982 
  983         if (createmode == NFS3_CREATE_EXCLUSIVE) {
  984                 /* while the verifier would fit in mtime+atime,
  985                  * solaris7 gets confused (bugid 4218508) if these have
  986                  * the high bit set, so we use the mode as well
  987                  */
  988                 v_mtime = verifier[0]&0x7fffffff;
  989                 v_atime = verifier[1]&0x7fffffff;
  990                 v_mode  = S_IFREG
  991                         | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
  992                         | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
  993                         ;
  994         }
  995         
  996         if (dchild->d_inode) {
  997                 err = 0;
  998 
  999                 switch (createmode) {
 1000                 case NFS3_CREATE_UNCHECKED:
 1001                         if (! S_ISREG(dchild->d_inode->i_mode))
 1002                                 err = nfserr_exist;
 1003                         else {
 1004                                 iap->ia_valid &= ATTR_SIZE;
 1005                                 goto set_attr;
 1006                         }
 1007                         break;
 1008                 case NFS3_CREATE_EXCLUSIVE:
 1009                         if (   dchild->d_inode->i_mtime == v_mtime
 1010                             && dchild->d_inode->i_atime == v_atime
 1011                             && dchild->d_inode->i_mode  == v_mode
 1012                             && dchild->d_inode->i_size  == 0 )
 1013                                 break;
 1014                          /* fallthru */
 1015                 case NFS3_CREATE_GUARDED:
 1016                         err = nfserr_exist;
 1017                 }
 1018                 goto out;
 1019         }
 1020 
 1021         err = vfs_create(dirp, dchild, iap->ia_mode);
 1022         if (err < 0)
 1023                 goto out_nfserr;
 1024 
 1025         if (EX_ISSYNC(fhp->fh_export)) {
 1026                 nfsd_sync_dir(dentry);
 1027                 /* setattr will sync the child (or not) */
 1028         }
 1029 
 1030         /*
 1031          * Update the filehandle to get the new inode info.
 1032          */
 1033         err = fh_update(resfhp);
 1034         if (err)
 1035                 goto out;
 1036 
 1037         if (createmode == NFS3_CREATE_EXCLUSIVE) {
 1038                 /* Cram the verifier into atime/mtime/mode */
 1039                 iap->ia_valid = ATTR_MTIME|ATTR_ATIME
 1040                         | ATTR_MTIME_SET|ATTR_ATIME_SET
 1041                         | ATTR_MODE;
 1042                 iap->ia_mtime = v_mtime;
 1043                 iap->ia_atime = v_atime;
 1044                 iap->ia_mode  = v_mode;
 1045         }
 1046 
 1047         /* Set file attributes.
 1048          * Mode has already been set but we might need to reset it
 1049          * for CREATE_EXCLUSIVE
 1050          * Irix appears to send along the gid when it tries to
 1051          * implement setgid directories via NFS. Clear out all that cruft.
 1052          */
 1053  set_attr:
 1054         if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0)
 1055                 err = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
 1056 
 1057  out:
 1058         fh_unlock(fhp);
 1059         return err;
 1060  
 1061  out_nfserr:
 1062         err = nfserrno(err);
 1063         goto out;
 1064 }
 1065 #endif /* CONFIG_NFSD_V3 */
 1066 
 1067 /*
 1068  * Read a symlink. On entry, *lenp must contain the maximum path length that
 1069  * fits into the buffer. On return, it contains the true length.
 1070  * N.B. After this call fhp needs an fh_put
 1071  */
 1072 int
 1073 nfsd_readlink(struct svc_rqst *rqstp, struct svc_fh *fhp, char *buf, int *lenp)
 1074 {
 1075         struct dentry   *dentry;
 1076         struct inode    *inode;
 1077         mm_segment_t    oldfs;
 1078         int             err;
 1079 
 1080         err = fh_verify(rqstp, fhp, S_IFLNK, MAY_NOP);
 1081         if (err)
 1082                 goto out;
 1083 
 1084         dentry = fhp->fh_dentry;
 1085         inode = dentry->d_inode;
 1086 
 1087         err = nfserr_inval;
 1088         if (!inode->i_op || !inode->i_op->readlink)
 1089                 goto out;
 1090 
 1091         UPDATE_ATIME(inode);
 1092         /* N.B. Why does this call need a get_fs()??
 1093          * Remove the set_fs and watch the fireworks:-) --okir
 1094          */
 1095 
 1096         oldfs = get_fs(); set_fs(KERNEL_DS);
 1097         err = inode->i_op->readlink(dentry, buf, *lenp);
 1098         set_fs(oldfs);
 1099 
 1100         if (err < 0)
 1101                 goto out_nfserr;
 1102         *lenp = err;
 1103         err = 0;
 1104 out:
 1105         return err;
 1106 
 1107 out_nfserr:
 1108         err = nfserrno(err);
 1109         goto out;
 1110 }
 1111 
 1112 /*
 1113  * Create a symlink and look up its inode
 1114  * N.B. After this call _both_ fhp and resfhp need an fh_put
 1115  */
 1116 int
 1117 nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
 1118                                 char *fname, int flen,
 1119                                 char *path,  int plen,
 1120                                 struct svc_fh *resfhp,
 1121                                 struct iattr *iap)
 1122 {
 1123         struct dentry   *dentry, *dnew;
 1124         int             err, cerr;
 1125 
 1126         err = nfserr_noent;
 1127         if (!flen || !plen)
 1128                 goto out;
 1129         err = nfserr_exist;
 1130         if (isdotent(fname, flen))
 1131                 goto out;
 1132 
 1133         err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
 1134         if (err)
 1135                 goto out;
 1136         fh_lock(fhp);
 1137         dentry = fhp->fh_dentry;
 1138         dnew = lookup_one_len(fname, dentry, flen);
 1139         err = PTR_ERR(dnew);
 1140         if (IS_ERR(dnew))
 1141                 goto out_nfserr;
 1142 
 1143         err = vfs_symlink(dentry->d_inode, dnew, path);
 1144         if (!err) {
 1145                 if (EX_ISSYNC(fhp->fh_export))
 1146                         nfsd_sync_dir(dentry);
 1147                 if (iap) {
 1148                         iap->ia_valid &= ATTR_MODE /* ~(ATTR_MODE|ATTR_UID|ATTR_GID)*/;
 1149                         if (iap->ia_valid) {
 1150                                 iap->ia_valid |= ATTR_CTIME;
 1151                                 iap->ia_mode = (iap->ia_mode&S_IALLUGO)
 1152                                         | S_IFLNK;
 1153                                 err = notify_change(dnew, iap);
 1154                                 if (err)
 1155                                         err = nfserrno(err);
 1156                                 else if (EX_ISSYNC(fhp->fh_export))
 1157                                         write_inode_now(dentry->d_inode, 1);
 1158                        }
 1159                 }
 1160         } else
 1161                 err = nfserrno(err);
 1162         fh_unlock(fhp);
 1163 
 1164         /* Compose the fh so the dentry will be freed ... */
 1165         cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp);
 1166         if (err==0) err = cerr;
 1167 out:
 1168         return err;
 1169 
 1170 out_nfserr:
 1171         err = nfserrno(err);
 1172         goto out;
 1173 }
 1174 
 1175 /*
 1176  * Create a hardlink
 1177  * N.B. After this call _both_ ffhp and tfhp need an fh_put
 1178  */
 1179 int
 1180 nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
 1181                                 char *name, int len, struct svc_fh *tfhp)
 1182 {
 1183         struct dentry   *ddir, *dnew, *dold;
 1184         struct inode    *dirp, *dest;
 1185         int             err;
 1186 
 1187         err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_CREATE);
 1188         if (err)
 1189                 goto out;
 1190         err = fh_verify(rqstp, tfhp, -S_IFDIR, MAY_NOP);
 1191         if (err)
 1192                 goto out;
 1193 
 1194         err = nfserr_perm;
 1195         if (!len)
 1196                 goto out;
 1197         err = nfserr_exist;
 1198         if (isdotent(name, len))
 1199                 goto out;
 1200 
 1201         fh_lock(ffhp);
 1202         ddir = ffhp->fh_dentry;
 1203         dirp = ddir->d_inode;
 1204 
 1205         dnew = lookup_one_len(name, ddir, len);
 1206         err = PTR_ERR(dnew);
 1207         if (IS_ERR(dnew))
 1208                 goto out_nfserr;
 1209 
 1210         dold = tfhp->fh_dentry;
 1211         dest = dold->d_inode;
 1212 
 1213         err = vfs_link(dold, dirp, dnew);
 1214         if (!err) {
 1215                 if (EX_ISSYNC(ffhp->fh_export)) {
 1216                         nfsd_sync_dir(ddir);
 1217                         write_inode_now(dest, 1);
 1218                 }
 1219         } else {
 1220                 if (err == -EXDEV && rqstp->rq_vers == 2)
 1221                         err = nfserr_acces;
 1222                 else
 1223                         err = nfserrno(err);
 1224         }
 1225 
 1226         fh_unlock(ffhp);
 1227         dput(dnew);
 1228 out:
 1229         return err;
 1230 
 1231 out_nfserr:
 1232         err = nfserrno(err);
 1233         goto out;
 1234 }
 1235 
 1236 /*
 1237  * Rename a file
 1238  * N.B. After this call _both_ ffhp and tfhp need an fh_put
 1239  */
 1240 int
 1241 nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
 1242                             struct svc_fh *tfhp, char *tname, int tlen)
 1243 {
 1244         struct dentry   *fdentry, *tdentry, *odentry, *ndentry;
 1245         struct inode    *fdir, *tdir;
 1246         int             err;
 1247 
 1248         err = fh_verify(rqstp, ffhp, S_IFDIR, MAY_REMOVE);
 1249         if (err)
 1250                 goto out;
 1251         err = fh_verify(rqstp, tfhp, S_IFDIR, MAY_CREATE);
 1252         if (err)
 1253                 goto out;
 1254 
 1255         fdentry = ffhp->fh_dentry;
 1256         fdir = fdentry->d_inode;
 1257 
 1258         tdentry = tfhp->fh_dentry;
 1259         tdir = tdentry->d_inode;
 1260 
 1261         err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
 1262         if (fdir->i_dev != tdir->i_dev)
 1263                 goto out;
 1264 
 1265         err = nfserr_perm;
 1266         if (!flen || isdotent(fname, flen) || !tlen || isdotent(tname, tlen))
 1267                 goto out;
 1268 
 1269         /* cannot use fh_lock as we need deadlock protective ordering
 1270          * so do it by hand */
 1271         double_down(&tdir->i_sem, &fdir->i_sem);
 1272         ffhp->fh_locked = tfhp->fh_locked = 1;
 1273         fill_pre_wcc(ffhp);
 1274         fill_pre_wcc(tfhp);
 1275 
 1276         odentry = lookup_one_len(fname, fdentry, flen);
 1277         err = PTR_ERR(odentry);
 1278         if (IS_ERR(odentry))
 1279                 goto out_nfserr;
 1280 
 1281         err = -ENOENT;
 1282         if (!odentry->d_inode)
 1283                 goto out_dput_old;
 1284 
 1285         ndentry = lookup_one_len(tname, tdentry, tlen);
 1286         err = PTR_ERR(ndentry);
 1287         if (IS_ERR(ndentry))
 1288                 goto out_dput_old;
 1289 
 1290 
 1291 #ifdef MSNFS
 1292         if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 1293                 ((atomic_read(&odentry->d_count) > 1)
 1294                  || (atomic_read(&ndentry->d_count) > 1))) {
 1295                         err = nfserr_perm;
 1296         } else
 1297 #endif
 1298         err = vfs_rename(fdir, odentry, tdir, ndentry);
 1299         if (!err && EX_ISSYNC(tfhp->fh_export)) {
 1300                 nfsd_sync_dir(tdentry);
 1301                 nfsd_sync_dir(fdentry);
 1302         }
 1303         dput(ndentry);
 1304 
 1305  out_dput_old:
 1306         dput(odentry);
 1307  out_nfserr:
 1308         if (err)
 1309                 err = nfserrno(err);
 1310 
 1311         /* we cannot reply on fh_unlock on the two filehandles,
 1312          * as that would do the wrong thing if the two directories
 1313          * were the same, so again we do it by hand
 1314          */
 1315         fill_post_wcc(ffhp);
 1316         fill_post_wcc(tfhp);
 1317         double_up(&tdir->i_sem, &fdir->i_sem);
 1318         ffhp->fh_locked = tfhp->fh_locked = 0;
 1319         
 1320 out:
 1321         return err;
 1322 }
 1323 
 1324 /*
 1325  * Unlink a file or directory
 1326  * N.B. After this call fhp needs an fh_put
 1327  */
 1328 int
 1329 nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 1330                                 char *fname, int flen)
 1331 {
 1332         struct dentry   *dentry, *rdentry;
 1333         struct inode    *dirp;
 1334         int             err;
 1335 
 1336         err = nfserr_acces;
 1337         if (!flen || isdotent(fname, flen))
 1338                 goto out;
 1339         err = fh_verify(rqstp, fhp, S_IFDIR, MAY_REMOVE);
 1340         if (err)
 1341                 goto out;
 1342 
 1343         fh_lock(fhp);
 1344         dentry = fhp->fh_dentry;
 1345         dirp = dentry->d_inode;
 1346 
 1347         rdentry = lookup_one_len(fname, dentry, flen);
 1348         err = PTR_ERR(rdentry);
 1349         if (IS_ERR(rdentry))
 1350                 goto out_nfserr;
 1351 
 1352         if (!rdentry->d_inode) {
 1353                 dput(rdentry);
 1354                 err = nfserr_noent;
 1355                 goto out;
 1356         }
 1357 
 1358         if (type != S_IFDIR) { /* It's UNLINK */
 1359 #ifdef MSNFS
 1360                 if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 1361                         (atomic_read(&rdentry->d_count) > 1)) {
 1362                         err = nfserr_perm;
 1363                 } else
 1364 #endif
 1365                 err = vfs_unlink(dirp, rdentry);
 1366         } else { /* It's RMDIR */
 1367                 err = vfs_rmdir(dirp, rdentry);
 1368         }
 1369 
 1370         dput(rdentry);
 1371 
 1372         if (err)
 1373                 goto out_nfserr;
 1374         if (EX_ISSYNC(fhp->fh_export)) 
 1375                 nfsd_sync_dir(dentry);
 1376 
 1377 out:
 1378         return err;
 1379 
 1380 out_nfserr:
 1381         err = nfserrno(err);
 1382         goto out;
 1383 }
 1384 
 1385 /*
 1386  * Read entries from a directory.
 1387  * The verifier is an NFSv3 thing we ignore for now.
 1388  */
 1389 int
 1390 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, 
 1391              encode_dent_fn func, u32 *buffer, int *countp, u32 *verf)
 1392 {
 1393         u32             *p;
 1394         int             oldlen, eof, err;
 1395         struct file     file;
 1396         struct readdir_cd cd;
 1397 
 1398         err = nfsd_open(rqstp, fhp, S_IFDIR, MAY_READ, &file);
 1399         if (err)
 1400                 goto out;
 1401         if (offset > ~(u32) 0)
 1402                 goto out_close;
 1403 
 1404         file.f_pos = offset;
 1405 
 1406         /* Set up the readdir context */
 1407         memset(&cd, 0, sizeof(cd));
 1408         cd.rqstp  = rqstp;
 1409         cd.buffer = buffer;
 1410         cd.buflen = *countp; /* count of words */
 1411         cd.dirfh  = fhp;
 1412 
 1413         /*
 1414          * Read the directory entries. This silly loop is necessary because
 1415          * readdir() is not guaranteed to fill up the entire buffer, but
 1416          * may choose to do less.
 1417          */
 1418 
 1419         do {
 1420                 oldlen = cd.buflen;
 1421 
 1422                 err = vfs_readdir(&file, (filldir_t) func, &cd);
 1423 
 1424                 if (err < 0)
 1425                         goto out_nfserr;
 1426 
 1427         } while (oldlen != cd.buflen && !cd.eob);
 1428 
 1429         /* If we didn't fill the buffer completely, we're at EOF */
 1430         eof = !cd.eob;
 1431 
 1432         if (cd.offset) {
 1433                 if (rqstp->rq_vers == 3)
 1434                         (void)xdr_encode_hyper(cd.offset, file.f_pos);
 1435                 else
 1436                         *cd.offset = htonl(file.f_pos);
 1437         }
 1438 
 1439         p = cd.buffer;
 1440         *p++ = 0;                       /* no more entries */
 1441         *p++ = htonl(eof);              /* end of directory */
 1442         *countp = (caddr_t) p - (caddr_t) buffer;
 1443 
 1444         dprintk("nfsd: readdir result %d bytes, eof %d offset %d\n",
 1445                                 *countp, eof,
 1446                                 cd.offset? ntohl(*cd.offset) : -1);
 1447         err = 0;
 1448 out_close:
 1449         nfsd_close(&file);
 1450 out:
 1451         return err;
 1452 
 1453 out_nfserr:
 1454         err = nfserrno(err);
 1455         goto out_close;
 1456 }
 1457 
 1458 /*
 1459  * Get file system stats
 1460  * N.B. After this call fhp needs an fh_put
 1461  */
 1462 int
 1463 nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct statfs *stat)
 1464 {
 1465         int err = fh_verify(rqstp, fhp, 0, MAY_NOP);
 1466         if (!err && vfs_statfs(fhp->fh_dentry->d_inode->i_sb,stat))
 1467                 err = nfserr_io;
 1468         return err;
 1469 }
 1470 
 1471 /*
 1472  * Check for a user's access permissions to this inode.
 1473  */
 1474 int
 1475 nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc)
 1476 {
 1477         struct inode    *inode = dentry->d_inode;
 1478         int             err;
 1479 
 1480         if (acc == MAY_NOP)
 1481                 return 0;
 1482 #if 0
 1483         dprintk("nfsd: permission 0x%x%s%s%s%s%s%s%s mode 0%o%s%s%s\n",
 1484                 acc,
 1485                 (acc & MAY_READ)?       " read"  : "",
 1486                 (acc & MAY_WRITE)?      " write" : "",
 1487                 (acc & MAY_EXEC)?       " exec"  : "",
 1488                 (acc & MAY_SATTR)?      " sattr" : "",
 1489                 (acc & MAY_TRUNC)?      " trunc" : "",
 1490                 (acc & MAY_LOCK)?       " lock"  : "",
 1491                 (acc & MAY_OWNER_OVERRIDE)? " owneroverride" : "",
 1492                 inode->i_mode,
 1493                 IS_IMMUTABLE(inode)?    " immut" : "",
 1494                 IS_APPEND(inode)?       " append" : "",
 1495                 IS_RDONLY(inode)?       " ro" : "");
 1496         dprintk("      owner %d/%d user %d/%d\n",
 1497                 inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
 1498 #endif
 1499 
 1500         /* The following code is here to make IRIX happy, which
 1501          * does a permission check every time a user does
 1502          *      echo yaddayadda > special-file
 1503          * by sending a CREATE request.
 1504          * The original code would check read-only export status
 1505          * only for regular files and directories, allowing
 1506          * clients to chown/chmod device files and fifos even
 1507          * on volumes exported read-only. */
 1508         if (!(acc & _NFSD_IRIX_BOGOSITY)
 1509          && (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC))) {
 1510                 if (EX_RDONLY(exp) || IS_RDONLY(inode))
 1511                         return nfserr_rofs;
 1512                 if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
 1513                         return nfserr_perm;
 1514         }
 1515         if ((acc & MAY_TRUNC) && IS_APPEND(inode))
 1516                 return nfserr_perm;
 1517 
 1518         if (acc & MAY_LOCK) {
 1519                 /* If we cannot rely on authentication in NLM requests,
 1520                  * just allow locks, otherwise require read permission, or
 1521                  * ownership
 1522                  */
 1523                 if (exp->ex_flags & NFSEXP_NOAUTHNLM)
 1524                         return 0;
 1525                 else
 1526                         acc = MAY_READ | MAY_OWNER_OVERRIDE;
 1527         }
 1528         /*
 1529          * The file owner always gets access permission for accesses that
 1530          * would normally be checked at open time. This is to make
 1531          * file access work even when the client has done a fchmod(fd, 0).
 1532          *
 1533          * However, `cp foo bar' should fail nevertheless when bar is
 1534          * readonly. A sensible way to do this might be to reject all
 1535          * attempts to truncate a read-only file, because a creat() call
 1536          * always implies file truncation.
 1537          * ... but this isn't really fair.  A process may reasonably call
 1538          * ftruncate on an open file descriptor on a file with perm 000.
 1539          * We must trust the client to do permission checking - using "ACCESS"
 1540          * with NFSv3.
 1541          */
 1542         if ((acc & MAY_OWNER_OVERRIDE) &&
 1543             inode->i_uid == current->fsuid)
 1544                 return 0;
 1545 
 1546         err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC));
 1547 
 1548         /* Allow read access to binaries even when mode 111 */
 1549         if (err == -EACCES && S_ISREG(inode->i_mode) &&
 1550             acc == (MAY_READ | MAY_OWNER_OVERRIDE))
 1551                 err = permission(inode, MAY_EXEC);
 1552 
 1553         return err? nfserrno(err) : 0;
 1554 }
 1555 
 1556 void
 1557 nfsd_racache_shutdown(void)
 1558 {
 1559         if (!raparm_cache)
 1560                 return;
 1561         dprintk("nfsd: freeing readahead buffers.\n");
 1562         kfree(raparml);
 1563         raparm_cache = raparml = NULL;
 1564 }
 1565 /*
 1566  * Initialize readahead param cache
 1567  */
 1568 int
 1569 nfsd_racache_init(int cache_size)
 1570 {
 1571         int     i;
 1572 
 1573         if (raparm_cache)
 1574                 return 0;
 1575         raparml = kmalloc(sizeof(struct raparms) * cache_size, GFP_KERNEL);
 1576 
 1577         if (raparml != NULL) {
 1578                 dprintk("nfsd: allocating %d readahead buffers.\n",
 1579                         cache_size);
 1580                 memset(raparml, 0, sizeof(struct raparms) * cache_size);
 1581                 for (i = 0; i < cache_size - 1; i++) {
 1582                         raparml[i].p_next = raparml + i + 1;
 1583                 }
 1584                 raparm_cache = raparml;
 1585         } else {
 1586                 printk(KERN_WARNING
 1587                        "nfsd: Could not allocate memory read-ahead cache.\n");
 1588                 return -ENOMEM;
 1589         }
 1590         nfsdstats.ra_size = cache_size;
 1591         return 0;
 1592 }

Cache object: 25934574cac5c76f79d075bc8a9af860


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