aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2020-02-05 09:01:54 -0500
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2020-02-12 13:55:25 -0500
commitefeda80da38d0b4afd77a12bd4a44f657567d26c (patch)
tree359ce5ab560de88855195f83e3d0844d9bc1932b /fs/nfs/delegation.c
parentNFSv4: Fix races between open and dentry revalidation (diff)
downloadlinux-dev-efeda80da38d0b4afd77a12bd4a44f657567d26c.tar.xz
linux-dev-efeda80da38d0b4afd77a12bd4a44f657567d26c.zip
NFSv4: Fix revalidation of dentries with delegations
If a dentry was not initially looked up while we were holding a delegation, then we do still need to revalidate that it still holds the same name. If there are multiple hard links to the same file, then all the hard links need validation. Reported-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Benjamin Coddington <bcodding@redhat.com> Tested-by: Benjamin Coddington <bcodding@redhat.com> [Anna: Put nfs_unset_verifier_delegated() under CONFIG_NFS_V4] Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 4a841071d8a7..d856326836a2 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -42,6 +42,8 @@ static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation)
if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
atomic_long_dec(&nfs_active_delegations);
+ if (!test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
+ nfs_clear_verifier_delegated(delegation->inode);
}
}
@@ -276,6 +278,8 @@ nfs_start_delegation_return_locked(struct nfs_inode *nfsi)
if (!test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
ret = delegation;
spin_unlock(&delegation->lock);
+ if (ret)
+ nfs_clear_verifier_delegated(&nfsi->vfs_inode);
out:
return ret;
}
@@ -689,6 +693,8 @@ void nfs4_inode_return_delegation_on_close(struct inode *inode)
ret = delegation;
}
spin_unlock(&delegation->lock);
+ if (ret)
+ nfs_clear_verifier_delegated(inode);
}
out:
rcu_read_unlock();