]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
NFSD: Refactor nfsd_setattr()
authorChuck Lever <chuck.lever@oracle.com>
Thu, 8 Sep 2022 22:14:07 +0000 (18:14 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 26 Sep 2022 18:02:32 +0000 (14:02 -0400)
Move code that will be retried (in a subsequent patch) into a helper
function.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
fs/nfsd/vfs.c

index 712fbfe30f53961ebfd6ece77ee26da948e75a60..7c17b4a93168fc92a9a70a81c1d52ef85c9412ce 100644 (file)
@@ -343,8 +343,61 @@ nfsd_get_write_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
        return nfserrno(get_write_access(inode));
 }
 
-/*
- * Set various file attributes.  After this call fhp needs an fh_put.
+static int __nfsd_setattr(struct dentry *dentry, struct iattr *iap)
+{
+       int host_err;
+
+       if (iap->ia_valid & ATTR_SIZE) {
+               /*
+                * RFC5661, Section 18.30.4:
+                *   Changing the size of a file with SETATTR indirectly
+                *   changes the time_modify and change attributes.
+                *
+                * (and similar for the older RFCs)
+                */
+               struct iattr size_attr = {
+                       .ia_valid       = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
+                       .ia_size        = iap->ia_size,
+               };
+
+               if (iap->ia_size < 0)
+                       return -EFBIG;
+
+               host_err = notify_change(&init_user_ns, dentry, &size_attr, NULL);
+               if (host_err)
+                       return host_err;
+               iap->ia_valid &= ~ATTR_SIZE;
+
+               /*
+                * Avoid the additional setattr call below if the only other
+                * attribute that the client sends is the mtime, as we update
+                * it as part of the size change above.
+                */
+               if ((iap->ia_valid & ~ATTR_MTIME) == 0)
+                       return 0;
+       }
+
+       if (!iap->ia_valid)
+               return 0;
+
+       iap->ia_valid |= ATTR_CTIME;
+       return notify_change(&init_user_ns, dentry, iap, NULL);
+}
+
+/**
+ * nfsd_setattr - Set various file attributes.
+ * @rqstp: controlling RPC transaction
+ * @fhp: filehandle of target
+ * @attr: attributes to set
+ * @check_guard: set to 1 if guardtime is a valid timestamp
+ * @guardtime: do not act if ctime.tv_sec does not match this timestamp
+ *
+ * This call may adjust the contents of @attr (in particular, this
+ * call may change the bits in the na_iattr.ia_valid field).
+ *
+ * Returns nfs_ok on success, otherwise an NFS status code is
+ * returned. Caller must release @fhp by calling fh_put in either
+ * case.
  */
 __be32
 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
@@ -357,7 +410,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
        int             accmode = NFSD_MAY_SATTR;
        umode_t         ftype = 0;
        __be32          err;
-       int             host_err = 0;
+       int             host_err;
        bool            get_write_count;
        bool            size_change = (iap->ia_valid & ATTR_SIZE);
 
@@ -414,43 +467,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
        }
 
        inode_lock(inode);
-       if (size_change) {
-               /*
-                * RFC5661, Section 18.30.4:
-                *   Changing the size of a file with SETATTR indirectly
-                *   changes the time_modify and change attributes.
-                *
-                * (and similar for the older RFCs)
-                */
-               struct iattr size_attr = {
-                       .ia_valid       = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME,
-                       .ia_size        = iap->ia_size,
-               };
-
-               host_err = -EFBIG;
-               if (iap->ia_size < 0)
-                       goto out_unlock;
-
-               host_err = notify_change(&init_user_ns, dentry, &size_attr, NULL);
-               if (host_err)
-                       goto out_unlock;
-               iap->ia_valid &= ~ATTR_SIZE;
-
-               /*
-                * Avoid the additional setattr call below if the only other
-                * attribute that the client sends is the mtime, as we update
-                * it as part of the size change above.
-                */
-               if ((iap->ia_valid & ~ATTR_MTIME) == 0)
-                       goto out_unlock;
-       }
-
-       if (iap->ia_valid) {
-               iap->ia_valid |= ATTR_CTIME;
-               host_err = notify_change(&init_user_ns, dentry, iap, NULL);
-       }
-
-out_unlock:
+       host_err = __nfsd_setattr(dentry, iap);
        if (attr->na_seclabel && attr->na_seclabel->len)
                attr->na_labelerr = security_inode_setsecctx(dentry,
                        attr->na_seclabel->data, attr->na_seclabel->len);