2 * Copyright (c) 2006,2007 The Regents of the University of Michigan.
5 * Andy Adamson <andros@citi.umich.edu>
6 * Fred Isaman <iisaman@umich.edu>
8 * permission is granted to use, copy, create derivative works and
9 * redistribute this software and such derivative works for any purpose,
10 * so long as the name of the university of michigan is not used in
11 * any advertising or publicity pertaining to the use or distribution
12 * of this software without specific, written prior authorization. if
13 * the above copyright notice or any other identification of the
14 * university of michigan is included in any copy of any portion of
15 * this software, then the disclaimer below must also be included.
17 * this software is provided as is, without representation from the
18 * university of michigan as to its fitness for any purpose, and without
19 * warranty by the university of michigan of any kind, either express
20 * or implied, including without limitation the implied warranties of
21 * merchantability and fitness for a particular purpose. the regents
22 * of the university of michigan shall not be liable for any damages,
23 * including special, indirect, incidental, or consequential damages,
24 * with respect to any claim arising out or in connection with the use
25 * of the software, even if it has been or is hereafter advised of the
26 * possibility of such damages.
29 #include <linux/module.h>
30 #include <linux/blkdev.h>
32 #include "blocklayout.h"
34 #define NFSDBG_FACILITY NFSDBG_PNFS_LD
37 nfs4_encode_simple(__be32
*p
, struct pnfs_block_volume
*b
)
41 *p
++ = cpu_to_be32(1);
42 *p
++ = cpu_to_be32(b
->type
);
43 *p
++ = cpu_to_be32(b
->simple
.nr_sigs
);
44 for (i
= 0; i
< b
->simple
.nr_sigs
; i
++) {
45 p
= xdr_encode_hyper(p
, b
->simple
.sigs
[i
].offset
);
46 p
= xdr_encode_opaque(p
, b
->simple
.sigs
[i
].sig
,
47 b
->simple
.sigs
[i
].sig_len
);
52 bl_resolve_deviceid(struct nfs_server
*server
, struct pnfs_block_volume
*b
,
55 struct net
*net
= server
->nfs_client
->cl_net
;
56 struct nfs_net
*nn
= net_generic(net
, nfs_net_id
);
57 struct bl_dev_msg
*reply
= &nn
->bl_mount_reply
;
58 struct bl_pipe_msg bl_pipe_msg
;
59 struct rpc_pipe_msg
*msg
= &bl_pipe_msg
.msg
;
60 struct bl_msg_hdr
*bl_msg
;
61 DECLARE_WAITQUEUE(wq
, current
);
65 dprintk("%s CREATING PIPEFS MESSAGE\n", __func__
);
67 mutex_lock(&nn
->bl_mutex
);
68 bl_pipe_msg
.bl_wq
= &nn
->bl_wq
;
70 b
->simple
.len
+= 4; /* single volume */
71 if (b
->simple
.len
> PAGE_SIZE
)
74 memset(msg
, 0, sizeof(*msg
));
75 msg
->len
= sizeof(*bl_msg
) + b
->simple
.len
;
76 msg
->data
= kzalloc(msg
->len
, gfp_mask
);
81 bl_msg
->type
= BL_DEVICE_MOUNT
;
82 bl_msg
->totallen
= b
->simple
.len
;
83 nfs4_encode_simple(msg
->data
+ sizeof(*bl_msg
), b
);
85 dprintk("%s CALLING USERSPACE DAEMON\n", __func__
);
86 add_wait_queue(&nn
->bl_wq
, &wq
);
87 rc
= rpc_queue_upcall(nn
->bl_device_pipe
, msg
);
89 remove_wait_queue(&nn
->bl_wq
, &wq
);
93 set_current_state(TASK_UNINTERRUPTIBLE
);
95 remove_wait_queue(&nn
->bl_wq
, &wq
);
97 if (reply
->status
!= BL_DEVICE_REQUEST_PROC
) {
98 printk(KERN_WARNING
"%s failed to decode device: %d\n",
99 __func__
, reply
->status
);
103 dev
= MKDEV(reply
->major
, reply
->minor
);
107 mutex_unlock(&nn
->bl_mutex
);
111 static ssize_t
bl_pipe_downcall(struct file
*filp
, const char __user
*src
,
114 struct nfs_net
*nn
= net_generic(file_inode(filp
)->i_sb
->s_fs_info
,
117 if (mlen
!= sizeof (struct bl_dev_msg
))
120 if (copy_from_user(&nn
->bl_mount_reply
, src
, mlen
) != 0)
128 static void bl_pipe_destroy_msg(struct rpc_pipe_msg
*msg
)
130 struct bl_pipe_msg
*bl_pipe_msg
=
131 container_of(msg
, struct bl_pipe_msg
, msg
);
135 wake_up(bl_pipe_msg
->bl_wq
);
138 static const struct rpc_pipe_ops bl_upcall_ops
= {
139 .upcall
= rpc_pipe_generic_upcall
,
140 .downcall
= bl_pipe_downcall
,
141 .destroy_msg
= bl_pipe_destroy_msg
,
144 static struct dentry
*nfs4blocklayout_register_sb(struct super_block
*sb
,
145 struct rpc_pipe
*pipe
)
147 struct dentry
*dir
, *dentry
;
149 dir
= rpc_d_lookup_sb(sb
, NFS_PIPE_DIRNAME
);
151 return ERR_PTR(-ENOENT
);
152 dentry
= rpc_mkpipe_dentry(dir
, "blocklayout", NULL
, pipe
);
157 static void nfs4blocklayout_unregister_sb(struct super_block
*sb
,
158 struct rpc_pipe
*pipe
)
161 rpc_unlink(pipe
->dentry
);
164 static int rpc_pipefs_event(struct notifier_block
*nb
, unsigned long event
,
167 struct super_block
*sb
= ptr
;
168 struct net
*net
= sb
->s_fs_info
;
169 struct nfs_net
*nn
= net_generic(net
, nfs_net_id
);
170 struct dentry
*dentry
;
173 if (!try_module_get(THIS_MODULE
))
176 if (nn
->bl_device_pipe
== NULL
) {
177 module_put(THIS_MODULE
);
182 case RPC_PIPEFS_MOUNT
:
183 dentry
= nfs4blocklayout_register_sb(sb
, nn
->bl_device_pipe
);
184 if (IS_ERR(dentry
)) {
185 ret
= PTR_ERR(dentry
);
188 nn
->bl_device_pipe
->dentry
= dentry
;
190 case RPC_PIPEFS_UMOUNT
:
191 if (nn
->bl_device_pipe
->dentry
)
192 nfs4blocklayout_unregister_sb(sb
, nn
->bl_device_pipe
);
198 module_put(THIS_MODULE
);
202 static struct notifier_block nfs4blocklayout_block
= {
203 .notifier_call
= rpc_pipefs_event
,
206 static struct dentry
*nfs4blocklayout_register_net(struct net
*net
,
207 struct rpc_pipe
*pipe
)
209 struct super_block
*pipefs_sb
;
210 struct dentry
*dentry
;
212 pipefs_sb
= rpc_get_sb_net(net
);
215 dentry
= nfs4blocklayout_register_sb(pipefs_sb
, pipe
);
220 static void nfs4blocklayout_unregister_net(struct net
*net
,
221 struct rpc_pipe
*pipe
)
223 struct super_block
*pipefs_sb
;
225 pipefs_sb
= rpc_get_sb_net(net
);
227 nfs4blocklayout_unregister_sb(pipefs_sb
, pipe
);
232 static int nfs4blocklayout_net_init(struct net
*net
)
234 struct nfs_net
*nn
= net_generic(net
, nfs_net_id
);
235 struct dentry
*dentry
;
237 mutex_init(&nn
->bl_mutex
);
238 init_waitqueue_head(&nn
->bl_wq
);
239 nn
->bl_device_pipe
= rpc_mkpipe_data(&bl_upcall_ops
, 0);
240 if (IS_ERR(nn
->bl_device_pipe
))
241 return PTR_ERR(nn
->bl_device_pipe
);
242 dentry
= nfs4blocklayout_register_net(net
, nn
->bl_device_pipe
);
243 if (IS_ERR(dentry
)) {
244 rpc_destroy_pipe_data(nn
->bl_device_pipe
);
245 return PTR_ERR(dentry
);
247 nn
->bl_device_pipe
->dentry
= dentry
;
251 static void nfs4blocklayout_net_exit(struct net
*net
)
253 struct nfs_net
*nn
= net_generic(net
, nfs_net_id
);
255 nfs4blocklayout_unregister_net(net
, nn
->bl_device_pipe
);
256 rpc_destroy_pipe_data(nn
->bl_device_pipe
);
257 nn
->bl_device_pipe
= NULL
;
260 static struct pernet_operations nfs4blocklayout_net_ops
= {
261 .init
= nfs4blocklayout_net_init
,
262 .exit
= nfs4blocklayout_net_exit
,
265 int __init
bl_init_pipefs(void)
269 ret
= rpc_pipefs_notifier_register(&nfs4blocklayout_block
);
272 ret
= register_pernet_subsys(&nfs4blocklayout_net_ops
);
274 goto out_unregister_notifier
;
277 out_unregister_notifier
:
278 rpc_pipefs_notifier_unregister(&nfs4blocklayout_block
);
283 void bl_cleanup_pipefs(void)
285 rpc_pipefs_notifier_unregister(&nfs4blocklayout_block
);
286 unregister_pernet_subsys(&nfs4blocklayout_net_ops
);