diff options
| -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(); |
