aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-09 11:38:14 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-09 11:38:14 -0400
commit8b80fc02b829a59602b0f53eb9393ffb2db2659d (patch)
tree9cce02e07ed1b30d6f6bd236a2d6015e5681eeb9 /fs/nfs/delegation.c
parent6a0ed91e361a93ee1efb4c20c4967024ed2a8dd7 (diff)
parent4011cd97886dd04b90fef8b671b9936cd39ab983 (diff)
Merge git://git.linux-nfs.org/pub/linux/nfs-2.6
* git://git.linux-nfs.org/pub/linux/nfs-2.6: SUNRPC: Replace flush_workqueue() with cancel_work_sync() and friends NFS: Replace flush_scheduled_work with cancel_work_sync() and friends SUNRPC: Don't call gss_delete_sec_context() from an rcu context NFSv4: Don't call put_rpccred() from an rcu callback NFS: Fix NFSv4 open stateid regressions NFSv4: Fix a locking regression in nfs4_set_mode_locked() NFS: Fix put_nfs_open_context SUNRPC: Fix a race in rpciod_down()
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c21
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
23static void nfs_free_delegation(struct nfs_delegation *delegation) 23static 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
35static 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
37static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) 46static 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();