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