2 * linux/fs/nfs/delegation.c
4 * Copyright (C) 2004 Trond Myklebust
6 * NFS file delegation management
9 #include <linux/completion.h>
10 #include <linux/kthread.h>
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/slab.h>
14 #include <linux/smp_lock.h>
15 #include <linux/spinlock.h>
17 #include <linux/nfs4.h>
18 #include <linux/nfs_fs.h>
19 #include <linux/nfs_xdr.h>
22 #include "delegation.h"
25 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
30 static void nfs_free_delegation_callback(struct rcu_head *head)
32 struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
34 nfs_do_free_delegation(delegation);
37 static void nfs_free_delegation(struct nfs_delegation *delegation)
39 if (delegation->cred) {
40 put_rpccred(delegation->cred);
41 delegation->cred = NULL;
43 call_rcu(&delegation->rcu, nfs_free_delegation_callback);
46 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
48 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
51 int nfs_have_delegation(struct inode *inode, fmode_t flags)
53 struct nfs_delegation *delegation;
56 flags &= FMODE_READ|FMODE_WRITE;
58 delegation = rcu_dereference(NFS_I(inode)->delegation);
59 if (delegation != NULL && (delegation->type & flags) == flags) {
60 nfs_mark_delegation_referenced(delegation);
67 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
69 struct inode *inode = state->inode;
73 if (inode->i_flock == NULL)
76 /* Protect inode->i_flock using the BKL */
78 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
79 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
81 if (nfs_file_open_context(fl->fl_file) != ctx)
84 status = nfs4_lock_delegation_recall(state, fl);
94 static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
96 struct nfs_inode *nfsi = NFS_I(inode);
97 struct nfs_open_context *ctx;
98 struct nfs4_state *state;
102 spin_lock(&inode->i_lock);
103 list_for_each_entry(ctx, &nfsi->open_files, list) {
107 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
109 if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
111 get_nfs_open_context(ctx);
112 spin_unlock(&inode->i_lock);
113 err = nfs4_open_delegation_recall(ctx, state, stateid);
115 err = nfs_delegation_claim_locks(ctx, state);
116 put_nfs_open_context(ctx);
121 spin_unlock(&inode->i_lock);
126 * Set up a delegation on an inode
128 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
130 struct nfs_delegation *delegation;
131 struct rpc_cred *oldcred = NULL;
134 delegation = rcu_dereference(NFS_I(inode)->delegation);
135 if (delegation != NULL) {
136 spin_lock(&delegation->lock);
137 if (delegation->inode != NULL) {
138 memcpy(delegation->stateid.data, res->delegation.data,
139 sizeof(delegation->stateid.data));
140 delegation->type = res->delegation_type;
141 delegation->maxsize = res->maxsize;
142 oldcred = delegation->cred;
143 delegation->cred = get_rpccred(cred);
144 clear_bit(NFS_DELEGATION_NEED_RECLAIM,
146 NFS_I(inode)->delegation_state = delegation->type;
147 spin_unlock(&delegation->lock);
148 put_rpccred(oldcred);
151 /* We appear to have raced with a delegation return. */
152 spin_unlock(&delegation->lock);
154 nfs_inode_set_delegation(inode, cred, res);
161 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
165 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
166 nfs_free_delegation(delegation);
170 static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
172 struct inode *inode = NULL;
174 spin_lock(&delegation->lock);
175 if (delegation->inode != NULL)
176 inode = igrab(delegation->inode);
177 spin_unlock(&delegation->lock);
181 static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi,
182 const nfs4_stateid *stateid,
183 struct nfs_client *clp)
185 struct nfs_delegation *delegation =
186 rcu_dereference_protected(nfsi->delegation,
187 lockdep_is_held(&clp->cl_lock));
189 if (delegation == NULL)
191 spin_lock(&delegation->lock);
192 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
193 sizeof(delegation->stateid.data)) != 0)
195 list_del_rcu(&delegation->super_list);
196 delegation->inode = NULL;
197 nfsi->delegation_state = 0;
198 rcu_assign_pointer(nfsi->delegation, NULL);
199 spin_unlock(&delegation->lock);
202 spin_unlock(&delegation->lock);
208 * Set up a delegation on an inode
210 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
212 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
213 struct nfs_inode *nfsi = NFS_I(inode);
214 struct nfs_delegation *delegation, *old_delegation;
215 struct nfs_delegation *freeme = NULL;
218 delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
219 if (delegation == NULL)
221 memcpy(delegation->stateid.data, res->delegation.data,
222 sizeof(delegation->stateid.data));
223 delegation->type = res->delegation_type;
224 delegation->maxsize = res->maxsize;
225 delegation->change_attr = nfsi->change_attr;
226 delegation->cred = get_rpccred(cred);
227 delegation->inode = inode;
228 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
229 spin_lock_init(&delegation->lock);
231 spin_lock(&clp->cl_lock);
232 old_delegation = rcu_dereference_protected(nfsi->delegation,
233 lockdep_is_held(&clp->cl_lock));
234 if (old_delegation != NULL) {
235 if (memcmp(&delegation->stateid, &old_delegation->stateid,
236 sizeof(old_delegation->stateid)) == 0 &&
237 delegation->type == old_delegation->type) {
241 * Deal with broken servers that hand out two
242 * delegations for the same file.
244 dfprintk(FILE, "%s: server %s handed out "
245 "a duplicate delegation!\n",
246 __func__, clp->cl_hostname);
247 if (delegation->type <= old_delegation->type) {
252 freeme = nfs_detach_delegation_locked(nfsi, NULL, clp);
254 list_add_rcu(&delegation->super_list, &clp->cl_delegations);
255 nfsi->delegation_state = delegation->type;
256 rcu_assign_pointer(nfsi->delegation, delegation);
259 /* Ensure we revalidate the attributes and page cache! */
260 spin_lock(&inode->i_lock);
261 nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
262 spin_unlock(&inode->i_lock);
265 spin_unlock(&clp->cl_lock);
266 if (delegation != NULL)
267 nfs_free_delegation(delegation);
269 nfs_do_return_delegation(inode, freeme, 0);
274 * Basic procedure for returning a delegation to the server
276 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
278 struct nfs_inode *nfsi = NFS_I(inode);
282 * Guard against new delegated open/lock/unlock calls and against
285 down_write(&nfsi->rwsem);
286 err = nfs_delegation_claim_opens(inode, &delegation->stateid);
287 up_write(&nfsi->rwsem);
291 err = nfs_do_return_delegation(inode, delegation, issync);
297 * Return all delegations that have been marked for return
299 int nfs_client_return_marked_delegations(struct nfs_client *clp)
301 struct nfs_delegation *delegation;
307 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
308 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
310 inode = nfs_delegation_grab_inode(delegation);
313 spin_lock(&clp->cl_lock);
314 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
315 spin_unlock(&clp->cl_lock);
317 if (delegation != NULL) {
318 filemap_flush(inode->i_mapping);
319 err = __nfs_inode_return_delegation(inode, delegation, 0);
324 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
332 * This function returns the delegation without reclaiming opens
333 * or protecting against delegation reclaims.
334 * It is therefore really only safe to be called from
337 void nfs_inode_return_delegation_noreclaim(struct inode *inode)
339 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
340 struct nfs_inode *nfsi = NFS_I(inode);
341 struct nfs_delegation *delegation;
343 if (rcu_access_pointer(nfsi->delegation) != NULL) {
344 spin_lock(&clp->cl_lock);
345 delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
346 spin_unlock(&clp->cl_lock);
347 if (delegation != NULL)
348 nfs_do_return_delegation(inode, delegation, 0);
352 int nfs_inode_return_delegation(struct inode *inode)
354 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
355 struct nfs_inode *nfsi = NFS_I(inode);
356 struct nfs_delegation *delegation;
359 if (rcu_access_pointer(nfsi->delegation) != NULL) {
360 spin_lock(&clp->cl_lock);
361 delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
362 spin_unlock(&clp->cl_lock);
363 if (delegation != NULL) {
365 err = __nfs_inode_return_delegation(inode, delegation, 1);
371 static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation)
373 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
374 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
378 * Return all delegations associated to a super block
380 void nfs_super_return_all_delegations(struct super_block *sb)
382 struct nfs_client *clp = NFS_SB(sb)->nfs_client;
383 struct nfs_delegation *delegation;
388 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
389 spin_lock(&delegation->lock);
390 if (delegation->inode != NULL && delegation->inode->i_sb == sb)
391 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
392 spin_unlock(&delegation->lock);
395 if (nfs_client_return_marked_delegations(clp) != 0)
396 nfs4_schedule_state_manager(clp);
400 void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
402 struct nfs_delegation *delegation;
405 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
406 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
408 if (delegation->type & flags)
409 nfs_mark_return_delegation(clp, delegation);
414 static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
416 nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
419 static void nfs_delegation_run_state_manager(struct nfs_client *clp)
421 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
422 nfs4_schedule_state_manager(clp);
425 void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
427 nfs_client_mark_return_all_delegation_types(clp, flags);
428 nfs_delegation_run_state_manager(clp);
431 void nfs_expire_all_delegations(struct nfs_client *clp)
433 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
437 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
439 void nfs_handle_cb_pathdown(struct nfs_client *clp)
443 nfs_client_mark_return_all_delegations(clp);
446 static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp)
448 struct nfs_delegation *delegation;
451 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
452 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
454 nfs_mark_return_delegation(clp, delegation);
459 void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
461 nfs_client_mark_return_unreferenced_delegations(clp);
462 nfs_delegation_run_state_manager(clp);
466 * Asynchronous delegation recall!
468 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid)
470 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
471 struct nfs_delegation *delegation;
474 delegation = rcu_dereference(NFS_I(inode)->delegation);
476 if (!clp->cl_mvops->validate_stateid(delegation, stateid)) {
481 nfs_mark_return_delegation(clp, delegation);
483 nfs_delegation_run_state_manager(clp);
488 * Retrieve the inode associated with a delegation
490 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle)
492 struct nfs_delegation *delegation;
493 struct inode *res = NULL;
495 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
496 spin_lock(&delegation->lock);
497 if (delegation->inode != NULL &&
498 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
499 res = igrab(delegation->inode);
501 spin_unlock(&delegation->lock);
510 * Mark all delegations as needing to be reclaimed
512 void nfs_delegation_mark_reclaim(struct nfs_client *clp)
514 struct nfs_delegation *delegation;
516 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
517 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
522 * Reap all unclaimed delegations after reboot recovery is done
524 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
526 struct nfs_delegation *delegation;
530 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
531 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0)
533 inode = nfs_delegation_grab_inode(delegation);
536 spin_lock(&clp->cl_lock);
537 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
538 spin_unlock(&clp->cl_lock);
540 if (delegation != NULL)
541 nfs_free_delegation(delegation);
548 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
550 struct nfs_inode *nfsi = NFS_I(inode);
551 struct nfs_delegation *delegation;
555 delegation = rcu_dereference(nfsi->delegation);
556 if (delegation != NULL) {
557 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));