NFS: Fix inode fileid checks in attribute revalidation code
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 28 Aug 2019 15:26:13 +0000 (11:26 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 2 Sep 2019 17:10:19 +0000 (13:10 -0400)
We want to throw out the attrbute if it refers to the mounted on fileid,
and not the real fileid. However we do not want to block cache consistency
updates from NFSv4 writes.

Reported-by: Murphy Zhou <jencce.kernel@gmail.com>
Fixes: 7e10cc25bfa0 ("NFS: Don't refresh attributes with mounted-on-file...")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/inode.c

index c764cfe456e5078636af71b38a8169785a563ded..2a03bfeec10a409a577eb2d773648c032d692d6e 100644 (file)
@@ -1403,11 +1403,12 @@ 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;
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) {
+               /* Only a mounted-on-fileid? Just exit */
+               if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
+                       return 0;
        /* Has the inode gone and changed behind our back? */
-       if (nfsi->fileid != fattr->fileid) {
+       } else 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)
@@ -1807,11 +1808,12 @@ 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);
 
-       /* No fileid? Just exit */
-       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID))
-               return 0;
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) {
+               /* Only a mounted-on-fileid? Just exit */
+               if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
+                       return 0;
        /* Has the inode gone and changed behind our back? */
-       if (nfsi->fileid != fattr->fileid) {
+       } else 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)