1 /* 2 * linux/fs/nfs/callback.c 3 * 4 * Copyright (C) 2004 Trond Myklebust 5 * 6 * NFSv4 callback handling 7 */ 8 9 #include <linux/completion.h> 10 #include <linux/ip.h> 11 #include <linux/module.h> 12 #include <linux/sunrpc/svc.h> 13 #include <linux/sunrpc/svcsock.h> 14 #include <linux/nfs_fs.h> 15 #include <linux/errno.h> 16 #include <linux/mutex.h> 17 #include <linux/freezer.h> 18 #include <linux/kthread.h> 19 #include <linux/sunrpc/svcauth_gss.h> 20 #include <linux/sunrpc/bc_xprt.h> 21 22 #include <net/inet_sock.h> 23 24 #include "nfs4_fs.h" 25 #include "callback.h" 26 #include "internal.h" 27 #include "netns.h" 28 29 #define NFSDBG_FACILITY NFSDBG_CALLBACK 30 31 struct nfs_callback_data { 32 unsigned int users; 33 struct svc_serv *serv; 34 struct svc_rqst *rqst; 35 struct task_struct *task; 36 }; 37 38 static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1]; 39 static DEFINE_MUTEX(nfs_callback_mutex); 40 static struct svc_program nfs4_callback_program; 41 42 static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net) 43 { 44 int ret; 45 struct nfs_net *nn = net_generic(net, nfs_net_id); 46 47 ret = svc_create_xprt(serv, "tcp", net, PF_INET, 48 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 49 if (ret <= 0) 50 goto out_err; 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); 54 55 ret = svc_create_xprt(serv, "tcp", net, PF_INET6, 56 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 57 if (ret > 0) { 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); 61 } else if (ret != -EAFNOSUPPORT) 62 goto out_err; 63 return 0; 64 65 out_err: 66 return (ret) ? ret : -ENOMEM; 67 } 68 69 /* 70 * This is the NFSv4 callback kernel thread. 71 */ 72 static int 73 nfs4_callback_svc(void *vrqstp) 74 { 75 int err; 76 struct svc_rqst *rqstp = vrqstp; 77 78 set_freezable(); 79 80 while (!kthread_should_stop()) { 81 /* 82 * Listen for a request on the socket 83 */ 84 err = svc_recv(rqstp, MAX_SCHEDULE_TIMEOUT); 85 if (err == -EAGAIN || err == -EINTR) 86 continue; 87 svc_process(rqstp); 88 } 89 return 0; 90 } 91 92 /* 93 * Prepare to bring up the NFSv4 callback service 94 */ 95 static struct svc_rqst * 96 nfs4_callback_up(struct svc_serv *serv) 97 { 98 return svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 99 } 100 101 #if defined(CONFIG_NFS_V4_1) 102 static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net) 103 { 104 /* 105 * Create an svc_sock for the back channel service that shares the 106 * fore channel connection. 107 * Returns the input port (0) and sets the svc_serv bc_xprt on success 108 */ 109 return svc_create_xprt(serv, "tcp-bc", net, PF_INET, 0, 110 SVC_SOCK_ANONYMOUS); 111 } 112 113 /* 114 * The callback service for NFSv4.1 callbacks 115 */ 116 static int 117 nfs41_callback_svc(void *vrqstp) 118 { 119 struct svc_rqst *rqstp = vrqstp; 120 struct svc_serv *serv = rqstp->rq_server; 121 struct rpc_rqst *req; 122 int error; 123 DEFINE_WAIT(wq); 124 125 set_freezable(); 126 127 while (!kthread_should_stop()) { 128 if (try_to_freeze()) 129 continue; 130 131 prepare_to_wait(&serv->sv_cb_waitq, &wq, TASK_INTERRUPTIBLE); 132 spin_lock_bh(&serv->sv_cb_lock); 133 if (!list_empty(&serv->sv_cb_list)) { 134 req = list_first_entry(&serv->sv_cb_list, 135 struct rpc_rqst, rq_bc_list); 136 list_del(&req->rq_bc_list); 137 spin_unlock_bh(&serv->sv_cb_lock); 138 dprintk("Invoking bc_svc_process()\n"); 139 error = bc_svc_process(serv, req, rqstp); 140 dprintk("bc_svc_process() returned w/ error code= %d\n", 141 error); 142 } else { 143 spin_unlock_bh(&serv->sv_cb_lock); 144 schedule(); 145 } 146 finish_wait(&serv->sv_cb_waitq, &wq); 147 } 148 return 0; 149 } 150 151 /* 152 * Bring up the NFSv4.1 callback service 153 */ 154 static struct svc_rqst * 155 nfs41_callback_up(struct svc_serv *serv) 156 { 157 struct svc_rqst *rqstp; 158 159 INIT_LIST_HEAD(&serv->sv_cb_list); 160 spin_lock_init(&serv->sv_cb_lock); 161 init_waitqueue_head(&serv->sv_cb_waitq); 162 rqstp = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 163 if (IS_ERR(rqstp)) { 164 svc_xprt_put(serv->sv_bc_xprt); 165 serv->sv_bc_xprt = NULL; 166 } 167 dprintk("--> %s return %ld\n", __func__, 168 IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0); 169 return rqstp; 170 } 171 172 static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv, 173 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp)) 174 { 175 *rqstpp = nfs41_callback_up(serv); 176 *callback_svc = nfs41_callback_svc; 177 } 178 179 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, 180 struct svc_serv *serv) 181 { 182 if (minorversion) 183 /* 184 * Save the svc_serv in the transport so that it can 185 * be referenced when the session backchannel is initialized 186 */ 187 xprt->bc_serv = serv; 188 } 189 #else 190 static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net) 191 { 192 return 0; 193 } 194 195 static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv, 196 struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp)) 197 { 198 *rqstpp = ERR_PTR(-ENOTSUPP); 199 *callback_svc = ERR_PTR(-ENOTSUPP); 200 } 201 202 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, 203 struct svc_serv *serv) 204 { 205 } 206 #endif /* CONFIG_NFS_V4_1 */ 207 208 static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, 209 struct svc_serv *serv) 210 { 211 struct svc_rqst *rqstp; 212 int (*callback_svc)(void *vrqstp); 213 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 214 int ret; 215 216 nfs_callback_bc_serv(minorversion, xprt, serv); 217 218 if (cb_info->task) 219 return 0; 220 221 switch (minorversion) { 222 case 0: 223 /* v4.0 callback setup */ 224 rqstp = nfs4_callback_up(serv); 225 callback_svc = nfs4_callback_svc; 226 break; 227 default: 228 nfs_minorversion_callback_svc_setup(serv, 229 &rqstp, &callback_svc); 230 } 231 232 if (IS_ERR(rqstp)) 233 return PTR_ERR(rqstp); 234 235 svc_sock_update_bufs(serv); 236 237 cb_info->serv = serv; 238 cb_info->rqst = rqstp; 239 cb_info->task = kthread_run(callback_svc, cb_info->rqst, 240 "nfsv4.%u-svc", minorversion); 241 if (IS_ERR(cb_info->task)) { 242 ret = PTR_ERR(cb_info->task); 243 svc_exit_thread(cb_info->rqst); 244 cb_info->rqst = NULL; 245 cb_info->task = NULL; 246 return ret; 247 } 248 dprintk("nfs_callback_up: service started\n"); 249 return 0; 250 } 251 252 static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net) 253 { 254 struct nfs_net *nn = net_generic(net, nfs_net_id); 255 256 if (--nn->cb_users[minorversion]) 257 return; 258 259 dprintk("NFS: destroy per-net callback data; net=%p\n", net); 260 svc_shutdown_net(serv, net); 261 } 262 263 static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, struct net *net) 264 { 265 struct nfs_net *nn = net_generic(net, nfs_net_id); 266 int ret; 267 268 if (nn->cb_users[minorversion]++) 269 return 0; 270 271 dprintk("NFS: create per-net callback data; net=%p\n", net); 272 273 ret = svc_bind(serv, net); 274 if (ret < 0) { 275 printk(KERN_WARNING "NFS: bind callback service failed\n"); 276 goto err_bind; 277 } 278 279 switch (minorversion) { 280 case 0: 281 ret = nfs4_callback_up_net(serv, net); 282 break; 283 case 1: 284 case 2: 285 ret = nfs41_callback_up_net(serv, net); 286 break; 287 default: 288 printk(KERN_ERR "NFS: unknown callback version: %d\n", 289 minorversion); 290 ret = -EINVAL; 291 break; 292 } 293 294 if (ret < 0) { 295 printk(KERN_ERR "NFS: callback service start failed\n"); 296 goto err_socks; 297 } 298 return 0; 299 300 err_socks: 301 svc_rpcb_cleanup(serv, net); 302 err_bind: 303 dprintk("NFS: Couldn't create callback socket: err = %d; " 304 "net = %p\n", ret, net); 305 return ret; 306 } 307 308 static struct svc_serv *nfs_callback_create_svc(int minorversion) 309 { 310 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 311 struct svc_serv *serv; 312 313 /* 314 * Check whether we're already up and running. 315 */ 316 if (cb_info->task) { 317 /* 318 * Note: increase service usage, because later in case of error 319 * svc_destroy() will be called. 320 */ 321 svc_get(cb_info->serv); 322 return cb_info->serv; 323 } 324 325 /* 326 * Sanity check: if there's no task, 327 * we should be the first user ... 328 */ 329 if (cb_info->users) 330 printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n", 331 cb_info->users); 332 333 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL); 334 if (!serv) { 335 printk(KERN_ERR "nfs_callback_create_svc: create service failed\n"); 336 return ERR_PTR(-ENOMEM); 337 } 338 /* As there is only one thread we need to over-ride the 339 * default maximum of 80 connections 340 */ 341 serv->sv_maxconn = 1024; 342 dprintk("nfs_callback_create_svc: service created\n"); 343 return serv; 344 } 345 346 /* 347 * Bring up the callback thread if it is not already up. 348 */ 349 int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) 350 { 351 struct svc_serv *serv; 352 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 353 int ret; 354 struct net *net = xprt->xprt_net; 355 356 mutex_lock(&nfs_callback_mutex); 357 358 serv = nfs_callback_create_svc(minorversion); 359 if (IS_ERR(serv)) { 360 ret = PTR_ERR(serv); 361 goto err_create; 362 } 363 364 ret = nfs_callback_up_net(minorversion, serv, net); 365 if (ret < 0) 366 goto err_net; 367 368 ret = nfs_callback_start_svc(minorversion, xprt, serv); 369 if (ret < 0) 370 goto err_start; 371 372 cb_info->users++; 373 /* 374 * svc_create creates the svc_serv with sv_nrthreads == 1, and then 375 * svc_prepare_thread increments that. So we need to call svc_destroy 376 * on both success and failure so that the refcount is 1 when the 377 * thread exits. 378 */ 379 err_net: 380 svc_destroy(serv); 381 err_create: 382 mutex_unlock(&nfs_callback_mutex); 383 return ret; 384 385 err_start: 386 nfs_callback_down_net(minorversion, serv, net); 387 dprintk("NFS: Couldn't create server thread; err = %d\n", ret); 388 goto err_net; 389 } 390 391 /* 392 * Kill the callback thread if it's no longer being used. 393 */ 394 void nfs_callback_down(int minorversion, struct net *net) 395 { 396 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 397 398 mutex_lock(&nfs_callback_mutex); 399 nfs_callback_down_net(minorversion, cb_info->serv, net); 400 cb_info->users--; 401 if (cb_info->users == 0 && cb_info->task != NULL) { 402 kthread_stop(cb_info->task); 403 dprintk("nfs_callback_down: service stopped\n"); 404 svc_exit_thread(cb_info->rqst); 405 dprintk("nfs_callback_down: service destroyed\n"); 406 cb_info->serv = NULL; 407 cb_info->rqst = NULL; 408 cb_info->task = NULL; 409 } 410 mutex_unlock(&nfs_callback_mutex); 411 } 412 413 /* Boolean check of RPC_AUTH_GSS principal */ 414 int 415 check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) 416 { 417 char *p = rqstp->rq_cred.cr_principal; 418 419 if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) 420 return 1; 421 422 /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ 423 if (clp->cl_minorversion != 0) 424 return 0; 425 /* 426 * It might just be a normal user principal, in which case 427 * userspace won't bother to tell us the name at all. 428 */ 429 if (p == NULL) 430 return 0; 431 432 /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ 433 434 if (memcmp(p, "nfs@", 4) != 0) 435 return 0; 436 p += 4; 437 if (strcmp(p, clp->cl_hostname) != 0) 438 return 0; 439 return 1; 440 } 441 442 /* 443 * pg_authenticate method for nfsv4 callback threads. 444 * 445 * The authflavor has been negotiated, so an incorrect flavor is a server 446 * bug. Drop packets with incorrect authflavor. 447 * 448 * All other checking done after NFS decoding where the nfs_client can be 449 * found in nfs4_callback_compound 450 */ 451 static int nfs_callback_authenticate(struct svc_rqst *rqstp) 452 { 453 switch (rqstp->rq_authop->flavour) { 454 case RPC_AUTH_NULL: 455 if (rqstp->rq_proc != CB_NULL) 456 return SVC_DROP; 457 break; 458 case RPC_AUTH_GSS: 459 /* No RPC_AUTH_GSS support yet in NFSv4.1 */ 460 if (svc_is_backchannel(rqstp)) 461 return SVC_DROP; 462 } 463 return SVC_OK; 464 } 465 466 /* 467 * Define NFS4 callback program 468 */ 469 static struct svc_version *nfs4_callback_version[] = { 470 [1] = &nfs4_callback_version1, 471 [4] = &nfs4_callback_version4, 472 }; 473 474 static struct svc_stat nfs4_callback_stats; 475 476 static struct svc_program nfs4_callback_program = { 477 .pg_prog = NFS4_CALLBACK, /* RPC service number */ 478 .pg_nvers = ARRAY_SIZE(nfs4_callback_version), /* Number of entries */ 479 .pg_vers = nfs4_callback_version, /* version table */ 480 .pg_name = "NFSv4 callback", /* service name */ 481 .pg_class = "nfs", /* authentication class */ 482 .pg_stats = &nfs4_callback_stats, 483 .pg_authenticate = nfs_callback_authenticate, 484 }; 485