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