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/spinlock.h>
16 #include <linux/nfs4.h>
17 #include <linux/nfs_fs.h>
18 #include <linux/nfs_xdr.h>
21 #include "delegation.h"
24 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
27 put_rpccred(delegation->cred);
31 static void nfs_free_delegation_callback(struct rcu_head *head)
33 struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
35 nfs_do_free_delegation(delegation);
38 static void nfs_free_delegation(struct nfs_delegation *delegation)
40 call_rcu(&delegation->rcu, nfs_free_delegation_callback);
43 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
45 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
48 int nfs_have_delegation(struct inode *inode, fmode_t flags)
50 struct nfs_delegation *delegation;
53 flags &= FMODE_READ|FMODE_WRITE;
55 delegation = rcu_dereference(NFS_I(inode)->delegation);
56 if (delegation != NULL && (delegation->type & flags) == flags) {
57 nfs_mark_delegation_referenced(delegation);
64 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
66 struct inode *inode = state->inode;
70 if (inode->i_flock == NULL)
73 /* Protect inode->i_flock using the file locks lock */
75 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
76 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
78 if (nfs_file_open_context(fl->fl_file) != ctx)
81 status = nfs4_lock_delegation_recall(state, fl);
91 static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
93 struct nfs_inode *nfsi = NFS_I(inode);
94 struct nfs_open_context *ctx;
95 struct nfs4_state *state;
99 spin_lock(&inode->i_lock);
100 list_for_each_entry(ctx, &nfsi->open_files, list) {
104 if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
106 if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
108 get_nfs_open_context(ctx);
109 spin_unlock(&inode->i_lock);
110 err = nfs4_open_delegation_recall(ctx, state, stateid);
112 err = nfs_delegation_claim_locks(ctx, state);
113 put_nfs_open_context(ctx);
118 spin_unlock(&inode->i_lock);
123 * Set up a delegation on an inode
125 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
127 struct nfs_delegation *delegation;
128 struct rpc_cred *oldcred = NULL;
131 delegation = rcu_dereference(NFS_I(inode)->delegation);
132 if (delegation != NULL) {
133 spin_lock(&delegation->lock);
134 if (delegation->inode != NULL) {
135 memcpy(delegation->stateid.data, res->delegation.data,
136 sizeof(delegation->stateid.data));
137 delegation->type = res->delegation_type;
138 delegation->maxsize = res->maxsize;
139 oldcred = delegation->cred;
140 delegation->cred = get_rpccred(cred);
141 clear_bit(NFS_DELEGATION_NEED_RECLAIM,
143 NFS_I(inode)->delegation_state = delegation->type;
144 spin_unlock(&delegation->lock);
145 put_rpccred(oldcred);
148 /* We appear to have raced with a delegation return. */
149 spin_unlock(&delegation->lock);
151 nfs_inode_set_delegation(inode, cred, res);
158 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
162 res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
163 nfs_free_delegation(delegation);
167 static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
169 struct inode *inode = NULL;
171 spin_lock(&delegation->lock);
172 if (delegation->inode != NULL)
173 inode = igrab(delegation->inode);
174 spin_unlock(&delegation->lock);
178 static struct nfs_delegation *
179 nfs_detach_delegation_locked(struct nfs_inode *nfsi,
180 struct nfs_client *clp)
182 struct nfs_delegation *delegation =
183 rcu_dereference_protected(nfsi->delegation,
184 lockdep_is_held(&clp->cl_lock));
186 if (delegation == NULL)
189 spin_lock(&delegation->lock);
190 list_del_rcu(&delegation->super_list);
191 delegation->inode = NULL;
192 nfsi->delegation_state = 0;
193 rcu_assign_pointer(nfsi->delegation, NULL);
194 spin_unlock(&delegation->lock);
200 static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
201 struct nfs_client *clp)
203 struct nfs_delegation *delegation;
205 spin_lock(&clp->cl_lock);
206 delegation = nfs_detach_delegation_locked(nfsi, clp);
207 spin_unlock(&clp->cl_lock);
212 * Set up a delegation on an inode
214 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
216 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
217 struct nfs_inode *nfsi = NFS_I(inode);
218 struct nfs_delegation *delegation, *old_delegation;
219 struct nfs_delegation *freeme = NULL;
222 delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
223 if (delegation == NULL)
225 memcpy(delegation->stateid.data, res->delegation.data,
226 sizeof(delegation->stateid.data));
227 delegation->type = res->delegation_type;
228 delegation->maxsize = res->maxsize;
229 delegation->change_attr = nfsi->change_attr;
230 delegation->cred = get_rpccred(cred);
231 delegation->inode = inode;
232 delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
233 spin_lock_init(&delegation->lock);
235 spin_lock(&clp->cl_lock);
236 old_delegation = rcu_dereference_protected(nfsi->delegation,
237 lockdep_is_held(&clp->cl_lock));
238 if (old_delegation != NULL) {
239 if (memcmp(&delegation->stateid, &old_delegation->stateid,
240 sizeof(old_delegation->stateid)) == 0 &&
241 delegation->type == old_delegation->type) {
245 * Deal with broken servers that hand out two
246 * delegations for the same file.
248 dfprintk(FILE, "%s: server %s handed out "
249 "a duplicate delegation!\n",
250 __func__, clp->cl_hostname);
251 if (delegation->type <= old_delegation->type) {
256 freeme = nfs_detach_delegation_locked(nfsi, clp);
258 list_add_rcu(&delegation->super_list, &clp->cl_delegations);
259 nfsi->delegation_state = delegation->type;
260 rcu_assign_pointer(nfsi->delegation, delegation);
263 /* Ensure we revalidate the attributes and page cache! */
264 spin_lock(&inode->i_lock);
265 nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
266 spin_unlock(&inode->i_lock);
269 spin_unlock(&clp->cl_lock);
270 if (delegation != NULL)
271 nfs_free_delegation(delegation);
273 nfs_do_return_delegation(inode, freeme, 0);
278 * Basic procedure for returning a delegation to the server
280 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
282 struct nfs_inode *nfsi = NFS_I(inode);
286 * Guard against new delegated open/lock/unlock calls and against
289 down_write(&nfsi->rwsem);
290 err = nfs_delegation_claim_opens(inode, &delegation->stateid);
291 up_write(&nfsi->rwsem);
295 err = nfs_do_return_delegation(inode, delegation, issync);
301 * Return all delegations that have been marked for return
303 int nfs_client_return_marked_delegations(struct nfs_client *clp)
305 struct nfs_delegation *delegation;
311 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
312 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
314 inode = nfs_delegation_grab_inode(delegation);
317 delegation = nfs_detach_delegation(NFS_I(inode), clp);
319 if (delegation != NULL) {
320 filemap_flush(inode->i_mapping);
321 err = __nfs_inode_return_delegation(inode, delegation, 0);
326 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
334 * This function returns the delegation without reclaiming opens
335 * or protecting against delegation reclaims.
336 * It is therefore really only safe to be called from
339 void nfs_inode_return_delegation_noreclaim(struct inode *inode)
341 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
342 struct nfs_inode *nfsi = NFS_I(inode);
343 struct nfs_delegation *delegation;
345 if (rcu_access_pointer(nfsi->delegation) != NULL) {
346 delegation = nfs_detach_delegation(nfsi, clp);
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 delegation = nfs_detach_delegation(nfsi, clp);
361 if (delegation != NULL) {
363 err = __nfs_inode_return_delegation(inode, delegation, 1);
369 static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation)
371 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
372 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
376 * Return all delegations associated to a super block
378 void nfs_super_return_all_delegations(struct super_block *sb)
380 struct nfs_client *clp = NFS_SB(sb)->nfs_client;
381 struct nfs_delegation *delegation;
386 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
387 spin_lock(&delegation->lock);
388 if (delegation->inode != NULL && delegation->inode->i_sb == sb)
389 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
390 spin_unlock(&delegation->lock);
393 if (nfs_client_return_marked_delegations(clp) != 0)
394 nfs4_schedule_state_manager(clp);
398 void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
400 struct nfs_delegation *delegation;
403 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
404 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
406 if (delegation->type & flags)
407 nfs_mark_return_delegation(clp, delegation);
412 static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
414 nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
417 static void nfs_delegation_run_state_manager(struct nfs_client *clp)
419 if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
420 nfs4_schedule_state_manager(clp);
423 void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
425 nfs_client_mark_return_all_delegation_types(clp, flags);
426 nfs_delegation_run_state_manager(clp);
429 void nfs_expire_all_delegations(struct nfs_client *clp)
431 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
435 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
437 void nfs_handle_cb_pathdown(struct nfs_client *clp)
441 nfs_client_mark_return_all_delegations(clp);
444 static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp)
446 struct nfs_delegation *delegation;
449 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
450 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
452 nfs_mark_return_delegation(clp, delegation);
457 void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
459 nfs_client_mark_return_unreferenced_delegations(clp);
460 nfs_delegation_run_state_manager(clp);
464 * Asynchronous delegation recall!
466 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid)
468 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
469 struct nfs_delegation *delegation;
472 delegation = rcu_dereference(NFS_I(inode)->delegation);
474 if (!clp->cl_mvops->validate_stateid(delegation, stateid)) {
479 nfs_mark_return_delegation(clp, delegation);
481 nfs_delegation_run_state_manager(clp);
486 * Retrieve the inode associated with a delegation
488 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle)
490 struct nfs_delegation *delegation;
491 struct inode *res = NULL;
493 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
494 spin_lock(&delegation->lock);
495 if (delegation->inode != NULL &&
496 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
497 res = igrab(delegation->inode);
499 spin_unlock(&delegation->lock);
508 * Mark all delegations as needing to be reclaimed
510 void nfs_delegation_mark_reclaim(struct nfs_client *clp)
512 struct nfs_delegation *delegation;
514 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
515 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
520 * Reap all unclaimed delegations after reboot recovery is done
522 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
524 struct nfs_delegation *delegation;
528 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
529 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0)
531 inode = nfs_delegation_grab_inode(delegation);
534 delegation = nfs_detach_delegation(NFS_I(inode), clp);
536 if (delegation != NULL)
537 nfs_free_delegation(delegation);
544 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
546 struct nfs_inode *nfsi = NFS_I(inode);
547 struct nfs_delegation *delegation;
551 delegation = rcu_dereference(nfsi->delegation);
552 if (delegation != NULL) {
553 memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));