aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 00c350c031b4..e75f2f8c5245 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -43,6 +43,27 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
43 put_rpccred(cred); 43 put_rpccred(cred);
44} 44}
45 45
46void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
47{
48 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
49}
50
51int nfs_have_delegation(struct inode *inode, int flags)
52{
53 struct nfs_delegation *delegation;
54 int ret = 0;
55
56 flags &= FMODE_READ|FMODE_WRITE;
57 rcu_read_lock();
58 delegation = rcu_dereference(NFS_I(inode)->delegation);
59 if (delegation != NULL && (delegation->type & flags) == flags) {
60 nfs_mark_delegation_referenced(delegation);
61 ret = 1;
62 }
63 rcu_read_unlock();
64 return ret;
65}
66
46static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state) 67static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
47{ 68{
48 struct inode *inode = state->inode; 69 struct inode *inode = state->inode;
@@ -188,6 +209,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
188 delegation->change_attr = nfsi->change_attr; 209 delegation->change_attr = nfsi->change_attr;
189 delegation->cred = get_rpccred(cred); 210 delegation->cred = get_rpccred(cred);
190 delegation->inode = inode; 211 delegation->inode = inode;
212 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
191 spin_lock_init(&delegation->lock); 213 spin_lock_init(&delegation->lock);
192 214
193 spin_lock(&clp->cl_lock); 215 spin_lock(&clp->cl_lock);
@@ -382,6 +404,26 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
382 nfs_client_mark_return_all_delegations(clp); 404 nfs_client_mark_return_all_delegations(clp);
383} 405}
384 406
407static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp)
408{
409 struct nfs_delegation *delegation;
410
411 rcu_read_lock();
412 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
413 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
414 continue;
415 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
416 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
417 }
418 rcu_read_unlock();
419}
420
421void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
422{
423 nfs_client_mark_return_unreferenced_delegations(clp);
424 nfs_delegation_run_state_manager(clp);
425}
426
385/* 427/*
386 * Asynchronous delegation recall! 428 * Asynchronous delegation recall!
387 */ 429 */