2019-10-31 23:15:57

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH v2 02/20] NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid()

A typo in nfs4_refresh_delegation_stateid() means we're leaking an
RCU lock, and always returning a value of 'false'. As the function
description states, we were always supposed to return 'true' if a
matching delegation was found.

Fixes: 12f275cdd163 ("NFSv4: Retry CLOSE and DELEGRETURN on NFS4ERR_OLD_STATEID.")
Cc: [email protected] # v4.15+
Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/delegation.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index ccdfb5f98f35..af549d70ec50 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -1191,7 +1191,7 @@ bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
if (delegation != NULL &&
nfs4_stateid_match_other(dst, &delegation->stateid)) {
dst->seqid = delegation->stateid.seqid;
- return ret;
+ ret = true;
}
rcu_read_unlock();
out:
--
2.23.0


2019-10-31 23:15:57

by Trond Myklebust

[permalink] [raw]
Subject: [PATCH v2 03/20] NFSv4: Fix delegation handling in update_open_stateid()

If the delegation is marked as being revoked, then don't use it in
the open state structure.

Signed-off-by: Trond Myklebust <[email protected]>
---
fs/nfs/nfs4proc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index caacf5e7f5e1..217885e32852 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1737,7 +1737,7 @@ static int update_open_stateid(struct nfs4_state *state,
ret = 1;
}

- deleg_cur = rcu_dereference(nfsi->delegation);
+ deleg_cur = nfs4_get_valid_delegation(state->inode);
if (deleg_cur == NULL)
goto no_delegation;

@@ -1749,7 +1749,7 @@ static int update_open_stateid(struct nfs4_state *state,

if (delegation == NULL)
delegation = &deleg_cur->stateid;
- else if (!nfs4_stateid_match(&deleg_cur->stateid, delegation))
+ else if (!nfs4_stateid_match_other(&deleg_cur->stateid, delegation))
goto no_delegation_unlock;

nfs_mark_delegation_referenced(deleg_cur);
--
2.23.0