1 /* 2 * linux/fs/nfsd/nfssvc.c 3 * 4 * Central processing for nfsd. 5 * 6 * Authors: Olaf Kirch (okir@monad.swb.de) 7 * 8 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> 9 */ 10 11 #include <linux/module.h> 12 13 #include <linux/time.h> 14 #include <linux/errno.h> 15 #include <linux/nfs.h> 16 #include <linux/in.h> 17 #include <linux/uio.h> 18 #include <linux/unistd.h> 19 #include <linux/slab.h> 20 #include <linux/smp.h> 21 #include <linux/smp_lock.h> 22 #include <linux/fs_struct.h> 23 24 #include <linux/sunrpc/types.h> 25 #include <linux/sunrpc/stats.h> 26 #include <linux/sunrpc/svc.h> 27 #include <linux/sunrpc/svcsock.h> 28 #include <linux/sunrpc/cache.h> 29 #include <linux/nfsd/nfsd.h> 30 #include <linux/nfsd/stats.h> 31 #include <linux/nfsd/cache.h> 32 #include <linux/nfsd/syscall.h> 33 #include <linux/lockd/bind.h> 34 #include <linux/nfsacl.h> 35 36 #define NFSDDBG_FACILITY NFSDDBG_SVC 37 38 /* these signals will be delivered to an nfsd thread 39 * when handling a request 40 */ 41 #define ALLOWED_SIGS (sigmask(SIGKILL)) 42 /* these signals will be delivered to an nfsd thread 43 * when not handling a request. i.e. when waiting 44 */ 45 #define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT)) 46 /* if the last thread dies with SIGHUP, then the exports table is 47 * left unchanged ( like 2.4-{0-9} ). Any other signal will clear 48 * the exports table (like 2.2). 49 */ 50 #define SIG_NOCLEAN SIGHUP 51 52 extern struct svc_program nfsd_program; 53 static void nfsd(struct svc_rqst *rqstp); 54 struct timeval nfssvc_boot; 55 struct svc_serv *nfsd_serv; 56 static atomic_t nfsd_busy; 57 static unsigned long nfsd_last_call; 58 static DEFINE_SPINLOCK(nfsd_call_lock); 59 60 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 61 static struct svc_stat nfsd_acl_svcstats; 62 static struct svc_version * nfsd_acl_version[] = { 63 [2] = &nfsd_acl_version2, 64 [3] = &nfsd_acl_version3, 65 }; 66 67 #define NFSD_ACL_MINVERS 2 68 #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version) 69 static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS]; 70 71 static struct svc_program nfsd_acl_program = { 72 .pg_prog = NFS_ACL_PROGRAM, 73 .pg_nvers = NFSD_ACL_NRVERS, 74 .pg_vers = nfsd_acl_versions, 75 .pg_name = "nfsacl", 76 .pg_class = "nfsd", 77 .pg_stats = &nfsd_acl_svcstats, 78 .pg_authenticate = &svc_set_client, 79 }; 80 81 static struct svc_stat nfsd_acl_svcstats = { 82 .program = &nfsd_acl_program, 83 }; 84 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ 85 86 static struct svc_version * nfsd_version[] = { 87 [2] = &nfsd_version2, 88 #if defined(CONFIG_NFSD_V3) 89 [3] = &nfsd_version3, 90 #endif 91 #if defined(CONFIG_NFSD_V4) 92 [4] = &nfsd_version4, 93 #endif 94 }; 95 96 #define NFSD_MINVERS 2 97 #define NFSD_NRVERS ARRAY_SIZE(nfsd_version) 98 static struct svc_version *nfsd_versions[NFSD_NRVERS]; 99 100 struct svc_program nfsd_program = { 101 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 102 .pg_next = &nfsd_acl_program, 103 #endif 104 .pg_prog = NFS_PROGRAM, /* program number */ 105 .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ 106 .pg_vers = nfsd_versions, /* version table */ 107 .pg_name = "nfsd", /* program name */ 108 .pg_class = "nfsd", /* authentication class */ 109 .pg_stats = &nfsd_svcstats, /* version table */ 110 .pg_authenticate = &svc_set_client, /* export authentication */ 111 112 }; 113 114 int nfsd_vers(int vers, enum vers_op change) 115 { 116 if (vers < NFSD_MINVERS || vers >= NFSD_NRVERS) 117 return -1; 118 switch(change) { 119 case NFSD_SET: 120 nfsd_versions[vers] = nfsd_version[vers]; 121 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 122 if (vers < NFSD_ACL_NRVERS) 123 nfsd_acl_versions[vers] = nfsd_acl_version[vers]; 124 #endif 125 break; 126 case NFSD_CLEAR: 127 nfsd_versions[vers] = NULL; 128 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 129 if (vers < NFSD_ACL_NRVERS) 130 nfsd_acl_versions[vers] = NULL; 131 #endif 132 break; 133 case NFSD_TEST: 134 return nfsd_versions[vers] != NULL; 135 case NFSD_AVAIL: 136 return nfsd_version[vers] != NULL; 137 } 138 return 0; 139 } 140 /* 141 * Maximum number of nfsd processes 142 */ 143 #define NFSD_MAXSERVS 8192 144 145 int nfsd_nrthreads(void) 146 { 147 if (nfsd_serv == NULL) 148 return 0; 149 else 150 return nfsd_serv->sv_nrthreads; 151 } 152 153 static int killsig; /* signal that was used to kill last nfsd */ 154 static void nfsd_last_thread(struct svc_serv *serv) 155 { 156 /* When last nfsd thread exits we need to do some clean-up */ 157 struct svc_sock *svsk; 158 list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) 159 lockd_down(); 160 nfsd_serv = NULL; 161 nfsd_racache_shutdown(); 162 nfs4_state_shutdown(); 163 164 printk(KERN_WARNING "nfsd: last server has exited\n"); 165 if (killsig != SIG_NOCLEAN) { 166 printk(KERN_WARNING "nfsd: unexporting all filesystems\n"); 167 nfsd_export_flush(); 168 } 169 } 170 171 void nfsd_reset_versions(void) 172 { 173 int found_one = 0; 174 int i; 175 176 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { 177 if (nfsd_program.pg_vers[i]) 178 found_one = 1; 179 } 180 181 if (!found_one) { 182 for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) 183 nfsd_program.pg_vers[i] = nfsd_version[i]; 184 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 185 for (i = NFSD_ACL_MINVERS; i < NFSD_ACL_NRVERS; i++) 186 nfsd_acl_program.pg_vers[i] = 187 nfsd_acl_version[i]; 188 #endif 189 } 190 } 191 192 int nfsd_create_serv(void) 193 { 194 int err = 0; 195 lock_kernel(); 196 if (nfsd_serv) { 197 svc_get(nfsd_serv); 198 unlock_kernel(); 199 return 0; 200 } 201 if (nfsd_max_blksize == 0) { 202 /* choose a suitable default */ 203 struct sysinfo i; 204 si_meminfo(&i); 205 /* Aim for 1/4096 of memory per thread 206 * This gives 1MB on 4Gig machines 207 * But only uses 32K on 128M machines. 208 * Bottom out at 8K on 32M and smaller. 209 * Of course, this is only a default. 210 */ 211 nfsd_max_blksize = NFSSVC_MAXBLKSIZE; 212 i.totalram <<= PAGE_SHIFT - 12; 213 while (nfsd_max_blksize > i.totalram && 214 nfsd_max_blksize >= 8*1024*2) 215 nfsd_max_blksize /= 2; 216 } 217 218 atomic_set(&nfsd_busy, 0); 219 nfsd_serv = svc_create_pooled(&nfsd_program, 220 nfsd_max_blksize, 221 nfsd_last_thread, 222 nfsd, SIG_NOCLEAN, THIS_MODULE); 223 if (nfsd_serv == NULL) 224 err = -ENOMEM; 225 unlock_kernel(); 226 do_gettimeofday(&nfssvc_boot); /* record boot time */ 227 return err; 228 } 229 230 static int nfsd_init_socks(int port) 231 { 232 int error; 233 if (!list_empty(&nfsd_serv->sv_permsocks)) 234 return 0; 235 236 error = lockd_up(IPPROTO_UDP); 237 if (error >= 0) { 238 error = svc_makesock(nfsd_serv, IPPROTO_UDP, port); 239 if (error < 0) 240 lockd_down(); 241 } 242 if (error < 0) 243 return error; 244 245 #ifdef CONFIG_NFSD_TCP 246 error = lockd_up(IPPROTO_TCP); 247 if (error >= 0) { 248 error = svc_makesock(nfsd_serv, IPPROTO_TCP, port); 249 if (error < 0) 250 lockd_down(); 251 } 252 if (error < 0) 253 return error; 254 #endif 255 return 0; 256 } 257 258 int nfsd_nrpools(void) 259 { 260 if (nfsd_serv == NULL) 261 return 0; 262 else 263 return nfsd_serv->sv_nrpools; 264 } 265 266 int nfsd_get_nrthreads(int n, int *nthreads) 267 { 268 int i = 0; 269 270 if (nfsd_serv != NULL) { 271 for (i = 0; i < nfsd_serv->sv_nrpools && i < n; i++) 272 nthreads[i] = nfsd_serv->sv_pools[i].sp_nrthreads; 273 } 274 275 return 0; 276 } 277 278 int nfsd_set_nrthreads(int n, int *nthreads) 279 { 280 int i = 0; 281 int tot = 0; 282 int err = 0; 283 284 if (nfsd_serv == NULL || n <= 0) 285 return 0; 286 287 if (n > nfsd_serv->sv_nrpools) 288 n = nfsd_serv->sv_nrpools; 289 290 /* enforce a global maximum number of threads */ 291 tot = 0; 292 for (i = 0; i < n; i++) { 293 if (nthreads[i] > NFSD_MAXSERVS) 294 nthreads[i] = NFSD_MAXSERVS; 295 tot += nthreads[i]; 296 } 297 if (tot > NFSD_MAXSERVS) { 298 /* total too large: scale down requested numbers */ 299 for (i = 0; i < n && tot > 0; i++) { 300 int new = nthreads[i] * NFSD_MAXSERVS / tot; 301 tot -= (nthreads[i] - new); 302 nthreads[i] = new; 303 } 304 for (i = 0; i < n && tot > 0; i++) { 305 nthreads[i]--; 306 tot--; 307 } 308 } 309 310 /* 311 * There must always be a thread in pool 0; the admin 312 * can't shut down NFS completely using pool_threads. 313 */ 314 if (nthreads[0] == 0) 315 nthreads[0] = 1; 316 317 /* apply the new numbers */ 318 lock_kernel(); 319 svc_get(nfsd_serv); 320 for (i = 0; i < n; i++) { 321 err = svc_set_num_threads(nfsd_serv, &nfsd_serv->sv_pools[i], 322 nthreads[i]); 323 if (err) 324 break; 325 } 326 svc_destroy(nfsd_serv); 327 unlock_kernel(); 328 329 return err; 330 } 331 332 int 333 nfsd_svc(unsigned short port, int nrservs) 334 { 335 int error; 336 337 lock_kernel(); 338 dprintk("nfsd: creating service\n"); 339 error = -EINVAL; 340 if (nrservs <= 0) 341 nrservs = 0; 342 if (nrservs > NFSD_MAXSERVS) 343 nrservs = NFSD_MAXSERVS; 344 345 /* Readahead param cache - will no-op if it already exists */ 346 error = nfsd_racache_init(2*nrservs); 347 if (error<0) 348 goto out; 349 error = nfs4_state_start(); 350 if (error<0) 351 goto out; 352 353 nfsd_reset_versions(); 354 355 error = nfsd_create_serv(); 356 357 if (error) 358 goto out; 359 error = nfsd_init_socks(port); 360 if (error) 361 goto failure; 362 363 error = svc_set_num_threads(nfsd_serv, NULL, nrservs); 364 failure: 365 svc_destroy(nfsd_serv); /* Release server */ 366 out: 367 unlock_kernel(); 368 return error; 369 } 370 371 static inline void 372 update_thread_usage(int busy_threads) 373 { 374 unsigned long prev_call; 375 unsigned long diff; 376 int decile; 377 378 spin_lock(&nfsd_call_lock); 379 prev_call = nfsd_last_call; 380 nfsd_last_call = jiffies; 381 decile = busy_threads*10/nfsdstats.th_cnt; 382 if (decile>0 && decile <= 10) { 383 diff = nfsd_last_call - prev_call; 384 if ( (nfsdstats.th_usage[decile-1] += diff) >= NFSD_USAGE_WRAP) 385 nfsdstats.th_usage[decile-1] -= NFSD_USAGE_WRAP; 386 if (decile == 10) 387 nfsdstats.th_fullcnt++; 388 } 389 spin_unlock(&nfsd_call_lock); 390 } 391 392 /* 393 * This is the NFS server kernel thread 394 */ 395 static void 396 nfsd(struct svc_rqst *rqstp) 397 { 398 struct fs_struct *fsp; 399 int err; 400 sigset_t shutdown_mask, allowed_mask; 401 402 /* Lock module and set up kernel thread */ 403 lock_kernel(); 404 daemonize("nfsd"); 405 406 /* After daemonize() this kernel thread shares current->fs 407 * with the init process. We need to create files with a 408 * umask of 0 instead of init's umask. */ 409 fsp = copy_fs_struct(current->fs); 410 if (!fsp) { 411 printk("Unable to start nfsd thread: out of memory\n"); 412 goto out; 413 } 414 exit_fs(current); 415 current->fs = fsp; 416 current->fs->umask = 0; 417 418 siginitsetinv(&shutdown_mask, SHUTDOWN_SIGS); 419 siginitsetinv(&allowed_mask, ALLOWED_SIGS); 420 421 nfsdstats.th_cnt++; 422 423 rqstp->rq_task = current; 424 425 unlock_kernel(); 426 427 /* 428 * We want less throttling in balance_dirty_pages() so that nfs to 429 * localhost doesn't cause nfsd to lock up due to all the client's 430 * dirty pages. 431 */ 432 current->flags |= PF_LESS_THROTTLE; 433 434 /* 435 * The main request loop 436 */ 437 for (;;) { 438 /* Block all but the shutdown signals */ 439 sigprocmask(SIG_SETMASK, &shutdown_mask, NULL); 440 441 /* 442 * Find a socket with data available and call its 443 * recvfrom routine. 444 */ 445 while ((err = svc_recv(rqstp, 60*60*HZ)) == -EAGAIN) 446 ; 447 if (err < 0) 448 break; 449 update_thread_usage(atomic_read(&nfsd_busy)); 450 atomic_inc(&nfsd_busy); 451 452 /* Lock the export hash tables for reading. */ 453 exp_readlock(); 454 455 /* Process request with signals blocked. */ 456 sigprocmask(SIG_SETMASK, &allowed_mask, NULL); 457 458 svc_process(rqstp); 459 460 /* Unlock export hash tables */ 461 exp_readunlock(); 462 update_thread_usage(atomic_read(&nfsd_busy)); 463 atomic_dec(&nfsd_busy); 464 } 465 466 if (err != -EINTR) { 467 printk(KERN_WARNING "nfsd: terminating on error %d\n", -err); 468 } else { 469 unsigned int signo; 470 471 for (signo = 1; signo <= _NSIG; signo++) 472 if (sigismember(¤t->pending.signal, signo) && 473 !sigismember(¤t->blocked, signo)) 474 break; 475 killsig = signo; 476 } 477 /* Clear signals before calling svc_exit_thread() */ 478 flush_signals(current); 479 480 lock_kernel(); 481 482 nfsdstats.th_cnt --; 483 484 out: 485 /* Release the thread */ 486 svc_exit_thread(rqstp); 487 488 /* Release module */ 489 unlock_kernel(); 490 module_put_and_exit(0); 491 } 492 493 int 494 nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) 495 { 496 struct svc_procedure *proc; 497 kxdrproc_t xdr; 498 __be32 nfserr; 499 __be32 *nfserrp; 500 501 dprintk("nfsd_dispatch: vers %d proc %d\n", 502 rqstp->rq_vers, rqstp->rq_proc); 503 proc = rqstp->rq_procinfo; 504 505 /* Check whether we have this call in the cache. */ 506 switch (nfsd_cache_lookup(rqstp, proc->pc_cachetype)) { 507 case RC_INTR: 508 case RC_DROPIT: 509 return 0; 510 case RC_REPLY: 511 return 1; 512 case RC_DOIT:; 513 /* do it */ 514 } 515 516 /* Decode arguments */ 517 xdr = proc->pc_decode; 518 if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, 519 rqstp->rq_argp)) { 520 dprintk("nfsd: failed to decode arguments!\n"); 521 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 522 *statp = rpc_garbage_args; 523 return 1; 524 } 525 526 /* need to grab the location to store the status, as 527 * nfsv4 does some encoding while processing 528 */ 529 nfserrp = rqstp->rq_res.head[0].iov_base 530 + rqstp->rq_res.head[0].iov_len; 531 rqstp->rq_res.head[0].iov_len += sizeof(__be32); 532 533 /* Now call the procedure handler, and encode NFS status. */ 534 nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); 535 if (nfserr == nfserr_jukebox && rqstp->rq_vers == 2) 536 nfserr = nfserr_dropit; 537 if (nfserr == nfserr_dropit) { 538 dprintk("nfsd: Dropping request due to malloc failure!\n"); 539 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 540 return 0; 541 } 542 543 if (rqstp->rq_proc != 0) 544 *nfserrp++ = nfserr; 545 546 /* Encode result. 547 * For NFSv2, additional info is never returned in case of an error. 548 */ 549 if (!(nfserr && rqstp->rq_vers == 2)) { 550 xdr = proc->pc_encode; 551 if (xdr && !xdr(rqstp, nfserrp, 552 rqstp->rq_resp)) { 553 /* Failed to encode result. Release cache entry */ 554 dprintk("nfsd: failed to encode result!\n"); 555 nfsd_cache_update(rqstp, RC_NOCACHE, NULL); 556 *statp = rpc_system_err; 557 return 1; 558 } 559 } 560 561 /* Store reply in cache. */ 562 nfsd_cache_update(rqstp, proc->pc_cachetype, statp + 1); 563 return 1; 564 } 565