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