OSDN Git Service

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 c764cfe..2a03bfe 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)