xref: /linux/fs/nfs/delegation.c (revision 5d4a2e29fba5b2bef95b96a46b338ec4d76fa4fd)
1 /*
2  * linux/fs/nfs/delegation.c
3  *
4  * Copyright (C) 2004 Trond Myklebust
5  *
6  * NFS file delegation management
7  *
8  */
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>
16 
17 #include <linux/nfs4.h>
18 #include <linux/nfs_fs.h>
19 #include <linux/nfs_xdr.h>
20 
21 #include "nfs4_fs.h"
22 #include "delegation.h"
23 #include "internal.h"
24 
25 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
26 {
27 	if (delegation->cred)
28 		put_rpccred(delegation->cred);
29 	kfree(delegation);
30 }
31 
32 static void nfs_free_delegation_callback(struct rcu_head *head)
33 {
34 	struct nfs_delegation *delegation = container_of(head, struct nfs_delegation, rcu);
35 
36 	nfs_do_free_delegation(delegation);
37 }
38 
39 static void nfs_free_delegation(struct nfs_delegation *delegation)
40 {
41 	call_rcu(&delegation->rcu, nfs_free_delegation_callback);
42 }
43 
44 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
45 {
46 	set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
47 }
48 
49 int nfs_have_delegation(struct inode *inode, fmode_t flags)
50 {
51 	struct nfs_delegation *delegation;
52 	int ret = 0;
53 
54 	flags &= FMODE_READ|FMODE_WRITE;
55 	rcu_read_lock();
56 	delegation = rcu_dereference(NFS_I(inode)->delegation);
57 	if (delegation != NULL && (delegation->type & flags) == flags) {
58 		nfs_mark_delegation_referenced(delegation);
59 		ret = 1;
60 	}
61 	rcu_read_unlock();
62 	return ret;
63 }
64 
65 static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state)
66 {
67 	struct inode *inode = state->inode;
68 	struct file_lock *fl;
69 	int status = 0;
70 
71 	if (inode->i_flock == NULL)
72 		goto out;
73 
74 	/* Protect inode->i_flock using the BKL */
75 	lock_kernel();
76 	for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
77 		if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
78 			continue;
79 		if (nfs_file_open_context(fl->fl_file) != ctx)
80 			continue;
81 		unlock_kernel();
82 		status = nfs4_lock_delegation_recall(state, fl);
83 		if (status < 0)
84 			goto out;
85 		lock_kernel();
86 	}
87 	unlock_kernel();
88 out:
89 	return status;
90 }
91 
92 static int nfs_delegation_claim_opens(struct inode *inode, const nfs4_stateid *stateid)
93 {
94 	struct nfs_inode *nfsi = NFS_I(inode);
95 	struct nfs_open_context *ctx;
96 	struct nfs4_state *state;
97 	int err;
98 
99 again:
100 	spin_lock(&inode->i_lock);
101 	list_for_each_entry(ctx, &nfsi->open_files, list) {
102 		state = ctx->state;
103 		if (state == NULL)
104 			continue;
105 		if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
106 			continue;
107 		if (memcmp(state->stateid.data, stateid->data, sizeof(state->stateid.data)) != 0)
108 			continue;
109 		get_nfs_open_context(ctx);
110 		spin_unlock(&inode->i_lock);
111 		err = nfs4_open_delegation_recall(ctx, state, stateid);
112 		if (err >= 0)
113 			err = nfs_delegation_claim_locks(ctx, state);
114 		put_nfs_open_context(ctx);
115 		if (err != 0)
116 			return err;
117 		goto again;
118 	}
119 	spin_unlock(&inode->i_lock);
120 	return 0;
121 }
122 
123 /*
124  * Set up a delegation on an inode
125  */
126 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
127 {
128 	struct nfs_delegation *delegation;
129 	struct rpc_cred *oldcred = NULL;
130 
131 	rcu_read_lock();
132 	delegation = rcu_dereference(NFS_I(inode)->delegation);
133 	if (delegation != NULL) {
134 		spin_lock(&delegation->lock);
135 		if (delegation->inode != NULL) {
136 			memcpy(delegation->stateid.data, res->delegation.data,
137 			       sizeof(delegation->stateid.data));
138 			delegation->type = res->delegation_type;
139 			delegation->maxsize = res->maxsize;
140 			oldcred = delegation->cred;
141 			delegation->cred = get_rpccred(cred);
142 			clear_bit(NFS_DELEGATION_NEED_RECLAIM,
143 				  &delegation->flags);
144 			NFS_I(inode)->delegation_state = delegation->type;
145 			spin_unlock(&delegation->lock);
146 			put_rpccred(oldcred);
147 			rcu_read_unlock();
148 		} else {
149 			/* We appear to have raced with a delegation return. */
150 			spin_unlock(&delegation->lock);
151 			rcu_read_unlock();
152 			nfs_inode_set_delegation(inode, cred, res);
153 		}
154 	} else {
155 		rcu_read_unlock();
156 	}
157 }
158 
159 static int nfs_do_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
160 {
161 	int res = 0;
162 
163 	res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync);
164 	nfs_free_delegation(delegation);
165 	return res;
166 }
167 
168 static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation)
169 {
170 	struct inode *inode = NULL;
171 
172 	spin_lock(&delegation->lock);
173 	if (delegation->inode != NULL)
174 		inode = igrab(delegation->inode);
175 	spin_unlock(&delegation->lock);
176 	return inode;
177 }
178 
179 static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi,
180 							   const nfs4_stateid *stateid,
181 							   struct nfs_client *clp)
182 {
183 	struct nfs_delegation *delegation =
184 		rcu_dereference_protected(nfsi->delegation,
185 					  lockdep_is_held(&clp->cl_lock));
186 
187 	if (delegation == NULL)
188 		goto nomatch;
189 	spin_lock(&delegation->lock);
190 	if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
191 				sizeof(delegation->stateid.data)) != 0)
192 		goto nomatch_unlock;
193 	list_del_rcu(&delegation->super_list);
194 	delegation->inode = NULL;
195 	nfsi->delegation_state = 0;
196 	rcu_assign_pointer(nfsi->delegation, NULL);
197 	spin_unlock(&delegation->lock);
198 	return delegation;
199 nomatch_unlock:
200 	spin_unlock(&delegation->lock);
201 nomatch:
202 	return NULL;
203 }
204 
205 /*
206  * Set up a delegation on an inode
207  */
208 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
209 {
210 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
211 	struct nfs_inode *nfsi = NFS_I(inode);
212 	struct nfs_delegation *delegation, *old_delegation;
213 	struct nfs_delegation *freeme = NULL;
214 	int status = 0;
215 
216 	delegation = kmalloc(sizeof(*delegation), GFP_NOFS);
217 	if (delegation == NULL)
218 		return -ENOMEM;
219 	memcpy(delegation->stateid.data, res->delegation.data,
220 			sizeof(delegation->stateid.data));
221 	delegation->type = res->delegation_type;
222 	delegation->maxsize = res->maxsize;
223 	delegation->change_attr = nfsi->change_attr;
224 	delegation->cred = get_rpccred(cred);
225 	delegation->inode = inode;
226 	delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
227 	spin_lock_init(&delegation->lock);
228 
229 	spin_lock(&clp->cl_lock);
230 	old_delegation = rcu_dereference_protected(nfsi->delegation,
231 						   lockdep_is_held(&clp->cl_lock));
232 	if (old_delegation != NULL) {
233 		if (memcmp(&delegation->stateid, &old_delegation->stateid,
234 					sizeof(old_delegation->stateid)) == 0 &&
235 				delegation->type == old_delegation->type) {
236 			goto out;
237 		}
238 		/*
239 		 * Deal with broken servers that hand out two
240 		 * delegations for the same file.
241 		 */
242 		dfprintk(FILE, "%s: server %s handed out "
243 				"a duplicate delegation!\n",
244 				__func__, clp->cl_hostname);
245 		if (delegation->type <= old_delegation->type) {
246 			freeme = delegation;
247 			delegation = NULL;
248 			goto out;
249 		}
250 		freeme = nfs_detach_delegation_locked(nfsi, NULL, clp);
251 	}
252 	list_add_rcu(&delegation->super_list, &clp->cl_delegations);
253 	nfsi->delegation_state = delegation->type;
254 	rcu_assign_pointer(nfsi->delegation, delegation);
255 	delegation = NULL;
256 
257 	/* Ensure we revalidate the attributes and page cache! */
258 	spin_lock(&inode->i_lock);
259 	nfsi->cache_validity |= NFS_INO_REVAL_FORCED;
260 	spin_unlock(&inode->i_lock);
261 
262 out:
263 	spin_unlock(&clp->cl_lock);
264 	if (delegation != NULL)
265 		nfs_free_delegation(delegation);
266 	if (freeme != NULL)
267 		nfs_do_return_delegation(inode, freeme, 0);
268 	return status;
269 }
270 
271 /* Sync all data to disk upon delegation return */
272 static void nfs_msync_inode(struct inode *inode)
273 {
274 	filemap_fdatawrite(inode->i_mapping);
275 	nfs_wb_all(inode);
276 	filemap_fdatawait(inode->i_mapping);
277 }
278 
279 /*
280  * Basic procedure for returning a delegation to the server
281  */
282 static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegation *delegation, int issync)
283 {
284 	struct nfs_inode *nfsi = NFS_I(inode);
285 	int err;
286 
287 	/*
288 	 * Guard against new delegated open/lock/unlock calls and against
289 	 * state recovery
290 	 */
291 	down_write(&nfsi->rwsem);
292 	err = nfs_delegation_claim_opens(inode, &delegation->stateid);
293 	up_write(&nfsi->rwsem);
294 	if (err)
295 		goto out;
296 
297 	err = nfs_do_return_delegation(inode, delegation, issync);
298 out:
299 	return err;
300 }
301 
302 /*
303  * Return all delegations that have been marked for return
304  */
305 int nfs_client_return_marked_delegations(struct nfs_client *clp)
306 {
307 	struct nfs_delegation *delegation;
308 	struct inode *inode;
309 	int err = 0;
310 
311 restart:
312 	rcu_read_lock();
313 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
314 		if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
315 			continue;
316 		inode = nfs_delegation_grab_inode(delegation);
317 		if (inode == NULL)
318 			continue;
319 		spin_lock(&clp->cl_lock);
320 		delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
321 		spin_unlock(&clp->cl_lock);
322 		rcu_read_unlock();
323 		if (delegation != NULL) {
324 			filemap_flush(inode->i_mapping);
325 			err = __nfs_inode_return_delegation(inode, delegation, 0);
326 		}
327 		iput(inode);
328 		if (!err)
329 			goto restart;
330 		set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
331 		return err;
332 	}
333 	rcu_read_unlock();
334 	return 0;
335 }
336 
337 /*
338  * This function returns the delegation without reclaiming opens
339  * or protecting against delegation reclaims.
340  * It is therefore really only safe to be called from
341  * nfs4_clear_inode()
342  */
343 void nfs_inode_return_delegation_noreclaim(struct inode *inode)
344 {
345 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
346 	struct nfs_inode *nfsi = NFS_I(inode);
347 	struct nfs_delegation *delegation;
348 
349 	if (rcu_access_pointer(nfsi->delegation) != NULL) {
350 		spin_lock(&clp->cl_lock);
351 		delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
352 		spin_unlock(&clp->cl_lock);
353 		if (delegation != NULL)
354 			nfs_do_return_delegation(inode, delegation, 0);
355 	}
356 }
357 
358 int nfs_inode_return_delegation(struct inode *inode)
359 {
360 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
361 	struct nfs_inode *nfsi = NFS_I(inode);
362 	struct nfs_delegation *delegation;
363 	int err = 0;
364 
365 	if (rcu_access_pointer(nfsi->delegation) != NULL) {
366 		spin_lock(&clp->cl_lock);
367 		delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
368 		spin_unlock(&clp->cl_lock);
369 		if (delegation != NULL) {
370 			nfs_msync_inode(inode);
371 			err = __nfs_inode_return_delegation(inode, delegation, 1);
372 		}
373 	}
374 	return err;
375 }
376 
377 static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation)
378 {
379 	set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
380 	set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
381 }
382 
383 /*
384  * Return all delegations associated to a super block
385  */
386 void nfs_super_return_all_delegations(struct super_block *sb)
387 {
388 	struct nfs_client *clp = NFS_SB(sb)->nfs_client;
389 	struct nfs_delegation *delegation;
390 
391 	if (clp == NULL)
392 		return;
393 	rcu_read_lock();
394 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
395 		spin_lock(&delegation->lock);
396 		if (delegation->inode != NULL && delegation->inode->i_sb == sb)
397 			set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
398 		spin_unlock(&delegation->lock);
399 	}
400 	rcu_read_unlock();
401 	if (nfs_client_return_marked_delegations(clp) != 0)
402 		nfs4_schedule_state_manager(clp);
403 }
404 
405 static
406 void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags)
407 {
408 	struct nfs_delegation *delegation;
409 
410 	rcu_read_lock();
411 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
412 		if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
413 			continue;
414 		if (delegation->type & flags)
415 			nfs_mark_return_delegation(clp, delegation);
416 	}
417 	rcu_read_unlock();
418 }
419 
420 static void nfs_client_mark_return_all_delegations(struct nfs_client *clp)
421 {
422 	nfs_client_mark_return_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
423 }
424 
425 static void nfs_delegation_run_state_manager(struct nfs_client *clp)
426 {
427 	if (test_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state))
428 		nfs4_schedule_state_manager(clp);
429 }
430 
431 void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
432 {
433 	nfs_client_mark_return_all_delegation_types(clp, flags);
434 	nfs_delegation_run_state_manager(clp);
435 }
436 
437 void nfs_expire_all_delegations(struct nfs_client *clp)
438 {
439 	nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
440 }
441 
442 /*
443  * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
444  */
445 void nfs_handle_cb_pathdown(struct nfs_client *clp)
446 {
447 	if (clp == NULL)
448 		return;
449 	nfs_client_mark_return_all_delegations(clp);
450 }
451 
452 static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp)
453 {
454 	struct nfs_delegation *delegation;
455 
456 	rcu_read_lock();
457 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
458 		if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
459 			continue;
460 		nfs_mark_return_delegation(clp, delegation);
461 	}
462 	rcu_read_unlock();
463 }
464 
465 void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
466 {
467 	nfs_client_mark_return_unreferenced_delegations(clp);
468 	nfs_delegation_run_state_manager(clp);
469 }
470 
471 /*
472  * Asynchronous delegation recall!
473  */
474 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
475 				      int (*validate_stateid)(struct nfs_delegation *delegation,
476 							      const nfs4_stateid *stateid))
477 {
478 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
479 	struct nfs_delegation *delegation;
480 
481 	rcu_read_lock();
482 	delegation = rcu_dereference(NFS_I(inode)->delegation);
483 
484 	if (!validate_stateid(delegation, stateid)) {
485 		rcu_read_unlock();
486 		return -ENOENT;
487 	}
488 
489 	nfs_mark_return_delegation(clp, delegation);
490 	rcu_read_unlock();
491 	nfs_delegation_run_state_manager(clp);
492 	return 0;
493 }
494 
495 /*
496  * Retrieve the inode associated with a delegation
497  */
498 struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle)
499 {
500 	struct nfs_delegation *delegation;
501 	struct inode *res = NULL;
502 	rcu_read_lock();
503 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
504 		spin_lock(&delegation->lock);
505 		if (delegation->inode != NULL &&
506 		    nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
507 			res = igrab(delegation->inode);
508 		}
509 		spin_unlock(&delegation->lock);
510 		if (res != NULL)
511 			break;
512 	}
513 	rcu_read_unlock();
514 	return res;
515 }
516 
517 /*
518  * Mark all delegations as needing to be reclaimed
519  */
520 void nfs_delegation_mark_reclaim(struct nfs_client *clp)
521 {
522 	struct nfs_delegation *delegation;
523 	rcu_read_lock();
524 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
525 		set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
526 	rcu_read_unlock();
527 }
528 
529 /*
530  * Reap all unclaimed delegations after reboot recovery is done
531  */
532 void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
533 {
534 	struct nfs_delegation *delegation;
535 	struct inode *inode;
536 restart:
537 	rcu_read_lock();
538 	list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
539 		if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0)
540 			continue;
541 		inode = nfs_delegation_grab_inode(delegation);
542 		if (inode == NULL)
543 			continue;
544 		spin_lock(&clp->cl_lock);
545 		delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp);
546 		spin_unlock(&clp->cl_lock);
547 		rcu_read_unlock();
548 		if (delegation != NULL)
549 			nfs_free_delegation(delegation);
550 		iput(inode);
551 		goto restart;
552 	}
553 	rcu_read_unlock();
554 }
555 
556 int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
557 {
558 	struct nfs_inode *nfsi = NFS_I(inode);
559 	struct nfs_delegation *delegation;
560 	int ret = 0;
561 
562 	rcu_read_lock();
563 	delegation = rcu_dereference(nfsi->delegation);
564 	if (delegation != NULL) {
565 		memcpy(dst->data, delegation->stateid.data, sizeof(dst->data));
566 		ret = 1;
567 	}
568 	rcu_read_unlock();
569 	return ret;
570 }
571