NFS: Don't refresh attributes with mounted-on-file information
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Fri, 9 Aug 2019 16:06:43 +0000 (12:06 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 19 Aug 2019 12:56:04 +0000 (08:56 -0400)
If we've been given the attributes of the mounted-on-file, then do not
use those to check or update the attributes on the application-visible
inode.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/inode.c

index 8a1758200b579198d24b562905a24765006f87ca..c764cfe456e5078636af71b38a8169785a563ded 100644 (file)
@@ -1403,12 +1403,21 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
                return 0;
 
+       /* No fileid? Just exit */
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID))
+               return 0;
        /* Has the inode gone and changed behind our back? */
-       if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
+       if (nfsi->fileid != fattr->fileid) {
+               /* Is this perhaps the mounted-on fileid? */
+               if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) &&
+                   nfsi->fileid == fattr->mounted_on_fileid)
+                       return 0;
                return -ESTALE;
+       }
        if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
                return -ESTALE;
 
+
        if (!nfs_file_has_buffered_writers(nfsi)) {
                /* Verify a few of the more important attributes */
                if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr))
@@ -1768,18 +1777,6 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
 EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
 
 
-static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
-                                   struct nfs_fattr *fattr)
-{
-       bool ret1 = true, ret2 = true;
-
-       if (fattr->valid & NFS_ATTR_FATTR_FILEID)
-               ret1 = (nfsi->fileid == fattr->fileid);
-       if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
-               ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
-       return ret1 || ret2;
-}
-
 /*
  * Many nfs protocol calls return the new file attributes after
  * an operation.  Here we update the inode to reflect the state
@@ -1810,7 +1807,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        nfs_display_fhandle_hash(NFS_FH(inode)),
                        atomic_read(&inode->i_count), fattr->valid);
 
-       if (!nfs_fileid_valid(nfsi, fattr)) {
+       /* No fileid? Just exit */
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID))
+               return 0;
+       /* Has the inode gone and changed behind our back? */
+       if (nfsi->fileid != fattr->fileid) {
+               /* Is this perhaps the mounted-on fileid? */
+               if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) &&
+                   nfsi->fileid == fattr->mounted_on_fileid)
+                       return 0;
                printk(KERN_ERR "NFS: server %s error: fileid changed\n"
                        "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
                        NFS_SERVER(inode)->nfs_client->cl_hostname,