2 * Copyright (c) 2004 The Regents of the University of Michigan.
3 * Copyright (c) 2012 Jeff Layton <jlayton@redhat.com>
6 * Andy Adamson <andros@citi.umich.edu>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
35 #include <linux/file.h>
36 #include <linux/slab.h>
37 #include <linux/namei.h>
38 #include <linux/crypto.h>
39 #include <linux/sched.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>
52 #define NFSDDBG_FACILITY NFSDDBG_PROC
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 net
*, time_t);
65 static struct file
*rec_file
;
66 static char user_recovery_dirname
[PATH_MAX
] = "/var/lib/nfs/v4recovery";
67 static struct nfsd4_client_tracking_ops
*client_tracking_ops
;
70 nfs4_save_creds(const struct cred
**original_creds
)
74 new = prepare_creds();
80 *original_creds
= override_creds(new);
86 nfs4_reset_creds(const struct cred
*original
)
88 revert_creds(original
);
92 md5_to_hex(char *out
, char *md5
)
96 for (i
=0; i
<16; i
++) {
97 unsigned char c
= md5
[i
];
99 *out
++ = '0' + ((c
&0xf0)>>4) + (c
>=0xa0)*('a'-'9'-1);
100 *out
++ = '0' + (c
&0x0f) + ((c
&0x0f)>=0x0a)*('a'-'9'-1);
106 nfs4_make_rec_clidname(char *dname
, struct xdr_netobj
*clname
)
108 struct xdr_netobj cksum
;
109 struct hash_desc desc
;
110 struct scatterlist sg
;
111 __be32 status
= nfserr_jukebox
;
113 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
114 clname
->len
, clname
->data
);
115 desc
.flags
= CRYPTO_TFM_REQ_MAY_SLEEP
;
116 desc
.tfm
= crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC
);
117 if (IS_ERR(desc
.tfm
))
119 cksum
.len
= crypto_hash_digestsize(desc
.tfm
);
120 cksum
.data
= kmalloc(cksum
.len
, GFP_KERNEL
);
121 if (cksum
.data
== NULL
)
124 sg_init_one(&sg
, clname
->data
, clname
->len
);
126 if (crypto_hash_digest(&desc
, &sg
, sg
.length
, cksum
.data
))
129 md5_to_hex(dname
, cksum
.data
);
134 crypto_free_hash(desc
.tfm
);
140 nfsd4_create_clid_dir(struct nfs4_client
*clp
)
142 const struct cred
*original_cred
;
143 char *dname
= clp
->cl_recdir
;
144 struct dentry
*dir
, *dentry
;
147 dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname
);
149 if (test_and_set_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
153 status
= nfs4_save_creds(&original_cred
);
157 dir
= rec_file
->f_path
.dentry
;
158 /* lock the parent */
159 mutex_lock(&dir
->d_inode
->i_mutex
);
161 dentry
= lookup_one_len(dname
, dir
, HEXDIR_LEN
-1);
162 if (IS_ERR(dentry
)) {
163 status
= PTR_ERR(dentry
);
168 * In the 4.1 case, where we're called from
169 * reclaim_complete(), records from the previous reboot
170 * may still be left, so this is OK.
172 * In the 4.0 case, we should never get here; but we may
173 * as well be forgiving and just succeed silently.
176 status
= mnt_want_write_file(rec_file
);
179 status
= vfs_mkdir(dir
->d_inode
, dentry
, S_IRWXU
);
180 mnt_drop_write_file(rec_file
);
184 mutex_unlock(&dir
->d_inode
->i_mutex
);
186 vfs_fsync(rec_file
, 0);
188 printk(KERN_ERR
"NFSD: failed to write recovery record"
189 " (err %d); please check that %s exists"
190 " and is writeable", status
,
191 user_recovery_dirname
);
192 nfs4_reset_creds(original_cred
);
195 typedef int (recdir_func
)(struct dentry
*, struct dentry
*);
198 char name
[HEXDIR_LEN
];
199 struct list_head list
;
203 nfsd4_build_namelist(void *arg
, const char *name
, int namlen
,
204 loff_t offset
, u64 ino
, unsigned int d_type
)
206 struct list_head
*names
= arg
;
207 struct name_list
*entry
;
209 if (namlen
!= HEXDIR_LEN
- 1)
211 entry
= kmalloc(sizeof(struct name_list
), GFP_KERNEL
);
214 memcpy(entry
->name
, name
, HEXDIR_LEN
- 1);
215 entry
->name
[HEXDIR_LEN
- 1] = '\0';
216 list_add(&entry
->list
, names
);
221 nfsd4_list_rec_dir(recdir_func
*f
)
223 const struct cred
*original_cred
;
224 struct dentry
*dir
= rec_file
->f_path
.dentry
;
228 status
= nfs4_save_creds(&original_cred
);
232 status
= vfs_llseek(rec_file
, 0, SEEK_SET
);
234 nfs4_reset_creds(original_cred
);
238 status
= vfs_readdir(rec_file
, nfsd4_build_namelist
, &names
);
239 mutex_lock_nested(&dir
->d_inode
->i_mutex
, I_MUTEX_PARENT
);
240 while (!list_empty(&names
)) {
241 struct name_list
*entry
;
242 entry
= list_entry(names
.next
, struct name_list
, list
);
244 struct dentry
*dentry
;
245 dentry
= lookup_one_len(entry
->name
, dir
, HEXDIR_LEN
-1);
246 if (IS_ERR(dentry
)) {
247 status
= PTR_ERR(dentry
);
250 status
= f(dir
, dentry
);
253 list_del(&entry
->list
);
256 mutex_unlock(&dir
->d_inode
->i_mutex
);
257 nfs4_reset_creds(original_cred
);
262 nfsd4_unlink_clid_dir(char *name
, int namlen
)
264 struct dentry
*dir
, *dentry
;
267 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen
, name
);
269 dir
= rec_file
->f_path
.dentry
;
270 mutex_lock_nested(&dir
->d_inode
->i_mutex
, I_MUTEX_PARENT
);
271 dentry
= lookup_one_len(name
, dir
, namlen
);
272 if (IS_ERR(dentry
)) {
273 status
= PTR_ERR(dentry
);
277 if (!dentry
->d_inode
)
279 status
= vfs_rmdir(dir
->d_inode
, dentry
);
283 mutex_unlock(&dir
->d_inode
->i_mutex
);
288 nfsd4_remove_clid_dir(struct nfs4_client
*clp
)
290 const struct cred
*original_cred
;
293 if (!rec_file
|| !test_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
296 status
= mnt_want_write_file(rec_file
);
299 clear_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
);
301 status
= nfs4_save_creds(&original_cred
);
305 status
= nfsd4_unlink_clid_dir(clp
->cl_recdir
, HEXDIR_LEN
-1);
306 nfs4_reset_creds(original_cred
);
308 vfs_fsync(rec_file
, 0);
309 mnt_drop_write_file(rec_file
);
312 printk("NFSD: Failed to remove expired client state directory"
313 " %.*s\n", HEXDIR_LEN
, clp
->cl_recdir
);
317 purge_old(struct dentry
*parent
, struct dentry
*child
)
321 if (nfs4_has_reclaimed_state(child
->d_name
.name
, false))
324 status
= vfs_rmdir(parent
->d_inode
, child
);
326 printk("failed to remove client recovery directory %s\n",
328 /* Keep trying, success or failure: */
333 nfsd4_recdir_purge_old(struct net
*net
, time_t boot_time
)
339 status
= mnt_want_write_file(rec_file
);
342 status
= nfsd4_list_rec_dir(purge_old
);
344 vfs_fsync(rec_file
, 0);
345 mnt_drop_write_file(rec_file
);
348 printk("nfsd4: failed to purge old clients from recovery"
349 " directory %s\n", rec_file
->f_path
.dentry
->d_name
.name
);
353 load_recdir(struct dentry
*parent
, struct dentry
*child
)
355 if (child
->d_name
.len
!= HEXDIR_LEN
- 1) {
356 printk("nfsd4: illegal name %s in recovery directory\n",
358 /* Keep trying; maybe the others are OK: */
361 nfs4_client_to_reclaim(child
->d_name
.name
);
366 nfsd4_recdir_load(void) {
372 status
= nfsd4_list_rec_dir(load_recdir
);
374 printk("nfsd4: failed loading clients from recovery"
375 " directory %s\n", rec_file
->f_path
.dentry
->d_name
.name
);
380 * Hold reference to the recovery directory.
384 nfsd4_init_recdir(void)
386 const struct cred
*original_cred
;
389 printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
390 user_recovery_dirname
);
394 status
= nfs4_save_creds(&original_cred
);
396 printk("NFSD: Unable to change credentials to find recovery"
397 " directory: error %d\n",
402 rec_file
= filp_open(user_recovery_dirname
, O_RDONLY
| O_DIRECTORY
, 0);
403 if (IS_ERR(rec_file
)) {
404 printk("NFSD: unable to find recovery directory %s\n",
405 user_recovery_dirname
);
406 status
= PTR_ERR(rec_file
);
410 nfs4_reset_creds(original_cred
);
415 nfsd4_load_reboot_recovery_data(struct net
*net
)
419 /* XXX: The legacy code won't work in a container */
420 if (net
!= &init_net
) {
421 WARN(1, KERN_ERR
"NFSD: attempt to initialize legacy client "
422 "tracking in a container!\n");
427 status
= nfsd4_init_recdir();
429 status
= nfsd4_recdir_load();
432 printk(KERN_ERR
"NFSD: Failure reading reboot recovery data\n");
437 nfsd4_shutdown_recdir(void)
446 nfsd4_legacy_tracking_exit(struct net
*net
)
448 nfs4_release_reclaim();
449 nfsd4_shutdown_recdir();
453 * Change the NFSv4 recovery directory to recdir.
456 nfs4_reset_recoverydir(char *recdir
)
461 status
= kern_path(recdir
, LOOKUP_FOLLOW
, &path
);
465 if (S_ISDIR(path
.dentry
->d_inode
->i_mode
)) {
466 strcpy(user_recovery_dirname
, recdir
);
474 nfs4_recoverydir(void)
476 return user_recovery_dirname
;
480 nfsd4_check_legacy_client(struct nfs4_client
*clp
)
482 /* did we already find that this client is stable? */
483 if (test_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
486 /* look for it in the reclaim hashtable otherwise */
487 if (nfsd4_find_reclaim_client(clp
)) {
488 set_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
);
495 static struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops
= {
496 .init
= nfsd4_load_reboot_recovery_data
,
497 .exit
= nfsd4_legacy_tracking_exit
,
498 .create
= nfsd4_create_clid_dir
,
499 .remove
= nfsd4_remove_clid_dir
,
500 .check
= nfsd4_check_legacy_client
,
501 .grace_done
= nfsd4_recdir_purge_old
,
505 #define NFSD_PIPE_DIR "nfsd"
506 #define NFSD_CLD_PIPE "cld"
508 /* per-net-ns structure for holding cld upcall info */
510 struct rpc_pipe
*cn_pipe
;
512 struct list_head cn_list
;
517 struct list_head cu_list
;
518 struct cld_net
*cu_net
;
519 struct task_struct
*cu_task
;
520 struct cld_msg cu_msg
;
524 __cld_pipe_upcall(struct rpc_pipe
*pipe
, struct cld_msg
*cmsg
)
527 struct rpc_pipe_msg msg
;
529 memset(&msg
, 0, sizeof(msg
));
531 msg
.len
= sizeof(*cmsg
);
534 * Set task state before we queue the upcall. That prevents
535 * wake_up_process in the downcall from racing with schedule.
537 set_current_state(TASK_UNINTERRUPTIBLE
);
538 ret
= rpc_queue_upcall(pipe
, &msg
);
540 set_current_state(TASK_RUNNING
);
545 set_current_state(TASK_RUNNING
);
554 cld_pipe_upcall(struct rpc_pipe
*pipe
, struct cld_msg
*cmsg
)
559 * -EAGAIN occurs when pipe is closed and reopened while there are
563 ret
= __cld_pipe_upcall(pipe
, cmsg
);
564 } while (ret
== -EAGAIN
);
570 cld_pipe_downcall(struct file
*filp
, const char __user
*src
, size_t mlen
)
572 struct cld_upcall
*tmp
, *cup
;
573 struct cld_msg
*cmsg
= (struct cld_msg
*)src
;
575 struct nfsd_net
*nn
= net_generic(filp
->f_dentry
->d_sb
->s_fs_info
,
577 struct cld_net
*cn
= nn
->cld_net
;
579 if (mlen
!= sizeof(*cmsg
)) {
580 dprintk("%s: got %zu bytes, expected %zu\n", __func__
, mlen
,
585 /* copy just the xid so we can try to find that */
586 if (copy_from_user(&xid
, &cmsg
->cm_xid
, sizeof(xid
)) != 0) {
587 dprintk("%s: error when copying xid from userspace", __func__
);
591 /* walk the list and find corresponding xid */
593 spin_lock(&cn
->cn_lock
);
594 list_for_each_entry(tmp
, &cn
->cn_list
, cu_list
) {
595 if (get_unaligned(&tmp
->cu_msg
.cm_xid
) == xid
) {
597 list_del_init(&cup
->cu_list
);
601 spin_unlock(&cn
->cn_lock
);
603 /* couldn't find upcall? */
605 dprintk("%s: couldn't find upcall -- xid=%u\n", __func__
, xid
);
609 if (copy_from_user(&cup
->cu_msg
, src
, mlen
) != 0)
612 wake_up_process(cup
->cu_task
);
617 cld_pipe_destroy_msg(struct rpc_pipe_msg
*msg
)
619 struct cld_msg
*cmsg
= msg
->data
;
620 struct cld_upcall
*cup
= container_of(cmsg
, struct cld_upcall
,
623 /* errno >= 0 means we got a downcall */
627 wake_up_process(cup
->cu_task
);
630 static const struct rpc_pipe_ops cld_upcall_ops
= {
631 .upcall
= rpc_pipe_generic_upcall
,
632 .downcall
= cld_pipe_downcall
,
633 .destroy_msg
= cld_pipe_destroy_msg
,
636 static struct dentry
*
637 nfsd4_cld_register_sb(struct super_block
*sb
, struct rpc_pipe
*pipe
)
639 struct dentry
*dir
, *dentry
;
641 dir
= rpc_d_lookup_sb(sb
, NFSD_PIPE_DIR
);
643 return ERR_PTR(-ENOENT
);
644 dentry
= rpc_mkpipe_dentry(dir
, NFSD_CLD_PIPE
, NULL
, pipe
);
650 nfsd4_cld_unregister_sb(struct rpc_pipe
*pipe
)
653 rpc_unlink(pipe
->dentry
);
656 static struct dentry
*
657 nfsd4_cld_register_net(struct net
*net
, struct rpc_pipe
*pipe
)
659 struct super_block
*sb
;
660 struct dentry
*dentry
;
662 sb
= rpc_get_sb_net(net
);
665 dentry
= nfsd4_cld_register_sb(sb
, pipe
);
671 nfsd4_cld_unregister_net(struct net
*net
, struct rpc_pipe
*pipe
)
673 struct super_block
*sb
;
675 sb
= rpc_get_sb_net(net
);
677 nfsd4_cld_unregister_sb(pipe
);
682 /* Initialize rpc_pipefs pipe for communication with client tracking daemon */
684 nfsd4_init_cld_pipe(struct net
*net
)
687 struct dentry
*dentry
;
688 struct nfsd_net
*nn
= net_generic(net
, nfsd_net_id
);
694 cn
= kzalloc(sizeof(*cn
), GFP_KERNEL
);
700 cn
->cn_pipe
= rpc_mkpipe_data(&cld_upcall_ops
, RPC_PIPE_WAIT_FOR_OPEN
);
701 if (IS_ERR(cn
->cn_pipe
)) {
702 ret
= PTR_ERR(cn
->cn_pipe
);
705 spin_lock_init(&cn
->cn_lock
);
706 INIT_LIST_HEAD(&cn
->cn_list
);
708 dentry
= nfsd4_cld_register_net(net
, cn
->cn_pipe
);
709 if (IS_ERR(dentry
)) {
710 ret
= PTR_ERR(dentry
);
711 goto err_destroy_data
;
714 cn
->cn_pipe
->dentry
= dentry
;
719 rpc_destroy_pipe_data(cn
->cn_pipe
);
722 printk(KERN_ERR
"NFSD: unable to create nfsdcld upcall pipe (%d)\n",
728 nfsd4_remove_cld_pipe(struct net
*net
)
730 struct nfsd_net
*nn
= net_generic(net
, nfsd_net_id
);
731 struct cld_net
*cn
= nn
->cld_net
;
733 nfsd4_cld_unregister_net(net
, cn
->cn_pipe
);
734 rpc_destroy_pipe_data(cn
->cn_pipe
);
739 static struct cld_upcall
*
740 alloc_cld_upcall(struct cld_net
*cn
)
742 struct cld_upcall
*new, *tmp
;
744 new = kzalloc(sizeof(*new), GFP_KERNEL
);
748 /* FIXME: hard cap on number in flight? */
750 spin_lock(&cn
->cn_lock
);
751 list_for_each_entry(tmp
, &cn
->cn_list
, cu_list
) {
752 if (tmp
->cu_msg
.cm_xid
== cn
->cn_xid
) {
754 spin_unlock(&cn
->cn_lock
);
758 new->cu_task
= current
;
759 new->cu_msg
.cm_vers
= CLD_UPCALL_VERSION
;
760 put_unaligned(cn
->cn_xid
++, &new->cu_msg
.cm_xid
);
762 list_add(&new->cu_list
, &cn
->cn_list
);
763 spin_unlock(&cn
->cn_lock
);
765 dprintk("%s: allocated xid %u\n", __func__
, new->cu_msg
.cm_xid
);
771 free_cld_upcall(struct cld_upcall
*victim
)
773 struct cld_net
*cn
= victim
->cu_net
;
775 spin_lock(&cn
->cn_lock
);
776 list_del(&victim
->cu_list
);
777 spin_unlock(&cn
->cn_lock
);
781 /* Ask daemon to create a new record */
783 nfsd4_cld_create(struct nfs4_client
*clp
)
786 struct cld_upcall
*cup
;
787 /* FIXME: determine net from clp */
788 struct nfsd_net
*nn
= net_generic(&init_net
, nfsd_net_id
);
789 struct cld_net
*cn
= nn
->cld_net
;
791 /* Don't upcall if it's already stored */
792 if (test_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
795 cup
= alloc_cld_upcall(cn
);
801 cup
->cu_msg
.cm_cmd
= Cld_Create
;
802 cup
->cu_msg
.cm_u
.cm_name
.cn_len
= clp
->cl_name
.len
;
803 memcpy(cup
->cu_msg
.cm_u
.cm_name
.cn_id
, clp
->cl_name
.data
,
806 ret
= cld_pipe_upcall(cn
->cn_pipe
, &cup
->cu_msg
);
808 ret
= cup
->cu_msg
.cm_status
;
809 set_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
);
812 free_cld_upcall(cup
);
815 printk(KERN_ERR
"NFSD: Unable to create client "
816 "record on stable storage: %d\n", ret
);
819 /* Ask daemon to create a new record */
821 nfsd4_cld_remove(struct nfs4_client
*clp
)
824 struct cld_upcall
*cup
;
825 /* FIXME: determine net from clp */
826 struct nfsd_net
*nn
= net_generic(&init_net
, nfsd_net_id
);
827 struct cld_net
*cn
= nn
->cld_net
;
829 /* Don't upcall if it's already removed */
830 if (!test_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
833 cup
= alloc_cld_upcall(cn
);
839 cup
->cu_msg
.cm_cmd
= Cld_Remove
;
840 cup
->cu_msg
.cm_u
.cm_name
.cn_len
= clp
->cl_name
.len
;
841 memcpy(cup
->cu_msg
.cm_u
.cm_name
.cn_id
, clp
->cl_name
.data
,
844 ret
= cld_pipe_upcall(cn
->cn_pipe
, &cup
->cu_msg
);
846 ret
= cup
->cu_msg
.cm_status
;
847 clear_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
);
850 free_cld_upcall(cup
);
853 printk(KERN_ERR
"NFSD: Unable to remove client "
854 "record from stable storage: %d\n", ret
);
857 /* Check for presence of a record, and update its timestamp */
859 nfsd4_cld_check(struct nfs4_client
*clp
)
862 struct cld_upcall
*cup
;
863 /* FIXME: determine net from clp */
864 struct nfsd_net
*nn
= net_generic(&init_net
, nfsd_net_id
);
865 struct cld_net
*cn
= nn
->cld_net
;
867 /* Don't upcall if one was already stored during this grace pd */
868 if (test_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
))
871 cup
= alloc_cld_upcall(cn
);
873 printk(KERN_ERR
"NFSD: Unable to check client record on "
874 "stable storage: %d\n", -ENOMEM
);
878 cup
->cu_msg
.cm_cmd
= Cld_Check
;
879 cup
->cu_msg
.cm_u
.cm_name
.cn_len
= clp
->cl_name
.len
;
880 memcpy(cup
->cu_msg
.cm_u
.cm_name
.cn_id
, clp
->cl_name
.data
,
883 ret
= cld_pipe_upcall(cn
->cn_pipe
, &cup
->cu_msg
);
885 ret
= cup
->cu_msg
.cm_status
;
886 set_bit(NFSD4_CLIENT_STABLE
, &clp
->cl_flags
);
889 free_cld_upcall(cup
);
894 nfsd4_cld_grace_done(struct net
*net
, time_t boot_time
)
897 struct cld_upcall
*cup
;
898 struct nfsd_net
*nn
= net_generic(net
, nfsd_net_id
);
899 struct cld_net
*cn
= nn
->cld_net
;
901 cup
= alloc_cld_upcall(cn
);
907 cup
->cu_msg
.cm_cmd
= Cld_GraceDone
;
908 cup
->cu_msg
.cm_u
.cm_gracetime
= (int64_t)boot_time
;
909 ret
= cld_pipe_upcall(cn
->cn_pipe
, &cup
->cu_msg
);
911 ret
= cup
->cu_msg
.cm_status
;
913 free_cld_upcall(cup
);
916 printk(KERN_ERR
"NFSD: Unable to end grace period: %d\n", ret
);
919 static struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops
= {
920 .init
= nfsd4_init_cld_pipe
,
921 .exit
= nfsd4_remove_cld_pipe
,
922 .create
= nfsd4_cld_create
,
923 .remove
= nfsd4_cld_remove
,
924 .check
= nfsd4_cld_check
,
925 .grace_done
= nfsd4_cld_grace_done
,
929 nfsd4_client_tracking_init(struct net
*net
)
934 if (!client_tracking_ops
) {
935 client_tracking_ops
= &nfsd4_cld_tracking_ops
;
936 status
= kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW
, &path
);
938 if (S_ISDIR(path
.dentry
->d_inode
->i_mode
))
939 client_tracking_ops
=
940 &nfsd4_legacy_tracking_ops
;
945 status
= client_tracking_ops
->init(net
);
947 printk(KERN_WARNING
"NFSD: Unable to initialize client "
948 "recovery tracking! (%d)\n", status
);
949 client_tracking_ops
= NULL
;
955 nfsd4_client_tracking_exit(struct net
*net
)
957 if (client_tracking_ops
) {
958 client_tracking_ops
->exit(net
);
959 client_tracking_ops
= NULL
;
964 nfsd4_client_record_create(struct nfs4_client
*clp
)
966 if (client_tracking_ops
)
967 client_tracking_ops
->create(clp
);
971 nfsd4_client_record_remove(struct nfs4_client
*clp
)
973 if (client_tracking_ops
)
974 client_tracking_ops
->remove(clp
);
978 nfsd4_client_record_check(struct nfs4_client
*clp
)
980 if (client_tracking_ops
)
981 return client_tracking_ops
->check(clp
);
987 nfsd4_record_grace_done(struct net
*net
, time_t boot_time
)
989 if (client_tracking_ops
)
990 client_tracking_ops
->grace_done(net
, boot_time
);
994 rpc_pipefs_event(struct notifier_block
*nb
, unsigned long event
, void *ptr
)
996 struct super_block
*sb
= ptr
;
997 struct net
*net
= sb
->s_fs_info
;
998 struct nfsd_net
*nn
= net_generic(net
, nfsd_net_id
);
999 struct cld_net
*cn
= nn
->cld_net
;
1000 struct dentry
*dentry
;
1003 if (!try_module_get(THIS_MODULE
))
1007 module_put(THIS_MODULE
);
1012 case RPC_PIPEFS_MOUNT
:
1013 dentry
= nfsd4_cld_register_sb(sb
, cn
->cn_pipe
);
1014 if (IS_ERR(dentry
)) {
1015 ret
= PTR_ERR(dentry
);
1018 cn
->cn_pipe
->dentry
= dentry
;
1020 case RPC_PIPEFS_UMOUNT
:
1021 if (cn
->cn_pipe
->dentry
)
1022 nfsd4_cld_unregister_sb(cn
->cn_pipe
);
1028 module_put(THIS_MODULE
);
1032 struct notifier_block nfsd4_cld_block
= {
1033 .notifier_call
= rpc_pipefs_event
,
1037 register_cld_notifier(void)
1039 return rpc_pipefs_notifier_register(&nfsd4_cld_block
);
1043 unregister_cld_notifier(void)
1045 rpc_pipefs_notifier_unregister(&nfsd4_cld_block
);