NFS: Ensure we revalidate the inode correctly after remove or rename
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 8 Apr 2018 22:11:18 +0000 (18:11 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Thu, 31 May 2018 19:02:16 +0000 (15:02 -0400)
We may need to revalidate the change attribute, ctime and the nlinks count.

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

index b315f53b3aec6b5d4efd70170dee88035101adca..978a22ea962cf79c225c8fae55b991995984c7c1 100644 (file)
@@ -1284,11 +1284,13 @@ static void nfs_drop_nlink(struct inode *inode)
 {
        spin_lock(&inode->i_lock);
        /* drop the inode if we're reasonably sure this is the last link */
-       if (inode->i_nlink == 1)
-               clear_nlink(inode);
+       if (inode->i_nlink > 0)
+               drop_nlink(inode);
+       NFS_I(inode)->attr_gencount = nfs_inc_attr_generation_counter();
        NFS_I(inode)->cache_validity |= NFS_INO_INVALID_CHANGE
                | NFS_INO_INVALID_CTIME
-               | NFS_INO_INVALID_OTHER;
+               | NFS_INO_INVALID_OTHER
+               | NFS_INO_REVAL_FORCED;
        spin_unlock(&inode->i_lock);
 }
 
@@ -2050,7 +2052,15 @@ int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        } else
                error = task->tk_status;
        rpc_put_task(task);
-       nfs_mark_for_revalidate(old_inode);
+       /* Ensure the inode attributes are revalidated */
+       if (error == 0) {
+               spin_lock(&old_inode->i_lock);
+               NFS_I(old_inode)->attr_gencount = nfs_inc_attr_generation_counter();
+               NFS_I(old_inode)->cache_validity |= NFS_INO_INVALID_CHANGE
+                       | NFS_INO_INVALID_CTIME
+                       | NFS_INO_REVAL_FORCED;
+               spin_unlock(&old_inode->i_lock);
+       }
 out:
        if (rehash)
                d_rehash(rehash);