11 #include <linux/module.h>
14 #include <linux/nfs_fs.h>
15 #include <linux/errno.h>
29 #define NFSDBG_FACILITY NFSDBG_CALLBACK
42 static int nfs4_callback_up_net(
struct svc_serv *serv,
struct net *
net)
51 nn->nfs_callback_tcpport =
ret;
52 dprintk(
"NFS: Callback listener port = %u (af %u, net %p)\n",
53 nn->nfs_callback_tcpport,
PF_INET, net);
58 nn->nfs_callback_tcpport6 =
ret;
59 dprintk(
"NFS: Callback listener port = %u (af %u, net %p)\n",
60 nn->nfs_callback_tcpport6,
PF_INET6, net);
66 return (ret) ? ret : -
ENOMEM;
73 nfs4_callback_svc(
void *vrqstp)
96 nfs4_callback_up(
struct svc_serv *serv)
101 #if defined(CONFIG_NFS_V4_1)
102 static int nfs41_callback_up_net(
struct svc_serv *serv,
struct net *net)
117 nfs41_callback_svc(
void *vrqstp)
121 struct rpc_rqst *
req;
129 spin_lock_bh(&serv->sv_cb_lock);
130 if (!list_empty(&serv->sv_cb_list)) {
132 struct rpc_rqst, rq_bc_list);
134 spin_unlock_bh(&serv->sv_cb_lock);
135 dprintk(
"Invoking bc_svc_process()\n");
137 dprintk(
"bc_svc_process() returned w/ error code= %d\n",
140 spin_unlock_bh(&serv->sv_cb_lock);
152 nfs41_callback_up(
struct svc_serv *serv)
156 INIT_LIST_HEAD(&serv->sv_cb_list);
162 serv->sv_bc_xprt =
NULL;
164 dprintk(
"--> %s return %ld\n", __func__,
165 IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0);
169 static void nfs_minorversion_callback_svc_setup(
struct svc_serv *serv,
170 struct svc_rqst **rqstpp,
int (**callback_svc)(
void *vrqstp))
172 *rqstpp = nfs41_callback_up(serv);
173 *callback_svc = nfs41_callback_svc;
176 static inline void nfs_callback_bc_serv(
u32 minorversion,
struct rpc_xprt *xprt,
184 xprt->bc_serv = serv;
187 static int nfs41_callback_up_net(
struct svc_serv *serv,
struct net *net)
192 static void nfs_minorversion_callback_svc_setup(
struct svc_serv *serv,
193 struct svc_rqst **rqstpp,
int (**callback_svc)(
void *vrqstp))
199 static inline void nfs_callback_bc_serv(
u32 minorversion,
struct rpc_xprt *xprt,
205 static int nfs_callback_start_svc(
int minorversion,
struct rpc_xprt *xprt,
209 int (*callback_svc)(
void *vrqstp);
214 nfs_callback_bc_serv(minorversion, xprt, serv);
219 switch (minorversion) {
222 rqstp = nfs4_callback_up(serv);
223 callback_svc = nfs4_callback_svc;
226 nfs_minorversion_callback_svc_setup(serv,
227 &rqstp, &callback_svc);
231 return PTR_ERR(rqstp);
235 sprintf(svc_name,
"nfsv4.%u-svc", minorversion);
237 cb_info->
rqst = rqstp;
239 if (IS_ERR(cb_info->
task)) {
240 ret = PTR_ERR(cb_info->
task);
246 dprintk(
"nfs_callback_up: service started\n");
250 static void nfs_callback_down_net(
u32 minorversion,
struct svc_serv *serv,
struct net *net)
254 if (--nn->cb_users[minorversion])
257 dprintk(
"NFS: destroy per-net callback data; net=%p\n", net);
261 static int nfs_callback_up_net(
int minorversion,
struct svc_serv *serv,
struct net *net)
266 if (nn->cb_users[minorversion]++)
269 dprintk(
"NFS: create per-net callback data; net=%p\n", net);
277 switch (minorversion) {
279 ret = nfs4_callback_up_net(serv, net);
282 ret = nfs41_callback_up_net(serv, net);
300 dprintk(
"NFS: Couldn't create callback socket: err = %d; "
301 "net = %p\n", ret, net);
305 static struct svc_serv *nfs_callback_create_svc(
int minorversion)
318 svc_get(cb_info->
serv);
319 return cb_info->
serv;
332 printk(
KERN_ERR "nfs_callback_create_svc: create service failed\n");
339 dprintk(
"nfs_callback_create_svc: service created\n");
351 struct net *net = xprt->xprt_net;
355 serv = nfs_callback_create_svc(minorversion);
361 ret = nfs_callback_up_net(minorversion, serv, net);
365 ret = nfs_callback_start_svc(minorversion, xprt, serv);
383 nfs_callback_down_net(minorversion, serv, net);
384 dprintk(
"NFS: Couldn't create server thread; err = %d\n", ret);
396 nfs_callback_down_net(minorversion, cb_info->
serv, net);
400 dprintk(
"nfs_callback_down: service stopped\n");
402 dprintk(
"nfs_callback_down: service destroyed\n");
414 char *
p = rqstp->
rq_cred.cr_principal;
416 if (rqstp->
rq_authop->flavour != RPC_AUTH_GSS)
431 if (
memcmp(p,
"nfs@", 4) != 0)
448 static int nfs_callback_authenticate(
struct svc_rqst *rqstp)
457 if (svc_is_backchannel(rqstp))
466 static struct svc_version *nfs4_callback_version[] = {
471 static struct svc_stat nfs4_callback_stats;
473 static struct svc_program nfs4_callback_program = {
475 .pg_nvers =
ARRAY_SIZE(nfs4_callback_version),
476 .pg_vers = nfs4_callback_version,
477 .pg_name =
"NFSv4 callback",
479 .pg_stats = &nfs4_callback_stats,
480 .pg_authenticate = nfs_callback_authenticate,