]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/nfsd/vfs.c
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
[linux-2.6-omap-h63xx.git] / fs / nfsd / vfs.c
index e90f4a8a1d011f11898834ae7984ef2a3cb9b92e..cec78c82b1f9ab11354498fa931f66cd2325a153 100644 (file)
@@ -115,19 +115,20 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
 
        exp2 = rqst_exp_get_by_name(rqstp, mnt, mounts);
        if (IS_ERR(exp2)) {
-               err = PTR_ERR(exp2);
+               if (PTR_ERR(exp2) != -ENOENT)
+                       err = PTR_ERR(exp2);
                dput(mounts);
                mntput(mnt);
                goto out;
        }
-       if (exp2 && ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2))) {
+       if ((exp->ex_flags & NFSEXP_CROSSMOUNT) || EX_NOHIDE(exp2)) {
                /* successfully crossed mount point */
                exp_put(exp);
                *expp = exp2;
                dput(dentry);
                *dpp = mounts;
        } else {
-               if (exp2) exp_put(exp2);
+               exp_put(exp2);
                dput(mounts);
        }
        mntput(mnt);
@@ -294,7 +295,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
        if (!iap->ia_valid)
                goto out;
 
-       /* NFSv2 does not differentiate between "set-[ac]time-to-now"
+       /*
+        * NFSv2 does not differentiate between "set-[ac]time-to-now"
         * which only requires access, and "set-[ac]time-to-X" which
         * requires ownership.
         * So if it looks like it might be "set both to the same time which
@@ -307,25 +309,33 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
         */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
 #define        MAX_TOUCH_TIME_ERROR (30*60)
-       if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
-           && iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec
-           ) {
-           /* Looks probable.  Now just make sure time is in the right ballpark.
-            * Solaris, at least, doesn't seem to care what the time request is.
-            * We require it be within 30 minutes of now.
-            */
-           time_t delta = iap->ia_atime.tv_sec - get_seconds();
-           if (delta<0) delta = -delta;
-           if (delta < MAX_TOUCH_TIME_ERROR &&
-               inode_change_ok(inode, iap) != 0) {
-               /* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
-                * this will cause notify_change to set these times to "now"
+       if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET &&
+           iap->ia_mtime.tv_sec == iap->ia_atime.tv_sec) {
+               /*
+                * Looks probable.
+                *
+                * Now just make sure time is in the right ballpark.
+                * Solaris, at least, doesn't seem to care what the time
+                * request is.  We require it be within 30 minutes of now.
                 */
-               iap->ia_valid &= ~BOTH_TIME_SET;
-           }
+               time_t delta = iap->ia_atime.tv_sec - get_seconds();
+               if (delta < 0)
+                       delta = -delta;
+               if (delta < MAX_TOUCH_TIME_ERROR &&
+                   inode_change_ok(inode, iap) != 0) {
+                       /*
+                        * Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
+                        * This will cause notify_change to set these times
+                        * to "now"
+                        */
+                       iap->ia_valid &= ~BOTH_TIME_SET;
+               }
        }
            
-       /* The size case is special. It changes the file as well as the attributes.  */
+       /*
+        * The size case is special.
+        * It changes the file as well as the attributes.
+        */
        if (iap->ia_valid & ATTR_SIZE) {
                if (iap->ia_size < inode->i_size) {
                        err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE);
@@ -1309,7 +1319,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
 
        if (createmode == NFS3_CREATE_EXCLUSIVE) {
                /* solaris7 gets confused (bugid 4218508) if these have
-                * the high bit set, so just clear the high bits.
+                * the high bit set, so just clear the high bits. If this is
+                * ever changed to use different attrs for storing the
+                * verifier, then do_open_lookup() will also need to be fixed
+                * accordingly.
                 */
                v_mtime = verifier[0]&0x7fffffff;
                v_atime = verifier[1]&0x7fffffff;
@@ -1797,6 +1810,11 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
        return err;
 }
 
+static int exp_rdonly(struct svc_rqst *rqstp, struct svc_export *exp)
+{
+       return nfsexp_flags(rqstp, exp) & NFSEXP_READONLY;
+}
+
 /*
  * Check for a user's access permissions to this inode.
  */
@@ -1833,7 +1851,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
         */
        if (!(acc & MAY_LOCAL_ACCESS))
                if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) {
-                       if (EX_RDONLY(exp, rqstp) || IS_RDONLY(inode))
+                       if (exp_rdonly(rqstp, exp) || IS_RDONLY(inode))
                                return nfserr_rofs;
                        if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode))
                                return nfserr_perm;
@@ -1916,7 +1934,7 @@ nfsd_racache_init(int cache_size)
                raparm_hash[i].pb_head = NULL;
                spin_lock_init(&raparm_hash[i].pb_lock);
        }
-       nperbucket = cache_size >> RAPARM_HASH_BITS;
+       nperbucket = DIV_ROUND_UP(cache_size, RAPARM_HASH_SIZE);
        for (i = 0; i < cache_size - 1; i++) {
                if (i % nperbucket == 0)
                        raparm_hash[j++].pb_head = raparml + i;