From: Trond Myklebust Date: Mon, 27 Jan 2020 17:44:41 +0000 (-0500) Subject: NFSv4: nfs_update_inplace_delegation() should update delegation cred X-Git-Tag: v5.15~4063^2~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=57f188e047731e50cb6af94d473c3c70d3bce7f9;p=platform%2Fkernel%2Flinux-starfive.git NFSv4: nfs_update_inplace_delegation() should update delegation cred If the cred assigned to the delegation that we're updating differs from the one we're updating too, then we need to update that field too. Signed-off-by: Trond Myklebust --- diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 1865322de142..509b7235b132 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -377,6 +377,18 @@ nfs_inode_detach_delegation(struct inode *inode) return delegation; } +static void +nfs_update_delegation_cred(struct nfs_delegation *delegation, + const struct cred *cred) +{ + const struct cred *old; + + if (cred_fscmp(delegation->cred, cred) != 0) { + old = xchg(&delegation->cred, get_cred(cred)); + put_cred(old); + } +} + static void nfs_update_inplace_delegation(struct nfs_delegation *delegation, const struct nfs_delegation *update) @@ -385,8 +397,14 @@ nfs_update_inplace_delegation(struct nfs_delegation *delegation, delegation->stateid.seqid = update->stateid.seqid; smp_wmb(); delegation->type = update->type; - if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) + delegation->pagemod_limit = update->pagemod_limit; + if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) { + delegation->change_attr = update->change_attr; + nfs_update_delegation_cred(delegation, update->cred); + /* smp_mb__before_atomic() is implicit due to xchg() */ + clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags); atomic_long_inc(&nfs_active_delegations); + } } }