xref: /linux/fs/nfsd/nfs4recover.c (revision 1d7f1e329bac41d017aaf40037346bf89f5c245e)
1 /*
2 *  Copyright (c) 2004 The Regents of the University of Michigan.
3 *  Copyright (c) 2012 Jeff Layton <jlayton@redhat.com>
4 *  All rights reserved.
5 *
6 *  Andy Adamson <andros@citi.umich.edu>
7 *
8 *  Redistribution and use in source and binary forms, with or without
9 *  modification, are permitted provided that the following conditions
10 *  are met:
11 *
12 *  1. Redistributions of source code must retain the above copyright
13 *     notice, this list of conditions and the following disclaimer.
14 *  2. Redistributions in binary form must reproduce the above copyright
15 *     notice, this list of conditions and the following disclaimer in the
16 *     documentation and/or other materials provided with the distribution.
17 *  3. Neither the name of the University nor the names of its
18 *     contributors may be used to endorse or promote products derived
19 *     from this software without specific prior written permission.
20 *
21 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34 
35 #include <crypto/md5.h>
36 #include <crypto/sha2.h>
37 #include <linux/file.h>
38 #include <linux/slab.h>
39 #include <linux/namei.h>
40 #include <linux/sched.h>
41 #include <linux/fs.h>
42 #include <linux/hex.h>
43 #include <linux/module.h>
44 #include <linux/umh.h>
45 #include <net/net_namespace.h>
46 #include <linux/sunrpc/rpc_pipe_fs.h>
47 #include <linux/sunrpc/clnt.h>
48 #include <linux/nfsd/cld.h>
49 
50 #include "nfsd.h"
51 #include "state.h"
52 #include "vfs.h"
53 #include "netns.h"
54 
55 #define NFSDDBG_FACILITY                NFSDDBG_PROC
56 
57 /* Declarations */
58 struct nfsd4_client_tracking_ops {
59 	int (*init)(struct net *);
60 	void (*exit)(struct net *);
61 	void (*create)(struct nfs4_client *);
62 	void (*remove)(struct nfs4_client *);
63 	int (*check)(struct nfs4_client *);
64 	void (*grace_done)(struct nfsd_net *);
65 	uint8_t version;
66 	size_t msglen;
67 };
68 
69 static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops;
70 static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2;
71 
72 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
73 /* Globals */
74 static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
75 
76 static int
77 nfs4_save_creds(const struct cred **original_creds)
78 {
79 	struct cred *new;
80 
81 	new = prepare_creds();
82 	if (!new)
83 		return -ENOMEM;
84 
85 	new->fsuid = GLOBAL_ROOT_UID;
86 	new->fsgid = GLOBAL_ROOT_GID;
87 	*original_creds = override_creds(new);
88 	return 0;
89 }
90 
91 static void
92 nfs4_reset_creds(const struct cred *original)
93 {
94 	put_cred(revert_creds(original));
95 }
96 
97 static void
98 nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname)
99 {
100 	u8 digest[MD5_DIGEST_SIZE];
101 
102 	dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
103 			clname->len, clname->data);
104 
105 	md5(clname->data, clname->len, digest);
106 
107 	static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1);
108 	sprintf(dname, "%*phN", MD5_DIGEST_SIZE, digest);
109 }
110 
111 static void
112 __nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
113 				    char *dname, struct nfsd_net *nn)
114 {
115 	struct xdr_netobj name = { .len = strlen(dname), .data = dname };
116 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
117 	struct nfs4_client_reclaim *crp;
118 
119 	crp = nfs4_client_to_reclaim(name, princhash, nn);
120 	crp->cr_clp = clp;
121 }
122 
123 static void
124 nfsd4_create_clid_dir(struct nfs4_client *clp)
125 {
126 	const struct cred *original_cred;
127 	char dname[HEXDIR_LEN];
128 	struct dentry *dir, *dentry;
129 	int status;
130 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
131 
132 	if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
133 		return;
134 	if (!nn->rec_file)
135 		return;
136 
137 	nfs4_make_rec_clidname(dname, &clp->cl_name);
138 
139 	status = nfs4_save_creds(&original_cred);
140 	if (status < 0)
141 		return;
142 
143 	status = mnt_want_write_file(nn->rec_file);
144 	if (status)
145 		goto out_creds;
146 
147 	dir = nn->rec_file->f_path.dentry;
148 
149 	dentry = start_creating(&nop_mnt_idmap, dir, &QSTR(dname));
150 	if (IS_ERR(dentry)) {
151 		status = PTR_ERR(dentry);
152 		goto out;
153 	}
154 	if (d_really_is_positive(dentry))
155 		/*
156 		 * In the 4.1 case, where we're called from
157 		 * reclaim_complete(), records from the previous reboot
158 		 * may still be left, so this is OK.
159 		 *
160 		 * In the 4.0 case, we should never get here; but we may
161 		 * as well be forgiving and just succeed silently.
162 		 */
163 		goto out_end;
164 	dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, 0700, NULL);
165 	if (IS_ERR(dentry))
166 		status = PTR_ERR(dentry);
167 out_end:
168 	end_creating(dentry);
169 out:
170 	if (status == 0) {
171 		if (test_bit(NFSD_NET_IN_GRACE, &nn->flags))
172 			__nfsd4_create_reclaim_record_grace(clp, dname, nn);
173 		vfs_fsync(nn->rec_file, 0);
174 	} else {
175 		printk(KERN_ERR "NFSD: failed to write recovery record"
176 				" (err %d); please check that %s exists"
177 				" and is writeable", status,
178 				user_recovery_dirname);
179 	}
180 	mnt_drop_write_file(nn->rec_file);
181 out_creds:
182 	nfs4_reset_creds(original_cred);
183 }
184 
185 typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *);
186 
187 struct name_list {
188 	char name[HEXDIR_LEN];
189 	struct list_head list;
190 };
191 
192 struct nfs4_dir_ctx {
193 	struct dir_context ctx;
194 	struct list_head names;
195 };
196 
197 static bool
198 nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
199 		loff_t offset, u64 ino, unsigned int d_type)
200 {
201 	struct nfs4_dir_ctx *ctx =
202 		container_of(__ctx, struct nfs4_dir_ctx, ctx);
203 	struct name_list *entry;
204 
205 	if (namlen != HEXDIR_LEN - 1)
206 		return true;
207 	entry = kmalloc_obj(struct name_list);
208 	if (entry == NULL)
209 		return false;
210 	memcpy(entry->name, name, HEXDIR_LEN - 1);
211 	entry->name[HEXDIR_LEN - 1] = '\0';
212 	list_add(&entry->list, &ctx->names);
213 	return true;
214 }
215 
216 static int
217 nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
218 {
219 	const struct cred *original_cred;
220 	struct dentry *dir = nn->rec_file->f_path.dentry;
221 	struct nfs4_dir_ctx ctx = {
222 		.ctx.actor = nfsd4_build_namelist,
223 		.names = LIST_HEAD_INIT(ctx.names)
224 	};
225 	struct name_list *entry, *tmp;
226 	int status;
227 
228 	status = nfs4_save_creds(&original_cred);
229 	if (status < 0)
230 		return status;
231 
232 	status = vfs_llseek(nn->rec_file, 0, SEEK_SET);
233 	if (status < 0) {
234 		nfs4_reset_creds(original_cred);
235 		return status;
236 	}
237 
238 	status = iterate_dir(nn->rec_file, &ctx.ctx);
239 
240 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
241 		if (!status)
242 			status = f(dir, entry->name, nn);
243 
244 		list_del(&entry->list);
245 		kfree(entry);
246 	}
247 	nfs4_reset_creds(original_cred);
248 
249 	list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
250 		dprintk("NFSD: %s. Left entry %s\n", __func__, entry->name);
251 		list_del(&entry->list);
252 		kfree(entry);
253 	}
254 	return status;
255 }
256 
257 static int
258 nfsd4_unlink_clid_dir(char *name, struct nfsd_net *nn)
259 {
260 	struct dentry *dir, *dentry;
261 	int status;
262 
263 	dprintk("NFSD: nfsd4_unlink_clid_dir. name %s\n", name);
264 
265 	dir = nn->rec_file->f_path.dentry;
266 	dentry = start_removing(&nop_mnt_idmap, dir, &QSTR(name));
267 	if (IS_ERR(dentry))
268 		return PTR_ERR(dentry);
269 
270 	status = vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry, NULL);
271 	end_removing(dentry);
272 	return status;
273 }
274 
275 static void
276 __nfsd4_remove_reclaim_record_grace(const char *dname, int len,
277 		struct nfsd_net *nn)
278 {
279 	struct xdr_netobj name;
280 	struct nfs4_client_reclaim *crp;
281 
282 	name.data = kmemdup(dname, len, GFP_KERNEL);
283 	if (!name.data) {
284 		dprintk("%s: failed to allocate memory for name.data!\n",
285 			__func__);
286 		return;
287 	}
288 	name.len = len;
289 	down_write(&nn->reclaim_str_hashtbl_lock);
290 	crp = nfsd4_find_reclaim_client(name, nn);
291 	if (crp)
292 		nfs4_remove_reclaim_record(crp, nn);
293 	up_write(&nn->reclaim_str_hashtbl_lock);
294 	kfree(name.data);
295 }
296 
297 static void
298 nfsd4_remove_clid_dir(struct nfs4_client *clp)
299 {
300 	const struct cred *original_cred;
301 	char dname[HEXDIR_LEN];
302 	int status;
303 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
304 
305 	if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
306 		return;
307 
308 	nfs4_make_rec_clidname(dname, &clp->cl_name);
309 
310 	status = mnt_want_write_file(nn->rec_file);
311 	if (status)
312 		goto out;
313 	clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
314 
315 	status = nfs4_save_creds(&original_cred);
316 	if (status < 0)
317 		goto out_drop_write;
318 
319 	status = nfsd4_unlink_clid_dir(dname, nn);
320 	nfs4_reset_creds(original_cred);
321 	if (status == 0) {
322 		vfs_fsync(nn->rec_file, 0);
323 		if (test_bit(NFSD_NET_IN_GRACE, &nn->flags))
324 			__nfsd4_remove_reclaim_record_grace(dname,
325 					HEXDIR_LEN, nn);
326 	}
327 out_drop_write:
328 	mnt_drop_write_file(nn->rec_file);
329 out:
330 	if (status)
331 		printk("NFSD: Failed to remove expired client state directory"
332 				" %.*s\n", HEXDIR_LEN, dname);
333 }
334 
335 static int
336 purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
337 {
338 	int status;
339 	struct dentry *child;
340 	struct xdr_netobj name;
341 
342 	if (strlen(cname) != HEXDIR_LEN - 1) {
343 		printk("%s: illegal name %s in recovery directory\n",
344 				__func__, cname);
345 		/* Keep trying; maybe the others are OK: */
346 		return 0;
347 	}
348 	name.data = kstrdup(cname, GFP_KERNEL);
349 	if (!name.data) {
350 		dprintk("%s: failed to allocate memory for name.data!\n",
351 			__func__);
352 		goto out;
353 	}
354 	name.len = HEXDIR_LEN;
355 	if (nfs4_has_reclaimed_state(name, nn))
356 		goto out_free;
357 
358 	child = start_removing_noperm(parent, &QSTR(cname));
359 	if (!IS_ERR(child)) {
360 		status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL);
361 		if (status)
362 			printk("failed to remove client recovery directory %pd\n",
363 			       child);
364 	}
365 	end_removing(child);
366 
367 out_free:
368 	kfree(name.data);
369 out:
370 	/* Keep trying, success or failure: */
371 	return 0;
372 }
373 
374 static void
375 nfsd4_recdir_purge_old(struct nfsd_net *nn)
376 {
377 	int status;
378 
379 	clear_bit(NFSD_NET_IN_GRACE, &nn->flags);
380 	if (!nn->rec_file)
381 		return;
382 	status = mnt_want_write_file(nn->rec_file);
383 	if (status)
384 		goto out;
385 	status = nfsd4_list_rec_dir(purge_old, nn);
386 	if (status == 0)
387 		vfs_fsync(nn->rec_file, 0);
388 	mnt_drop_write_file(nn->rec_file);
389 out:
390 	nfs4_release_reclaim(nn);
391 	if (status)
392 		printk("nfsd4: failed to purge old clients from recovery"
393 			" directory %pD\n", nn->rec_file);
394 }
395 
396 static int
397 load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
398 {
399 	struct xdr_netobj name = { .len = HEXDIR_LEN, .data = cname };
400 	struct xdr_netobj princhash = { .len = 0, .data = NULL };
401 
402 	if (strlen(cname) != HEXDIR_LEN - 1) {
403 		printk("%s: illegal name %s in recovery directory\n",
404 				__func__, cname);
405 		/* Keep trying; maybe the others are OK: */
406 		return 0;
407 	}
408 	nfs4_client_to_reclaim(name, princhash, nn);
409 	return 0;
410 }
411 
412 static int
413 nfsd4_recdir_load(struct net *net) {
414 	int status;
415 	struct nfsd_net *nn =  net_generic(net, nfsd_net_id);
416 
417 	if (!nn->rec_file)
418 		return 0;
419 
420 	status = nfsd4_list_rec_dir(load_recdir, nn);
421 	if (status)
422 		printk("nfsd4: failed loading clients from recovery"
423 			" directory %pD\n", nn->rec_file);
424 	return status;
425 }
426 
427 /*
428  * Hold reference to the recovery directory.
429  */
430 
431 static int
432 nfsd4_init_recdir(struct net *net)
433 {
434 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
435 	const struct cred *original_cred;
436 	int status;
437 
438 	printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
439 			user_recovery_dirname);
440 
441 	BUG_ON(nn->rec_file);
442 
443 	status = nfs4_save_creds(&original_cred);
444 	if (status < 0) {
445 		printk("NFSD: Unable to change credentials to find recovery"
446 		       " directory: error %d\n",
447 		       status);
448 		return status;
449 	}
450 
451 	nn->rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0);
452 	if (IS_ERR(nn->rec_file)) {
453 		printk("NFSD: unable to find recovery directory %s\n",
454 				user_recovery_dirname);
455 		status = PTR_ERR(nn->rec_file);
456 		nn->rec_file = NULL;
457 	}
458 
459 	nfs4_reset_creds(original_cred);
460 	if (!status)
461 		set_bit(NFSD_NET_IN_GRACE, &nn->flags);
462 	return status;
463 }
464 
465 static void
466 nfsd4_shutdown_recdir(struct net *net)
467 {
468 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
469 
470 	if (!nn->rec_file)
471 		return;
472 	fput(nn->rec_file);
473 	nn->rec_file = NULL;
474 }
475 
476 static int
477 nfs4_legacy_state_init(struct net *net)
478 {
479 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
480 	int i;
481 
482 	nn->reclaim_str_hashtbl = kmalloc_objs(struct list_head,
483 					       CLIENT_HASH_SIZE);
484 	if (!nn->reclaim_str_hashtbl)
485 		return -ENOMEM;
486 
487 	for (i = 0; i < CLIENT_HASH_SIZE; i++)
488 		INIT_LIST_HEAD(&nn->reclaim_str_hashtbl[i]);
489 	nn->reclaim_str_hashtbl_size = 0;
490 	init_rwsem(&nn->reclaim_str_hashtbl_lock);
491 
492 	return 0;
493 }
494 
495 static void
496 nfs4_legacy_state_shutdown(struct net *net)
497 {
498 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
499 
500 	kfree(nn->reclaim_str_hashtbl);
501 }
502 
503 static int
504 nfsd4_load_reboot_recovery_data(struct net *net)
505 {
506 	int status;
507 
508 	status = nfsd4_init_recdir(net);
509 	if (status)
510 		return status;
511 
512 	status = nfsd4_recdir_load(net);
513 	if (status)
514 		nfsd4_shutdown_recdir(net);
515 
516 	return status;
517 }
518 
519 static int
520 nfsd4_legacy_tracking_init(struct net *net)
521 {
522 	int status;
523 
524 	/* XXX: The legacy code won't work in a container */
525 	if (net != &init_net) {
526 		pr_warn("NFSD: attempt to initialize legacy client tracking in a container ignored.\n");
527 		return -EINVAL;
528 	}
529 
530 	status = nfs4_legacy_state_init(net);
531 	if (status)
532 		return status;
533 
534 	status = nfsd4_load_reboot_recovery_data(net);
535 	if (status)
536 		goto err;
537 	pr_info("NFSD: Using legacy client tracking operations.\n");
538 	return 0;
539 
540 err:
541 	nfs4_legacy_state_shutdown(net);
542 	return status;
543 }
544 
545 static void
546 nfsd4_legacy_tracking_exit(struct net *net)
547 {
548 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
549 
550 	nfs4_release_reclaim(nn);
551 	nfsd4_shutdown_recdir(net);
552 	nfs4_legacy_state_shutdown(net);
553 }
554 
555 /*
556  * Change the NFSv4 recovery directory to recdir.
557  */
558 int
559 nfs4_reset_recoverydir(char *recdir)
560 {
561 	int status;
562 	struct path path;
563 
564 	status = kern_path(recdir, LOOKUP_FOLLOW, &path);
565 	if (status)
566 		return status;
567 	status = -ENOTDIR;
568 	if (d_is_dir(path.dentry)) {
569 		strscpy(user_recovery_dirname, recdir,
570 			sizeof(user_recovery_dirname));
571 		status = 0;
572 	}
573 	path_put(&path);
574 	return status;
575 }
576 
577 char *
578 nfs4_recoverydir(void)
579 {
580 	return user_recovery_dirname;
581 }
582 
583 static int
584 nfsd4_check_legacy_client(struct nfs4_client *clp)
585 {
586 	char dname[HEXDIR_LEN];
587 	struct nfs4_client_reclaim *crp;
588 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
589 	struct xdr_netobj name;
590 
591 	/* did we already find that this client is stable? */
592 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
593 		return 0;
594 
595 	nfs4_make_rec_clidname(dname, &clp->cl_name);
596 
597 	/* look for it in the reclaim hashtable otherwise */
598 	name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
599 	if (!name.data) {
600 		dprintk("%s: failed to allocate memory for name.data!\n",
601 			__func__);
602 		goto out_enoent;
603 	}
604 	name.len = HEXDIR_LEN;
605 	down_read(&nn->reclaim_str_hashtbl_lock);
606 	crp = nfsd4_find_reclaim_client(name, nn);
607 	if (crp) {
608 		set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
609 		crp->cr_clp = clp;
610 	}
611 	up_read(&nn->reclaim_str_hashtbl_lock);
612 	kfree(name.data);
613 	if (crp)
614 		return 0;
615 
616 out_enoent:
617 	return -ENOENT;
618 }
619 
620 static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
621 	.init		= nfsd4_legacy_tracking_init,
622 	.exit		= nfsd4_legacy_tracking_exit,
623 	.create		= nfsd4_create_clid_dir,
624 	.remove		= nfsd4_remove_clid_dir,
625 	.check		= nfsd4_check_legacy_client,
626 	.grace_done	= nfsd4_recdir_purge_old,
627 	.version	= 1,
628 	.msglen		= 0,
629 };
630 #endif /* CONFIG_NFSD_LEGACY_CLIENT_TRACKING */
631 
632 /* Globals */
633 #define NFSD_PIPE_DIR		"nfsd"
634 #define NFSD_CLD_PIPE		"cld"
635 
636 /* per-net-ns structure for holding cld upcall info */
637 struct cld_net {
638 	struct rpc_pipe		*cn_pipe;
639 	spinlock_t		 cn_lock;
640 	struct list_head	 cn_list;
641 	unsigned int		 cn_xid;
642 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
643 	bool			 cn_has_legacy;
644 #endif
645 };
646 
647 struct cld_upcall {
648 	struct list_head	 cu_list;
649 	struct cld_net		*cu_net;
650 	struct completion	 cu_done;
651 	union {
652 		struct cld_msg_hdr	 cu_hdr;
653 		struct cld_msg		 cu_msg;
654 		struct cld_msg_v2	 cu_msg_v2;
655 	} cu_u;
656 };
657 
658 static int
659 __cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
660 {
661 	int ret;
662 	struct rpc_pipe_msg msg;
663 	struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u);
664 
665 	memset(&msg, 0, sizeof(msg));
666 	msg.data = cmsg;
667 	msg.len = nn->client_tracking_ops->msglen;
668 
669 	ret = rpc_queue_upcall(pipe, &msg);
670 	if (ret < 0) {
671 		goto out;
672 	}
673 
674 	wait_for_completion(&cup->cu_done);
675 
676 	if (msg.errno < 0)
677 		ret = msg.errno;
678 out:
679 	return ret;
680 }
681 
682 static int
683 cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
684 {
685 	int ret;
686 
687 	/*
688 	 * -EAGAIN occurs when pipe is closed and reopened while there are
689 	 *  upcalls queued.
690 	 */
691 	do {
692 		ret = __cld_pipe_upcall(pipe, cmsg, nn);
693 	} while (ret == -EAGAIN);
694 
695 	return ret;
696 }
697 
698 static ssize_t
699 __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
700 		struct nfsd_net *nn)
701 {
702 	uint8_t cmd, princhashlen;
703 	struct xdr_netobj name, princhash = { .len = 0, .data = NULL };
704 	char *namecopy __free(kfree) = NULL;
705 	char *princhashcopy __free(kfree) = NULL;
706 	uint16_t namelen;
707 
708 	if (get_user(cmd, &cmsg->cm_cmd)) {
709 		dprintk("%s: error when copying cmd from userspace", __func__);
710 		return -EFAULT;
711 	}
712 	if (cmd == Cld_GraceStart) {
713 		if (nn->client_tracking_ops->version >= 2) {
714 			const struct cld_clntinfo __user *ci;
715 
716 			ci = &cmsg->cm_u.cm_clntinfo;
717 			if (get_user(namelen, &ci->cc_name.cn_len))
718 				return -EFAULT;
719 			if (namelen == 0 || namelen > NFS4_OPAQUE_LIMIT) {
720 				dprintk("%s: invalid namelen (%u)", __func__, namelen);
721 				return -EINVAL;
722 			}
723 			namecopy = memdup_user(&ci->cc_name.cn_id, namelen);
724 			if (IS_ERR(namecopy))
725 				return PTR_ERR(namecopy);
726 			name.data = namecopy;
727 			name.len = namelen;
728 			if (get_user(princhashlen, &ci->cc_princhash.cp_len))
729 				return -EFAULT;
730 			if (princhashlen > 0) {
731 				princhashcopy = memdup_user(
732 					&ci->cc_princhash.cp_data,
733 					princhashlen);
734 				if (IS_ERR(princhashcopy))
735 					return PTR_ERR(princhashcopy);
736 				princhash.data = princhashcopy;
737 				princhash.len = princhashlen;
738 			} else
739 				princhash.len = 0;
740 		} else {
741 			const struct cld_name __user *cnm;
742 
743 			cnm = &cmsg->cm_u.cm_name;
744 			if (get_user(namelen, &cnm->cn_len))
745 				return -EFAULT;
746 			if (namelen == 0 || namelen > NFS4_OPAQUE_LIMIT) {
747 				dprintk("%s: invalid namelen (%u)", __func__, namelen);
748 				return -EINVAL;
749 			}
750 			namecopy = memdup_user(&cnm->cn_id, namelen);
751 			if (IS_ERR(namecopy))
752 				return PTR_ERR(namecopy);
753 			name.data = namecopy;
754 			name.len = namelen;
755 		}
756 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
757 		if (name.len > 5 && memcmp(name.data, "hash:", 5) == 0) {
758 			struct cld_net *cn = nn->cld_net;
759 
760 			name.len = name.len - 5;
761 			name.data = name.data + 5;
762 			cn->cn_has_legacy = true;
763 		}
764 #endif
765 		if (!nfs4_client_to_reclaim(name, princhash, nn))
766 			return -EFAULT;
767 		return nn->client_tracking_ops->msglen;
768 	}
769 	return -EFAULT;
770 }
771 
772 static ssize_t
773 cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
774 {
775 	struct cld_upcall *tmp, *cup;
776 	struct cld_msg_hdr __user *hdr = (struct cld_msg_hdr __user *)src;
777 	struct cld_msg_v2 __user *cmsg = (struct cld_msg_v2 __user *)src;
778 	uint32_t xid;
779 	struct nfsd_net *nn = net_generic(file_inode(filp)->i_sb->s_fs_info,
780 						nfsd_net_id);
781 	struct cld_net *cn = nn->cld_net;
782 	int16_t status;
783 
784 	if (mlen != nn->client_tracking_ops->msglen) {
785 		dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen,
786 			nn->client_tracking_ops->msglen);
787 		return -EINVAL;
788 	}
789 
790 	/* copy just the xid so we can try to find that */
791 	if (copy_from_user(&xid, &hdr->cm_xid, sizeof(xid)) != 0) {
792 		dprintk("%s: error when copying xid from userspace", __func__);
793 		return -EFAULT;
794 	}
795 
796 	/*
797 	 * copy the status so we know whether to remove the upcall from the
798 	 * list (for -EINPROGRESS, we just want to make sure the xid is
799 	 * valid, not remove the upcall from the list)
800 	 */
801 	if (get_user(status, &hdr->cm_status)) {
802 		dprintk("%s: error when copying status from userspace", __func__);
803 		return -EFAULT;
804 	}
805 
806 	/* walk the list and find corresponding xid */
807 	cup = NULL;
808 	spin_lock(&cn->cn_lock);
809 	list_for_each_entry(tmp, &cn->cn_list, cu_list) {
810 		if (get_unaligned(&tmp->cu_u.cu_hdr.cm_xid) == xid) {
811 			cup = tmp;
812 			if (status != -EINPROGRESS)
813 				list_del_init(&cup->cu_list);
814 			break;
815 		}
816 	}
817 	spin_unlock(&cn->cn_lock);
818 
819 	/* couldn't find upcall? */
820 	if (!cup) {
821 		dprintk("%s: couldn't find upcall -- xid=%u\n", __func__, xid);
822 		return -EINVAL;
823 	}
824 
825 	if (status == -EINPROGRESS)
826 		return __cld_pipe_inprogress_downcall(cmsg, nn);
827 
828 	if (copy_from_user(&cup->cu_u.cu_msg_v2, src, mlen) != 0)
829 		return -EFAULT;
830 
831 	complete(&cup->cu_done);
832 	return mlen;
833 }
834 
835 static void
836 cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
837 {
838 	struct cld_msg *cmsg = msg->data;
839 	struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
840 						 cu_u.cu_msg);
841 
842 	/* errno >= 0 means we got a downcall */
843 	if (msg->errno >= 0)
844 		return;
845 
846 	complete(&cup->cu_done);
847 }
848 
849 static const struct rpc_pipe_ops cld_upcall_ops = {
850 	.upcall		= rpc_pipe_generic_upcall,
851 	.downcall	= cld_pipe_downcall,
852 	.destroy_msg	= cld_pipe_destroy_msg,
853 };
854 
855 static int
856 nfsd4_cld_register_sb(struct super_block *sb, struct rpc_pipe *pipe)
857 {
858 	struct dentry *dir;
859 	int err;
860 
861 	dir = rpc_d_lookup_sb(sb, NFSD_PIPE_DIR);
862 	if (dir == NULL)
863 		return -ENOENT;
864 	err = rpc_mkpipe_dentry(dir, NFSD_CLD_PIPE, NULL, pipe);
865 	dput(dir);
866 	return err;
867 }
868 
869 static int
870 nfsd4_cld_register_net(struct net *net, struct rpc_pipe *pipe)
871 {
872 	struct super_block *sb;
873 	int err;
874 
875 	sb = rpc_get_sb_net(net);
876 	if (!sb)
877 		return 0;
878 	err = nfsd4_cld_register_sb(sb, pipe);
879 	rpc_put_sb_net(net);
880 	return err;
881 }
882 
883 static void
884 nfsd4_cld_unregister_net(struct net *net, struct rpc_pipe *pipe)
885 {
886 	struct super_block *sb;
887 
888 	sb = rpc_get_sb_net(net);
889 	if (sb) {
890 		rpc_unlink(pipe);
891 		rpc_put_sb_net(net);
892 	}
893 }
894 
895 /* Initialize rpc_pipefs pipe for communication with client tracking daemon */
896 static int
897 __nfsd4_init_cld_pipe(struct net *net)
898 {
899 	int ret;
900 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
901 	struct cld_net *cn;
902 
903 	if (nn->cld_net)
904 		return 0;
905 
906 	cn = kzalloc_obj(*cn);
907 	if (!cn) {
908 		ret = -ENOMEM;
909 		goto err;
910 	}
911 
912 	cn->cn_pipe = rpc_mkpipe_data(&cld_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
913 	if (IS_ERR(cn->cn_pipe)) {
914 		ret = PTR_ERR(cn->cn_pipe);
915 		goto err;
916 	}
917 	spin_lock_init(&cn->cn_lock);
918 	INIT_LIST_HEAD(&cn->cn_list);
919 
920 	ret = nfsd4_cld_register_net(net, cn->cn_pipe);
921 	if (unlikely(ret))
922 		goto err_destroy_data;
923 
924 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
925 	cn->cn_has_legacy = false;
926 #endif
927 	nn->cld_net = cn;
928 	return 0;
929 
930 err_destroy_data:
931 	rpc_destroy_pipe_data(cn->cn_pipe);
932 err:
933 	kfree(cn);
934 	printk(KERN_ERR "NFSD: unable to create nfsdcld upcall pipe (%d)\n",
935 			ret);
936 	return ret;
937 }
938 
939 static int
940 nfsd4_init_cld_pipe(struct net *net)
941 {
942 	int status;
943 
944 	status = __nfsd4_init_cld_pipe(net);
945 	if (!status)
946 		pr_info("NFSD: Using old nfsdcld client tracking operations.\n");
947 	return status;
948 }
949 
950 static void
951 nfsd4_remove_cld_pipe(struct net *net)
952 {
953 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
954 	struct cld_net *cn = nn->cld_net;
955 
956 	nfsd4_cld_unregister_net(net, cn->cn_pipe);
957 	rpc_destroy_pipe_data(cn->cn_pipe);
958 	kfree(nn->cld_net);
959 	nn->cld_net = NULL;
960 }
961 
962 static struct cld_upcall *
963 alloc_cld_upcall(struct nfsd_net *nn)
964 {
965 	struct cld_upcall *new, *tmp;
966 	struct cld_net *cn = nn->cld_net;
967 
968 	new = kzalloc_obj(*new);
969 	if (!new)
970 		return new;
971 
972 	/* FIXME: hard cap on number in flight? */
973 restart_search:
974 	spin_lock(&cn->cn_lock);
975 	list_for_each_entry(tmp, &cn->cn_list, cu_list) {
976 		if (tmp->cu_u.cu_msg.cm_xid == cn->cn_xid) {
977 			cn->cn_xid++;
978 			spin_unlock(&cn->cn_lock);
979 			goto restart_search;
980 		}
981 	}
982 	init_completion(&new->cu_done);
983 	new->cu_u.cu_msg.cm_vers = nn->client_tracking_ops->version;
984 	put_unaligned(cn->cn_xid++, &new->cu_u.cu_msg.cm_xid);
985 	new->cu_net = cn;
986 	list_add(&new->cu_list, &cn->cn_list);
987 	spin_unlock(&cn->cn_lock);
988 
989 	dprintk("%s: allocated xid %u\n", __func__, new->cu_u.cu_msg.cm_xid);
990 
991 	return new;
992 }
993 
994 static void
995 free_cld_upcall(struct cld_upcall *victim)
996 {
997 	struct cld_net *cn = victim->cu_net;
998 
999 	spin_lock(&cn->cn_lock);
1000 	list_del(&victim->cu_list);
1001 	spin_unlock(&cn->cn_lock);
1002 	kfree(victim);
1003 }
1004 
1005 /* Ask daemon to create a new record */
1006 static void
1007 nfsd4_cld_create(struct nfs4_client *clp)
1008 {
1009 	int ret;
1010 	struct cld_upcall *cup;
1011 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1012 	struct cld_net *cn = nn->cld_net;
1013 
1014 	/* Don't upcall if it's already stored */
1015 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1016 		return;
1017 
1018 	cup = alloc_cld_upcall(nn);
1019 	if (!cup) {
1020 		ret = -ENOMEM;
1021 		goto out_err;
1022 	}
1023 
1024 	cup->cu_u.cu_msg.cm_cmd = Cld_Create;
1025 	cup->cu_u.cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
1026 	memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
1027 			clp->cl_name.len);
1028 
1029 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1030 	if (!ret) {
1031 		ret = cup->cu_u.cu_msg.cm_status;
1032 		set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1033 	}
1034 
1035 	free_cld_upcall(cup);
1036 out_err:
1037 	if (ret)
1038 		printk(KERN_ERR "NFSD: Unable to create client "
1039 				"record on stable storage: %d\n", ret);
1040 }
1041 
1042 /* Ask daemon to create a new record */
1043 static void
1044 nfsd4_cld_create_v2(struct nfs4_client *clp)
1045 {
1046 	int ret;
1047 	struct cld_upcall *cup;
1048 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1049 	struct cld_net *cn = nn->cld_net;
1050 	struct cld_msg_v2 *cmsg;
1051 	char *principal = NULL;
1052 
1053 	/* Don't upcall if it's already stored */
1054 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1055 		return;
1056 
1057 	cup = alloc_cld_upcall(nn);
1058 	if (!cup) {
1059 		ret = -ENOMEM;
1060 		goto out_err;
1061 	}
1062 
1063 	cmsg = &cup->cu_u.cu_msg_v2;
1064 	cmsg->cm_cmd = Cld_Create;
1065 	cmsg->cm_u.cm_clntinfo.cc_name.cn_len = clp->cl_name.len;
1066 	memcpy(cmsg->cm_u.cm_clntinfo.cc_name.cn_id, clp->cl_name.data,
1067 			clp->cl_name.len);
1068 	if (clp->cl_cred.cr_raw_principal)
1069 		principal = clp->cl_cred.cr_raw_principal;
1070 	else if (clp->cl_cred.cr_principal)
1071 		principal = clp->cl_cred.cr_principal;
1072 	if (principal) {
1073 		sha256(principal, strlen(principal),
1074 		       cmsg->cm_u.cm_clntinfo.cc_princhash.cp_data);
1075 		cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = SHA256_DIGEST_SIZE;
1076 	} else
1077 		cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0;
1078 
1079 	ret = cld_pipe_upcall(cn->cn_pipe, cmsg, nn);
1080 	if (!ret) {
1081 		ret = cmsg->cm_status;
1082 		set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1083 	}
1084 
1085 	free_cld_upcall(cup);
1086 out_err:
1087 	if (ret)
1088 		pr_err("NFSD: Unable to create client record on stable storage: %d\n",
1089 				ret);
1090 }
1091 
1092 /* Ask daemon to create a new record */
1093 static void
1094 nfsd4_cld_remove(struct nfs4_client *clp)
1095 {
1096 	int ret;
1097 	struct cld_upcall *cup;
1098 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1099 	struct cld_net *cn = nn->cld_net;
1100 
1101 	/* Don't upcall if it's already removed */
1102 	if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1103 		return;
1104 
1105 	cup = alloc_cld_upcall(nn);
1106 	if (!cup) {
1107 		ret = -ENOMEM;
1108 		goto out_err;
1109 	}
1110 
1111 	cup->cu_u.cu_msg.cm_cmd = Cld_Remove;
1112 	cup->cu_u.cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
1113 	memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
1114 			clp->cl_name.len);
1115 
1116 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1117 	if (!ret) {
1118 		ret = cup->cu_u.cu_msg.cm_status;
1119 		clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1120 	}
1121 
1122 	free_cld_upcall(cup);
1123 out_err:
1124 	if (ret)
1125 		printk(KERN_ERR "NFSD: Unable to remove client "
1126 				"record from stable storage: %d\n", ret);
1127 }
1128 
1129 /*
1130  * For older nfsdcld's that do not allow us to "slurp" the clients
1131  * from the tracking database during startup.
1132  *
1133  * Check for presence of a record, and update its timestamp
1134  */
1135 static int
1136 nfsd4_cld_check_v0(struct nfs4_client *clp)
1137 {
1138 	int ret;
1139 	struct cld_upcall *cup;
1140 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1141 	struct cld_net *cn = nn->cld_net;
1142 
1143 	/* Don't upcall if one was already stored during this grace pd */
1144 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1145 		return 0;
1146 
1147 	cup = alloc_cld_upcall(nn);
1148 	if (!cup) {
1149 		printk(KERN_ERR "NFSD: Unable to check client record on "
1150 				"stable storage: %d\n", -ENOMEM);
1151 		return -ENOMEM;
1152 	}
1153 
1154 	cup->cu_u.cu_msg.cm_cmd = Cld_Check;
1155 	cup->cu_u.cu_msg.cm_u.cm_name.cn_len = clp->cl_name.len;
1156 	memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data,
1157 			clp->cl_name.len);
1158 
1159 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1160 	if (!ret) {
1161 		ret = cup->cu_u.cu_msg.cm_status;
1162 		set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1163 	}
1164 
1165 	free_cld_upcall(cup);
1166 	return ret;
1167 }
1168 
1169 /*
1170  * For newer nfsdcld's that allow us to "slurp" the clients
1171  * from the tracking database during startup.
1172  *
1173  * Check for presence of a record in the reclaim_str_hashtbl
1174  */
1175 static int
1176 nfsd4_cld_check(struct nfs4_client *clp)
1177 {
1178 	struct nfs4_client_reclaim *crp;
1179 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1180 
1181 	/* did we already find that this client is stable? */
1182 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1183 		return 0;
1184 
1185 	/* look for it in the reclaim hashtable otherwise */
1186 	down_read(&nn->reclaim_str_hashtbl_lock);
1187 	crp = nfsd4_find_reclaim_client(clp->cl_name, nn);
1188 	if (crp)
1189 		goto found;
1190 
1191 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
1192 	if (nn->cld_net->cn_has_legacy) {
1193 		char dname[HEXDIR_LEN];
1194 		struct xdr_netobj name;
1195 
1196 		nfs4_make_rec_clidname(dname, &clp->cl_name);
1197 
1198 		name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
1199 		if (!name.data) {
1200 			dprintk("%s: failed to allocate memory for name.data!\n",
1201 				__func__);
1202 			up_read(&nn->reclaim_str_hashtbl_lock);
1203 			return -ENOENT;
1204 		}
1205 		name.len = HEXDIR_LEN;
1206 		crp = nfsd4_find_reclaim_client(name, nn);
1207 		kfree(name.data);
1208 		if (crp)
1209 			goto found;
1210 
1211 	}
1212 #endif
1213 	up_read(&nn->reclaim_str_hashtbl_lock);
1214 	return -ENOENT;
1215 found:
1216 	crp->cr_clp = clp;
1217 	up_read(&nn->reclaim_str_hashtbl_lock);
1218 	return 0;
1219 }
1220 
1221 static int
1222 nfsd4_cld_check_v2(struct nfs4_client *clp)
1223 {
1224 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1225 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
1226 	struct cld_net *cn = nn->cld_net;
1227 #endif
1228 	struct nfs4_client_reclaim *crp;
1229 	unsigned int princhashlen;
1230 	char *principal = NULL;
1231 
1232 	/* did we already find that this client is stable? */
1233 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1234 		return 0;
1235 
1236 	/* look for it in the reclaim hashtable otherwise */
1237 	down_read(&nn->reclaim_str_hashtbl_lock);
1238 	crp = nfsd4_find_reclaim_client(clp->cl_name, nn);
1239 	if (crp)
1240 		goto found;
1241 
1242 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
1243 	if (cn->cn_has_legacy) {
1244 		struct xdr_netobj name;
1245 		char dname[HEXDIR_LEN];
1246 
1247 		nfs4_make_rec_clidname(dname, &clp->cl_name);
1248 
1249 		name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
1250 		if (!name.data) {
1251 			dprintk("%s: failed to allocate memory for name.data\n",
1252 					__func__);
1253 			up_read(&nn->reclaim_str_hashtbl_lock);
1254 			return -ENOENT;
1255 		}
1256 		name.len = HEXDIR_LEN;
1257 		crp = nfsd4_find_reclaim_client(name, nn);
1258 		kfree(name.data);
1259 		if (crp)
1260 			goto found;
1261 
1262 	}
1263 #endif
1264 	up_read(&nn->reclaim_str_hashtbl_lock);
1265 	return -ENOENT;
1266 found:
1267 	princhashlen = crp->cr_princhash.len;
1268 	if (princhashlen) {
1269 		u8 digest[SHA256_DIGEST_SIZE];
1270 		u8 *pdata;
1271 
1272 		if (clp->cl_cred.cr_raw_principal)
1273 			principal = clp->cl_cred.cr_raw_principal;
1274 		else if (clp->cl_cred.cr_principal)
1275 			principal = clp->cl_cred.cr_principal;
1276 		if (principal == NULL) {
1277 			up_read(&nn->reclaim_str_hashtbl_lock);
1278 			return -ENOENT;
1279 		}
1280 		sha256(principal, strlen(principal), digest);
1281 		pdata = crp->cr_princhash.data;
1282 		if (memcmp(pdata, digest, princhashlen)) {
1283 			up_read(&nn->reclaim_str_hashtbl_lock);
1284 			return -ENOENT;
1285 		}
1286 	}
1287 	crp->cr_clp = clp;
1288 	up_read(&nn->reclaim_str_hashtbl_lock);
1289 	return 0;
1290 }
1291 
1292 static int
1293 nfsd4_cld_grace_start(struct nfsd_net *nn)
1294 {
1295 	int ret;
1296 	struct cld_upcall *cup;
1297 	struct cld_net *cn = nn->cld_net;
1298 
1299 	cup = alloc_cld_upcall(nn);
1300 	if (!cup) {
1301 		ret = -ENOMEM;
1302 		goto out_err;
1303 	}
1304 
1305 	cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart;
1306 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1307 	if (!ret)
1308 		ret = cup->cu_u.cu_msg.cm_status;
1309 
1310 	free_cld_upcall(cup);
1311 out_err:
1312 	if (ret)
1313 		dprintk("%s: Unable to get clients from userspace: %d\n",
1314 			__func__, ret);
1315 	return ret;
1316 }
1317 
1318 /* For older nfsdcld's that need cm_gracetime */
1319 static void
1320 nfsd4_cld_grace_done_v0(struct nfsd_net *nn)
1321 {
1322 	int ret;
1323 	struct cld_upcall *cup;
1324 	struct cld_net *cn = nn->cld_net;
1325 
1326 	cup = alloc_cld_upcall(nn);
1327 	if (!cup) {
1328 		ret = -ENOMEM;
1329 		goto out_err;
1330 	}
1331 
1332 	cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
1333 	cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time;
1334 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1335 	if (!ret)
1336 		ret = cup->cu_u.cu_msg.cm_status;
1337 
1338 	free_cld_upcall(cup);
1339 out_err:
1340 	if (ret)
1341 		printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
1342 }
1343 
1344 /*
1345  * For newer nfsdcld's that do not need cm_gracetime.  We also need to call
1346  * nfs4_release_reclaim() to clear out the reclaim_str_hashtbl.
1347  */
1348 static void
1349 nfsd4_cld_grace_done(struct nfsd_net *nn)
1350 {
1351 	int ret;
1352 	struct cld_upcall *cup;
1353 	struct cld_net *cn = nn->cld_net;
1354 
1355 	cup = alloc_cld_upcall(nn);
1356 	if (!cup) {
1357 		ret = -ENOMEM;
1358 		goto out_err;
1359 	}
1360 
1361 	cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
1362 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1363 	if (!ret)
1364 		ret = cup->cu_u.cu_msg.cm_status;
1365 
1366 	free_cld_upcall(cup);
1367 out_err:
1368 	nfs4_release_reclaim(nn);
1369 	if (ret)
1370 		printk(KERN_ERR "NFSD: Unable to end grace period: %d\n", ret);
1371 }
1372 
1373 static int
1374 nfs4_cld_state_init(struct net *net)
1375 {
1376 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1377 	int i;
1378 
1379 	nn->reclaim_str_hashtbl = kmalloc_objs(struct list_head,
1380 					       CLIENT_HASH_SIZE);
1381 	if (!nn->reclaim_str_hashtbl)
1382 		return -ENOMEM;
1383 
1384 	for (i = 0; i < CLIENT_HASH_SIZE; i++)
1385 		INIT_LIST_HEAD(&nn->reclaim_str_hashtbl[i]);
1386 	nn->reclaim_str_hashtbl_size = 0;
1387 	init_rwsem(&nn->reclaim_str_hashtbl_lock);
1388 	set_bit(NFSD_NET_TRACK_RECLAIM_COMPLETES, &nn->flags);
1389 	atomic_set(&nn->nr_reclaim_complete, 0);
1390 
1391 	return 0;
1392 }
1393 
1394 static void
1395 nfs4_cld_state_shutdown(struct net *net)
1396 {
1397 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1398 
1399 	clear_bit(NFSD_NET_TRACK_RECLAIM_COMPLETES, &nn->flags);
1400 	kfree(nn->reclaim_str_hashtbl);
1401 }
1402 
1403 static bool
1404 cld_running(struct nfsd_net *nn)
1405 {
1406 	struct cld_net *cn = nn->cld_net;
1407 	struct rpc_pipe *pipe = cn->cn_pipe;
1408 
1409 	return pipe->nreaders || pipe->nwriters;
1410 }
1411 
1412 static int
1413 nfsd4_cld_get_version(struct nfsd_net *nn)
1414 {
1415 	int ret = 0;
1416 	struct cld_upcall *cup;
1417 	struct cld_net *cn = nn->cld_net;
1418 	uint8_t version;
1419 
1420 	cup = alloc_cld_upcall(nn);
1421 	if (!cup) {
1422 		ret = -ENOMEM;
1423 		goto out_err;
1424 	}
1425 	cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion;
1426 	ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn);
1427 	if (!ret) {
1428 		ret = cup->cu_u.cu_msg.cm_status;
1429 		if (ret)
1430 			goto out_free;
1431 		version = cup->cu_u.cu_msg.cm_u.cm_version;
1432 		dprintk("%s: userspace returned version %u\n",
1433 				__func__, version);
1434 		if (version < 1)
1435 			version = 1;
1436 		else if (version > CLD_UPCALL_VERSION)
1437 			version = CLD_UPCALL_VERSION;
1438 
1439 		switch (version) {
1440 		case 1:
1441 			nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
1442 			break;
1443 		case 2:
1444 			nn->client_tracking_ops = &nfsd4_cld_tracking_ops_v2;
1445 			break;
1446 		default:
1447 			break;
1448 		}
1449 	}
1450 out_free:
1451 	free_cld_upcall(cup);
1452 out_err:
1453 	if (ret)
1454 		dprintk("%s: Unable to get version from userspace: %d\n",
1455 			__func__, ret);
1456 	return ret;
1457 }
1458 
1459 static int
1460 nfsd4_cld_tracking_init(struct net *net)
1461 {
1462 	int status;
1463 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1464 	bool running;
1465 	int retries = 10;
1466 
1467 	status = nfs4_cld_state_init(net);
1468 	if (status)
1469 		return status;
1470 
1471 	status = __nfsd4_init_cld_pipe(net);
1472 	if (status)
1473 		goto err_shutdown;
1474 
1475 	/*
1476 	 * rpc pipe upcalls take 30 seconds to time out, so we don't want to
1477 	 * queue an upcall unless we know that nfsdcld is running (because we
1478 	 * want this to fail fast so that nfsd4_client_tracking_init() can try
1479 	 * the next client tracking method).  nfsdcld should already be running
1480 	 * before nfsd is started, so the wait here is for nfsdcld to open the
1481 	 * pipefs file we just created.
1482 	 */
1483 	while (!(running = cld_running(nn)) && retries--)
1484 		msleep(100);
1485 
1486 	if (!running) {
1487 		status = -ETIMEDOUT;
1488 		goto err_remove;
1489 	}
1490 
1491 	status = nfsd4_cld_get_version(nn);
1492 	if (status == -EOPNOTSUPP)
1493 		pr_warn("NFSD: nfsdcld GetVersion upcall failed. Please upgrade nfsdcld.\n");
1494 
1495 	status = nfsd4_cld_grace_start(nn);
1496 	if (status) {
1497 		if (status == -EOPNOTSUPP)
1498 			pr_warn("NFSD: nfsdcld GraceStart upcall failed. Please upgrade nfsdcld.\n");
1499 		nfs4_release_reclaim(nn);
1500 		goto err_remove;
1501 	} else
1502 		pr_info("NFSD: Using nfsdcld client tracking operations.\n");
1503 	return 0;
1504 
1505 err_remove:
1506 	nfsd4_remove_cld_pipe(net);
1507 err_shutdown:
1508 	nfs4_cld_state_shutdown(net);
1509 	return status;
1510 }
1511 
1512 static void
1513 nfsd4_cld_tracking_exit(struct net *net)
1514 {
1515 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1516 
1517 	nfs4_release_reclaim(nn);
1518 	nfsd4_remove_cld_pipe(net);
1519 	nfs4_cld_state_shutdown(net);
1520 }
1521 
1522 /* For older nfsdcld's */
1523 static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v0 = {
1524 	.init		= nfsd4_init_cld_pipe,
1525 	.exit		= nfsd4_remove_cld_pipe,
1526 	.create		= nfsd4_cld_create,
1527 	.remove		= nfsd4_cld_remove,
1528 	.check		= nfsd4_cld_check_v0,
1529 	.grace_done	= nfsd4_cld_grace_done_v0,
1530 	.version	= 1,
1531 	.msglen		= sizeof(struct cld_msg),
1532 };
1533 
1534 /* For newer nfsdcld's */
1535 static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops = {
1536 	.init		= nfsd4_cld_tracking_init,
1537 	.exit		= nfsd4_cld_tracking_exit,
1538 	.create		= nfsd4_cld_create,
1539 	.remove		= nfsd4_cld_remove,
1540 	.check		= nfsd4_cld_check,
1541 	.grace_done	= nfsd4_cld_grace_done,
1542 	.version	= 1,
1543 	.msglen		= sizeof(struct cld_msg),
1544 };
1545 
1546 /* v2 create/check ops include the principal, if available */
1547 static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2 = {
1548 	.init		= nfsd4_cld_tracking_init,
1549 	.exit		= nfsd4_cld_tracking_exit,
1550 	.create		= nfsd4_cld_create_v2,
1551 	.remove		= nfsd4_cld_remove,
1552 	.check		= nfsd4_cld_check_v2,
1553 	.grace_done	= nfsd4_cld_grace_done,
1554 	.version	= 2,
1555 	.msglen		= sizeof(struct cld_msg_v2),
1556 };
1557 
1558 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
1559 /* upcall via usermodehelper */
1560 static char cltrack_prog[PATH_MAX] = "/sbin/nfsdcltrack";
1561 module_param_string(cltrack_prog, cltrack_prog, sizeof(cltrack_prog),
1562 			S_IRUGO|S_IWUSR);
1563 MODULE_PARM_DESC(cltrack_prog, "Path to the nfsdcltrack upcall program");
1564 
1565 static bool cltrack_legacy_disable;
1566 module_param(cltrack_legacy_disable, bool, S_IRUGO|S_IWUSR);
1567 MODULE_PARM_DESC(cltrack_legacy_disable,
1568 		"Disable legacy recoverydir conversion. Default: false");
1569 
1570 #define LEGACY_TOPDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_TOPDIR="
1571 #define LEGACY_RECDIR_ENV_PREFIX "NFSDCLTRACK_LEGACY_RECDIR="
1572 #define HAS_SESSION_ENV_PREFIX "NFSDCLTRACK_CLIENT_HAS_SESSION="
1573 #define GRACE_START_ENV_PREFIX "NFSDCLTRACK_GRACE_START="
1574 
1575 static char *
1576 nfsd4_cltrack_legacy_topdir(void)
1577 {
1578 	int copied;
1579 	size_t len;
1580 	char *result;
1581 
1582 	if (cltrack_legacy_disable)
1583 		return NULL;
1584 
1585 	len = strlen(LEGACY_TOPDIR_ENV_PREFIX) +
1586 		strlen(nfs4_recoverydir()) + 1;
1587 
1588 	result = kmalloc(len, GFP_KERNEL);
1589 	if (!result)
1590 		return result;
1591 
1592 	copied = snprintf(result, len, LEGACY_TOPDIR_ENV_PREFIX "%s",
1593 				nfs4_recoverydir());
1594 	if (copied >= len) {
1595 		/* just return nothing if output was truncated */
1596 		kfree(result);
1597 		return NULL;
1598 	}
1599 
1600 	return result;
1601 }
1602 
1603 static char *
1604 nfsd4_cltrack_legacy_recdir(const struct xdr_netobj *name)
1605 {
1606 	int copied;
1607 	size_t len;
1608 	char *result;
1609 
1610 	if (cltrack_legacy_disable)
1611 		return NULL;
1612 
1613 	/* +1 is for '/' between "topdir" and "recdir" */
1614 	len = strlen(LEGACY_RECDIR_ENV_PREFIX) +
1615 		strlen(nfs4_recoverydir()) + 1 + HEXDIR_LEN;
1616 
1617 	result = kmalloc(len, GFP_KERNEL);
1618 	if (!result)
1619 		return result;
1620 
1621 	copied = snprintf(result, len, LEGACY_RECDIR_ENV_PREFIX "%s/",
1622 				nfs4_recoverydir());
1623 	if (copied > (len - HEXDIR_LEN)) {
1624 		/* just return nothing if output will be truncated */
1625 		kfree(result);
1626 		return NULL;
1627 	}
1628 
1629 	nfs4_make_rec_clidname(result + copied, name);
1630 
1631 	return result;
1632 }
1633 
1634 static char *
1635 nfsd4_cltrack_client_has_session(struct nfs4_client *clp)
1636 {
1637 	int copied;
1638 	size_t len;
1639 	char *result;
1640 
1641 	/* prefix + Y/N character + terminating NULL */
1642 	len = strlen(HAS_SESSION_ENV_PREFIX) + 1 + 1;
1643 
1644 	result = kmalloc(len, GFP_KERNEL);
1645 	if (!result)
1646 		return result;
1647 
1648 	copied = snprintf(result, len, HAS_SESSION_ENV_PREFIX "%c",
1649 				clp->cl_minorversion ? 'Y' : 'N');
1650 	if (copied >= len) {
1651 		/* just return nothing if output was truncated */
1652 		kfree(result);
1653 		return NULL;
1654 	}
1655 
1656 	return result;
1657 }
1658 
1659 static char *
1660 nfsd4_cltrack_grace_start(time64_t grace_start)
1661 {
1662 	int copied;
1663 	size_t len;
1664 	char *result;
1665 
1666 	/* prefix + max width of int64_t string + terminating NULL */
1667 	len = strlen(GRACE_START_ENV_PREFIX) + 22 + 1;
1668 
1669 	result = kmalloc(len, GFP_KERNEL);
1670 	if (!result)
1671 		return result;
1672 
1673 	copied = snprintf(result, len, GRACE_START_ENV_PREFIX "%lld",
1674 				grace_start);
1675 	if (copied >= len) {
1676 		/* just return nothing if output was truncated */
1677 		kfree(result);
1678 		return NULL;
1679 	}
1680 
1681 	return result;
1682 }
1683 
1684 static int
1685 nfsd4_umh_cltrack_upcall(char *cmd, char *arg, char *env0, char *env1)
1686 {
1687 	char *envp[3];
1688 	char *argv[4];
1689 	int ret;
1690 
1691 	if (unlikely(!cltrack_prog[0])) {
1692 		dprintk("%s: cltrack_prog is disabled\n", __func__);
1693 		return -EACCES;
1694 	}
1695 
1696 	dprintk("%s: cmd: %s\n", __func__, cmd);
1697 	dprintk("%s: arg: %s\n", __func__, arg ? arg : "(null)");
1698 	dprintk("%s: env0: %s\n", __func__, env0 ? env0 : "(null)");
1699 	dprintk("%s: env1: %s\n", __func__, env1 ? env1 : "(null)");
1700 
1701 	envp[0] = env0;
1702 	envp[1] = env1;
1703 	envp[2] = NULL;
1704 
1705 	argv[0] = (char *)cltrack_prog;
1706 	argv[1] = cmd;
1707 	argv[2] = arg;
1708 	argv[3] = NULL;
1709 
1710 	ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
1711 	/*
1712 	 * Disable the upcall mechanism if we're getting an ENOENT or EACCES
1713 	 * error. The admin can re-enable it on the fly by using sysfs
1714 	 * once the problem has been fixed.
1715 	 */
1716 	if (ret == -ENOENT || ret == -EACCES) {
1717 		dprintk("NFSD: %s was not found or isn't executable (%d). "
1718 			"Setting cltrack_prog to blank string!",
1719 			cltrack_prog, ret);
1720 		cltrack_prog[0] = '\0';
1721 	}
1722 	dprintk("%s: %s return value: %d\n", __func__, cltrack_prog, ret);
1723 
1724 	return ret;
1725 }
1726 
1727 static char *
1728 bin_to_hex_dup(const unsigned char *src, int srclen)
1729 {
1730 	char *buf;
1731 
1732 	/* +1 for terminating NULL */
1733 	buf = kzalloc((srclen * 2) + 1, GFP_KERNEL);
1734 	if (!buf)
1735 		return buf;
1736 
1737 	bin2hex(buf, src, srclen);
1738 	return buf;
1739 }
1740 
1741 static int
1742 nfsd4_umh_cltrack_init(struct net *net)
1743 {
1744 	int ret;
1745 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1746 	char *grace_start = nfsd4_cltrack_grace_start(nn->boot_time);
1747 
1748 	/* XXX: The usermode helper s not working in container yet. */
1749 	if (net != &init_net) {
1750 		pr_warn("NFSD: attempt to initialize umh client tracking in a container ignored.\n");
1751 		kfree(grace_start);
1752 		return -EINVAL;
1753 	}
1754 
1755 	ret = nfsd4_umh_cltrack_upcall("init", NULL, grace_start, NULL);
1756 	kfree(grace_start);
1757 	if (!ret)
1758 		pr_info("NFSD: Using UMH upcall client tracking operations.\n");
1759 	return ret;
1760 }
1761 
1762 static void
1763 nfsd4_cltrack_upcall_lock(struct nfs4_client *clp)
1764 {
1765 	wait_on_bit_lock(&clp->cl_flags, NFSD4_CLIENT_UPCALL_LOCK,
1766 			 TASK_UNINTERRUPTIBLE);
1767 }
1768 
1769 static void
1770 nfsd4_cltrack_upcall_unlock(struct nfs4_client *clp)
1771 {
1772 	clear_and_wake_up_bit(NFSD4_CLIENT_UPCALL_LOCK, &clp->cl_flags);
1773 }
1774 
1775 static void
1776 nfsd4_umh_cltrack_create(struct nfs4_client *clp)
1777 {
1778 	char *hexid, *has_session, *grace_start;
1779 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1780 
1781 	/*
1782 	 * With v4.0 clients, there's little difference in outcome between a
1783 	 * create and check operation, and we can end up calling into this
1784 	 * function multiple times per client (once for each openowner). So,
1785 	 * for v4.0 clients skip upcalling once the client has been recorded
1786 	 * on stable storage.
1787 	 *
1788 	 * For v4.1+ clients, the outcome of the two operations is different,
1789 	 * so we must ensure that we upcall for the create operation. v4.1+
1790 	 * clients call this on RECLAIM_COMPLETE though, so we should only end
1791 	 * up doing a single create upcall per client.
1792 	 */
1793 	if (clp->cl_minorversion == 0 &&
1794 	    test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1795 		return;
1796 
1797 	hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1798 	if (!hexid) {
1799 		dprintk("%s: can't allocate memory for upcall!\n", __func__);
1800 		return;
1801 	}
1802 
1803 	has_session = nfsd4_cltrack_client_has_session(clp);
1804 	grace_start = nfsd4_cltrack_grace_start(nn->boot_time);
1805 
1806 	nfsd4_cltrack_upcall_lock(clp);
1807 	if (!nfsd4_umh_cltrack_upcall("create", hexid, has_session, grace_start))
1808 		set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1809 	nfsd4_cltrack_upcall_unlock(clp);
1810 
1811 	kfree(has_session);
1812 	kfree(grace_start);
1813 	kfree(hexid);
1814 }
1815 
1816 static void
1817 nfsd4_umh_cltrack_remove(struct nfs4_client *clp)
1818 {
1819 	char *hexid;
1820 
1821 	if (!test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1822 		return;
1823 
1824 	hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1825 	if (!hexid) {
1826 		dprintk("%s: can't allocate memory for upcall!\n", __func__);
1827 		return;
1828 	}
1829 
1830 	nfsd4_cltrack_upcall_lock(clp);
1831 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags) &&
1832 	    nfsd4_umh_cltrack_upcall("remove", hexid, NULL, NULL) == 0)
1833 		clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1834 	nfsd4_cltrack_upcall_unlock(clp);
1835 
1836 	kfree(hexid);
1837 }
1838 
1839 static int
1840 nfsd4_umh_cltrack_check(struct nfs4_client *clp)
1841 {
1842 	int ret;
1843 	char *hexid, *has_session, *legacy;
1844 
1845 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
1846 		return 0;
1847 
1848 	hexid = bin_to_hex_dup(clp->cl_name.data, clp->cl_name.len);
1849 	if (!hexid) {
1850 		dprintk("%s: can't allocate memory for upcall!\n", __func__);
1851 		return -ENOMEM;
1852 	}
1853 
1854 	has_session = nfsd4_cltrack_client_has_session(clp);
1855 	legacy = nfsd4_cltrack_legacy_recdir(&clp->cl_name);
1856 
1857 	nfsd4_cltrack_upcall_lock(clp);
1858 	if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) {
1859 		ret = 0;
1860 	} else {
1861 		ret = nfsd4_umh_cltrack_upcall("check", hexid, has_session, legacy);
1862 		if (ret == 0)
1863 			set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
1864 	}
1865 	nfsd4_cltrack_upcall_unlock(clp);
1866 	kfree(has_session);
1867 	kfree(legacy);
1868 	kfree(hexid);
1869 
1870 	return ret;
1871 }
1872 
1873 static void
1874 nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn)
1875 {
1876 	char *legacy;
1877 	char timestr[22]; /* FIXME: better way to determine max size? */
1878 
1879 	sprintf(timestr, "%lld", nn->boot_time);
1880 	legacy = nfsd4_cltrack_legacy_topdir();
1881 	nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy, NULL);
1882 	kfree(legacy);
1883 }
1884 
1885 static const struct nfsd4_client_tracking_ops nfsd4_umh_tracking_ops = {
1886 	.init		= nfsd4_umh_cltrack_init,
1887 	.exit		= NULL,
1888 	.create		= nfsd4_umh_cltrack_create,
1889 	.remove		= nfsd4_umh_cltrack_remove,
1890 	.check		= nfsd4_umh_cltrack_check,
1891 	.grace_done	= nfsd4_umh_cltrack_grace_done,
1892 	.version	= 1,
1893 	.msglen		= 0,
1894 };
1895 
1896 static inline int check_for_legacy_methods(int status, struct net *net)
1897 {
1898 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1899 	struct path path;
1900 
1901 	/*
1902 	 * Next, try the UMH upcall.
1903 	 */
1904 	nn->client_tracking_ops = &nfsd4_umh_tracking_ops;
1905 	status = nn->client_tracking_ops->init(net);
1906 	if (!status)
1907 		return status;
1908 
1909 	/*
1910 	 * Finally, See if the recoverydir exists and is a directory.
1911 	 * If it is, then use the legacy ops.
1912 	 */
1913 	nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
1914 	status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
1915 	if (!status) {
1916 		status = !d_is_dir(path.dentry);
1917 		path_put(&path);
1918 		if (status)
1919 			return -ENOTDIR;
1920 	}
1921 	return status;
1922 }
1923 #else
1924 static inline int check_for_legacy_methods(int status, struct net *net)
1925 {
1926 	return status;
1927 }
1928 #endif /* CONFIG_LEGACY_NFSD_CLIENT_TRACKING */
1929 
1930 int
1931 nfsd4_client_tracking_init(struct net *net)
1932 {
1933 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1934 	int status;
1935 
1936 	/* just run the init if it the method is already decided */
1937 	if (nn->client_tracking_ops)
1938 		goto do_init;
1939 
1940 	/* First, try to use nfsdcld */
1941 	nn->client_tracking_ops = &nfsd4_cld_tracking_ops;
1942 	status = nn->client_tracking_ops->init(net);
1943 	if (!status)
1944 		return status;
1945 	if (status != -ETIMEDOUT) {
1946 		nn->client_tracking_ops = &nfsd4_cld_tracking_ops_v0;
1947 		status = nn->client_tracking_ops->init(net);
1948 		if (!status)
1949 			return status;
1950 	}
1951 
1952 	status = check_for_legacy_methods(status, net);
1953 	if (status)
1954 		goto out;
1955 do_init:
1956 	status = nn->client_tracking_ops->init(net);
1957 out:
1958 	if (status) {
1959 		pr_warn("NFSD: Unable to initialize client recovery tracking! (%d)\n", status);
1960 		pr_warn("NFSD: Is nfsdcld running? If not, enable CONFIG_NFSD_LEGACY_CLIENT_TRACKING.\n");
1961 		nn->client_tracking_ops = NULL;
1962 	}
1963 	return status;
1964 }
1965 
1966 void
1967 nfsd4_client_tracking_exit(struct net *net)
1968 {
1969 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
1970 
1971 	if (nn->client_tracking_ops) {
1972 		if (nn->client_tracking_ops->exit)
1973 			nn->client_tracking_ops->exit(net);
1974 		nn->client_tracking_ops = NULL;
1975 	}
1976 }
1977 
1978 void
1979 nfsd4_client_record_create(struct nfs4_client *clp)
1980 {
1981 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1982 
1983 	if (nn->client_tracking_ops)
1984 		nn->client_tracking_ops->create(clp);
1985 }
1986 
1987 void
1988 nfsd4_client_record_remove(struct nfs4_client *clp)
1989 {
1990 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
1991 
1992 	if (nn->client_tracking_ops)
1993 		nn->client_tracking_ops->remove(clp);
1994 }
1995 
1996 int
1997 nfsd4_client_record_check(struct nfs4_client *clp)
1998 {
1999 	struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
2000 
2001 	if (nn->client_tracking_ops)
2002 		return nn->client_tracking_ops->check(clp);
2003 
2004 	return -EOPNOTSUPP;
2005 }
2006 
2007 void
2008 nfsd4_record_grace_done(struct nfsd_net *nn)
2009 {
2010 	if (nn->client_tracking_ops)
2011 		nn->client_tracking_ops->grace_done(nn);
2012 }
2013 
2014 static int
2015 rpc_pipefs_event(struct notifier_block *nb, unsigned long event, void *ptr)
2016 {
2017 	struct super_block *sb = ptr;
2018 	struct net *net = sb->s_fs_info;
2019 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
2020 	struct cld_net *cn = nn->cld_net;
2021 	int ret = 0;
2022 
2023 	if (!try_module_get(THIS_MODULE))
2024 		return 0;
2025 
2026 	if (!cn) {
2027 		module_put(THIS_MODULE);
2028 		return 0;
2029 	}
2030 
2031 	switch (event) {
2032 	case RPC_PIPEFS_MOUNT:
2033 		ret = nfsd4_cld_register_sb(sb, cn->cn_pipe);
2034 		break;
2035 	case RPC_PIPEFS_UMOUNT:
2036 		rpc_unlink(cn->cn_pipe);
2037 		break;
2038 	default:
2039 		ret = -ENOTSUPP;
2040 		break;
2041 	}
2042 	module_put(THIS_MODULE);
2043 	return ret;
2044 }
2045 
2046 static struct notifier_block nfsd4_cld_block = {
2047 	.notifier_call = rpc_pipefs_event,
2048 };
2049 
2050 int
2051 register_cld_notifier(void)
2052 {
2053 	WARN_ON(!nfsd_net_id);
2054 	return rpc_pipefs_notifier_register(&nfsd4_cld_block);
2055 }
2056 
2057 void
2058 unregister_cld_notifier(void)
2059 {
2060 	rpc_pipefs_notifier_unregister(&nfsd4_cld_block);
2061 }
2062