diff options
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 20ac403469a0..c55a761c22bb 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -20,10 +20,8 @@ | |||
20 | #include "delegation.h" | 20 | #include "delegation.h" |
21 | #include "internal.h" | 21 | #include "internal.h" |
22 | 22 | ||
23 | static void nfs_free_delegation(struct nfs_delegation *delegation) | 23 | static void nfs_do_free_delegation(struct nfs_delegation *delegation) |
24 | { | 24 | { |
25 | if (delegation->cred) | ||
26 | put_rpccred(delegation->cred); | ||
27 | kfree(delegation); | 25 | kfree(delegation); |
28 | } | 26 | } |
29 | 27 | ||
@@ -31,7 +29,18 @@ static void nfs_free_delegation_callback(struct rcu_head *head) | |||
31 | { | 29 | { |
32 | struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu); | 30 | struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu); |
33 | 31 | ||
34 | nfs_free_delegation(delegation); | 32 | nfs_do_free_delegation(delegation); |
33 | } | ||
34 | |||
35 | static void nfs_free_delegation(struct nfs_delegation *delegation) | ||
36 | { | ||
37 | struct rpc_cred *cred; | ||
38 | |||
39 | cred = rcu_dereference(delegation->cred); | ||
40 | rcu_assign_pointer(delegation->cred, NULL); | ||
41 | call_rcu(&delegation->rcu, nfs_free_delegation_callback); | ||
42 | if (cred) | ||
43 | put_rpccred(cred); | ||
35 | } | 44 | } |
36 | 45 | ||
37 | static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) | 46 | static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) |
@@ -166,7 +175,7 @@ static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation * | |||
166 | int res = 0; | 175 | int res = 0; |
167 | 176 | ||
168 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); | 177 | res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid); |
169 | call_rcu(&delegation->rcu, nfs_free_delegation_callback); | 178 | nfs_free_delegation(delegation); |
170 | return res; | 179 | return res; |
171 | } | 180 | } |
172 | 181 | ||
@@ -448,7 +457,7 @@ restart: | |||
448 | spin_unlock(&clp->cl_lock); | 457 | spin_unlock(&clp->cl_lock); |
449 | rcu_read_unlock(); | 458 | rcu_read_unlock(); |
450 | if (delegation != NULL) | 459 | if (delegation != NULL) |
451 | call_rcu(&delegation->rcu, nfs_free_delegation_callback); | 460 | nfs_free_delegation(delegation); |
452 | goto restart; | 461 | goto restart; |
453 | } | 462 | } |
454 | rcu_read_unlock(); | 463 | rcu_read_unlock(); |