1 /* 2 * Syscall interface to knfsd. 3 * 4 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 5 */ 6 7 #include <linux/slab.h> 8 #include <linux/namei.h> 9 #include <linux/ctype.h> 10 11 #include <linux/sunrpc/svcsock.h> 12 #include <linux/lockd/lockd.h> 13 #include <linux/sunrpc/addr.h> 14 #include <linux/sunrpc/gss_api.h> 15 #include <linux/sunrpc/gss_krb5_enctypes.h> 16 #include <linux/sunrpc/rpc_pipe_fs.h> 17 #include <linux/module.h> 18 19 #include "idmap.h" 20 #include "nfsd.h" 21 #include "cache.h" 22 #include "state.h" 23 #include "netns.h" 24 25 /* 26 * We have a single directory with several nodes in it. 27 */ 28 enum { 29 NFSD_Root = 1, 30 NFSD_List, 31 NFSD_Export_features, 32 NFSD_Fh, 33 NFSD_FO_UnlockIP, 34 NFSD_FO_UnlockFS, 35 NFSD_Threads, 36 NFSD_Pool_Threads, 37 NFSD_Pool_Stats, 38 NFSD_Reply_Cache_Stats, 39 NFSD_Versions, 40 NFSD_Ports, 41 NFSD_MaxBlkSize, 42 NFSD_MaxConnections, 43 NFSD_SupportedEnctypes, 44 /* 45 * The below MUST come last. Otherwise we leave a hole in nfsd_files[] 46 * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops 47 */ 48 #ifdef CONFIG_NFSD_V4 49 NFSD_Leasetime, 50 NFSD_Gracetime, 51 NFSD_RecoveryDir, 52 #endif 53 }; 54 55 /* 56 * write() for these nodes. 57 */ 58 static ssize_t write_filehandle(struct file *file, char *buf, size_t size); 59 static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size); 60 static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size); 61 static ssize_t write_threads(struct file *file, char *buf, size_t size); 62 static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); 63 static ssize_t write_versions(struct file *file, char *buf, size_t size); 64 static ssize_t write_ports(struct file *file, char *buf, size_t size); 65 static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); 66 static ssize_t write_maxconn(struct file *file, char *buf, size_t size); 67 #ifdef CONFIG_NFSD_V4 68 static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 69 static ssize_t write_gracetime(struct file *file, char *buf, size_t size); 70 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); 71 #endif 72 73 static ssize_t (*write_op[])(struct file *, char *, size_t) = { 74 [NFSD_Fh] = write_filehandle, 75 [NFSD_FO_UnlockIP] = write_unlock_ip, 76 [NFSD_FO_UnlockFS] = write_unlock_fs, 77 [NFSD_Threads] = write_threads, 78 [NFSD_Pool_Threads] = write_pool_threads, 79 [NFSD_Versions] = write_versions, 80 [NFSD_Ports] = write_ports, 81 [NFSD_MaxBlkSize] = write_maxblksize, 82 [NFSD_MaxConnections] = write_maxconn, 83 #ifdef CONFIG_NFSD_V4 84 [NFSD_Leasetime] = write_leasetime, 85 [NFSD_Gracetime] = write_gracetime, 86 [NFSD_RecoveryDir] = write_recoverydir, 87 #endif 88 }; 89 90 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 91 { 92 ino_t ino = file_inode(file)->i_ino; 93 char *data; 94 ssize_t rv; 95 96 if (ino >= ARRAY_SIZE(write_op) || !write_op[ino]) 97 return -EINVAL; 98 99 data = simple_transaction_get(file, buf, size); 100 if (IS_ERR(data)) 101 return PTR_ERR(data); 102 103 rv = write_op[ino](file, data, size); 104 if (rv >= 0) { 105 simple_transaction_set(file, rv); 106 rv = size; 107 } 108 return rv; 109 } 110 111 static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) 112 { 113 if (! file->private_data) { 114 /* An attempt to read a transaction file without writing 115 * causes a 0-byte write so that the file can return 116 * state information 117 */ 118 ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos); 119 if (rv < 0) 120 return rv; 121 } 122 return simple_transaction_read(file, buf, size, pos); 123 } 124 125 static const struct file_operations transaction_ops = { 126 .write = nfsctl_transaction_write, 127 .read = nfsctl_transaction_read, 128 .release = simple_transaction_release, 129 .llseek = default_llseek, 130 }; 131 132 static int exports_net_open(struct net *net, struct file *file) 133 { 134 int err; 135 struct seq_file *seq; 136 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 137 138 err = seq_open(file, &nfs_exports_op); 139 if (err) 140 return err; 141 142 seq = file->private_data; 143 seq->private = nn->svc_export_cache; 144 return 0; 145 } 146 147 static int exports_proc_open(struct inode *inode, struct file *file) 148 { 149 return exports_net_open(current->nsproxy->net_ns, file); 150 } 151 152 static const struct file_operations exports_proc_operations = { 153 .open = exports_proc_open, 154 .read = seq_read, 155 .llseek = seq_lseek, 156 .release = seq_release, 157 .owner = THIS_MODULE, 158 }; 159 160 static int exports_nfsd_open(struct inode *inode, struct file *file) 161 { 162 return exports_net_open(inode->i_sb->s_fs_info, file); 163 } 164 165 static const struct file_operations exports_nfsd_operations = { 166 .open = exports_nfsd_open, 167 .read = seq_read, 168 .llseek = seq_lseek, 169 .release = seq_release, 170 .owner = THIS_MODULE, 171 }; 172 173 static int export_features_show(struct seq_file *m, void *v) 174 { 175 seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS); 176 return 0; 177 } 178 179 static int export_features_open(struct inode *inode, struct file *file) 180 { 181 return single_open(file, export_features_show, NULL); 182 } 183 184 static const struct file_operations export_features_operations = { 185 .open = export_features_open, 186 .read = seq_read, 187 .llseek = seq_lseek, 188 .release = single_release, 189 }; 190 191 #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) 192 static int supported_enctypes_show(struct seq_file *m, void *v) 193 { 194 seq_printf(m, KRB5_SUPPORTED_ENCTYPES); 195 return 0; 196 } 197 198 static int supported_enctypes_open(struct inode *inode, struct file *file) 199 { 200 return single_open(file, supported_enctypes_show, NULL); 201 } 202 203 static const struct file_operations supported_enctypes_ops = { 204 .open = supported_enctypes_open, 205 .read = seq_read, 206 .llseek = seq_lseek, 207 .release = single_release, 208 }; 209 #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ 210 211 static const struct file_operations pool_stats_operations = { 212 .open = nfsd_pool_stats_open, 213 .read = seq_read, 214 .llseek = seq_lseek, 215 .release = nfsd_pool_stats_release, 216 .owner = THIS_MODULE, 217 }; 218 219 static struct file_operations reply_cache_stats_operations = { 220 .open = nfsd_reply_cache_stats_open, 221 .read = seq_read, 222 .llseek = seq_lseek, 223 .release = single_release, 224 }; 225 226 /*----------------------------------------------------------------------------*/ 227 /* 228 * payload - write methods 229 */ 230 231 232 /** 233 * write_unlock_ip - Release all locks used by a client 234 * 235 * Experimental. 236 * 237 * Input: 238 * buf: '\n'-terminated C string containing a 239 * presentation format IP address 240 * size: length of C string in @buf 241 * Output: 242 * On success: returns zero if all specified locks were released; 243 * returns one if one or more locks were not released 244 * On error: return code is negative errno value 245 */ 246 static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size) 247 { 248 struct sockaddr_storage address; 249 struct sockaddr *sap = (struct sockaddr *)&address; 250 size_t salen = sizeof(address); 251 char *fo_path; 252 struct net *net = file->f_dentry->d_sb->s_fs_info; 253 254 /* sanity check */ 255 if (size == 0) 256 return -EINVAL; 257 258 if (buf[size-1] != '\n') 259 return -EINVAL; 260 261 fo_path = buf; 262 if (qword_get(&buf, fo_path, size) < 0) 263 return -EINVAL; 264 265 if (rpc_pton(net, fo_path, size, sap, salen) == 0) 266 return -EINVAL; 267 268 return nlmsvc_unlock_all_by_ip(sap); 269 } 270 271 /** 272 * write_unlock_fs - Release all locks on a local file system 273 * 274 * Experimental. 275 * 276 * Input: 277 * buf: '\n'-terminated C string containing the 278 * absolute pathname of a local file system 279 * size: length of C string in @buf 280 * Output: 281 * On success: returns zero if all specified locks were released; 282 * returns one if one or more locks were not released 283 * On error: return code is negative errno value 284 */ 285 static ssize_t write_unlock_fs(struct file *file, char *buf, size_t size) 286 { 287 struct path path; 288 char *fo_path; 289 int error; 290 291 /* sanity check */ 292 if (size == 0) 293 return -EINVAL; 294 295 if (buf[size-1] != '\n') 296 return -EINVAL; 297 298 fo_path = buf; 299 if (qword_get(&buf, fo_path, size) < 0) 300 return -EINVAL; 301 302 error = kern_path(fo_path, 0, &path); 303 if (error) 304 return error; 305 306 /* 307 * XXX: Needs better sanity checking. Otherwise we could end up 308 * releasing locks on the wrong file system. 309 * 310 * For example: 311 * 1. Does the path refer to a directory? 312 * 2. Is that directory a mount point, or 313 * 3. Is that directory the root of an exported file system? 314 */ 315 error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb); 316 317 path_put(&path); 318 return error; 319 } 320 321 /** 322 * write_filehandle - Get a variable-length NFS file handle by path 323 * 324 * On input, the buffer contains a '\n'-terminated C string comprised of 325 * three alphanumeric words separated by whitespace. The string may 326 * contain escape sequences. 327 * 328 * Input: 329 * buf: 330 * domain: client domain name 331 * path: export pathname 332 * maxsize: numeric maximum size of 333 * @buf 334 * size: length of C string in @buf 335 * Output: 336 * On success: passed-in buffer filled with '\n'-terminated C 337 * string containing a ASCII hex text version 338 * of the NFS file handle; 339 * return code is the size in bytes of the string 340 * On error: return code is negative errno value 341 */ 342 static ssize_t write_filehandle(struct file *file, char *buf, size_t size) 343 { 344 char *dname, *path; 345 int uninitialized_var(maxsize); 346 char *mesg = buf; 347 int len; 348 struct auth_domain *dom; 349 struct knfsd_fh fh; 350 struct net *net = file->f_dentry->d_sb->s_fs_info; 351 352 if (size == 0) 353 return -EINVAL; 354 355 if (buf[size-1] != '\n') 356 return -EINVAL; 357 buf[size-1] = 0; 358 359 dname = mesg; 360 len = qword_get(&mesg, dname, size); 361 if (len <= 0) 362 return -EINVAL; 363 364 path = dname+len+1; 365 len = qword_get(&mesg, path, size); 366 if (len <= 0) 367 return -EINVAL; 368 369 len = get_int(&mesg, &maxsize); 370 if (len) 371 return len; 372 373 if (maxsize < NFS_FHSIZE) 374 return -EINVAL; 375 maxsize = min(maxsize, NFS3_FHSIZE); 376 377 if (qword_get(&mesg, mesg, size)>0) 378 return -EINVAL; 379 380 /* we have all the words, they are in buf.. */ 381 dom = unix_domain_find(dname); 382 if (!dom) 383 return -ENOMEM; 384 385 len = exp_rootfh(net, dom, path, &fh, maxsize); 386 auth_domain_put(dom); 387 if (len) 388 return len; 389 390 mesg = buf; 391 len = SIMPLE_TRANSACTION_LIMIT; 392 qword_addhex(&mesg, &len, (char*)&fh.fh_base, fh.fh_size); 393 mesg[-1] = '\n'; 394 return mesg - buf; 395 } 396 397 /** 398 * write_threads - Start NFSD, or report the current number of running threads 399 * 400 * Input: 401 * buf: ignored 402 * size: zero 403 * Output: 404 * On success: passed-in buffer filled with '\n'-terminated C 405 * string numeric value representing the number of 406 * running NFSD threads; 407 * return code is the size in bytes of the string 408 * On error: return code is zero 409 * 410 * OR 411 * 412 * Input: 413 * buf: C string containing an unsigned 414 * integer value representing the 415 * number of NFSD threads to start 416 * size: non-zero length of C string in @buf 417 * Output: 418 * On success: NFS service is started; 419 * passed-in buffer filled with '\n'-terminated C 420 * string numeric value representing the number of 421 * running NFSD threads; 422 * return code is the size in bytes of the string 423 * On error: return code is zero or a negative errno value 424 */ 425 static ssize_t write_threads(struct file *file, char *buf, size_t size) 426 { 427 char *mesg = buf; 428 int rv; 429 struct net *net = file->f_dentry->d_sb->s_fs_info; 430 431 if (size > 0) { 432 int newthreads; 433 rv = get_int(&mesg, &newthreads); 434 if (rv) 435 return rv; 436 if (newthreads < 0) 437 return -EINVAL; 438 rv = nfsd_svc(newthreads, net); 439 if (rv < 0) 440 return rv; 441 } else 442 rv = nfsd_nrthreads(net); 443 444 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", rv); 445 } 446 447 /** 448 * write_pool_threads - Set or report the current number of threads per pool 449 * 450 * Input: 451 * buf: ignored 452 * size: zero 453 * 454 * OR 455 * 456 * Input: 457 * buf: C string containing whitespace- 458 * separated unsigned integer values 459 * representing the number of NFSD 460 * threads to start in each pool 461 * size: non-zero length of C string in @buf 462 * Output: 463 * On success: passed-in buffer filled with '\n'-terminated C 464 * string containing integer values representing the 465 * number of NFSD threads in each pool; 466 * return code is the size in bytes of the string 467 * On error: return code is zero or a negative errno value 468 */ 469 static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) 470 { 471 /* if size > 0, look for an array of number of threads per node 472 * and apply them then write out number of threads per node as reply 473 */ 474 char *mesg = buf; 475 int i; 476 int rv; 477 int len; 478 int npools; 479 int *nthreads; 480 struct net *net = file->f_dentry->d_sb->s_fs_info; 481 482 mutex_lock(&nfsd_mutex); 483 npools = nfsd_nrpools(net); 484 if (npools == 0) { 485 /* 486 * NFS is shut down. The admin can start it by 487 * writing to the threads file but NOT the pool_threads 488 * file, sorry. Report zero threads. 489 */ 490 mutex_unlock(&nfsd_mutex); 491 strcpy(buf, "0\n"); 492 return strlen(buf); 493 } 494 495 nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); 496 rv = -ENOMEM; 497 if (nthreads == NULL) 498 goto out_free; 499 500 if (size > 0) { 501 for (i = 0; i < npools; i++) { 502 rv = get_int(&mesg, &nthreads[i]); 503 if (rv == -ENOENT) 504 break; /* fewer numbers than pools */ 505 if (rv) 506 goto out_free; /* syntax error */ 507 rv = -EINVAL; 508 if (nthreads[i] < 0) 509 goto out_free; 510 } 511 rv = nfsd_set_nrthreads(i, nthreads, net); 512 if (rv) 513 goto out_free; 514 } 515 516 rv = nfsd_get_nrthreads(npools, nthreads, net); 517 if (rv) 518 goto out_free; 519 520 mesg = buf; 521 size = SIMPLE_TRANSACTION_LIMIT; 522 for (i = 0; i < npools && size > 0; i++) { 523 snprintf(mesg, size, "%d%c", nthreads[i], (i == npools-1 ? '\n' : ' ')); 524 len = strlen(mesg); 525 size -= len; 526 mesg += len; 527 } 528 rv = mesg - buf; 529 out_free: 530 kfree(nthreads); 531 mutex_unlock(&nfsd_mutex); 532 return rv; 533 } 534 535 static ssize_t __write_versions(struct file *file, char *buf, size_t size) 536 { 537 char *mesg = buf; 538 char *vers, *minorp, sign; 539 int len, num, remaining; 540 unsigned minor; 541 ssize_t tlen = 0; 542 char *sep; 543 struct net *net = file->f_dentry->d_sb->s_fs_info; 544 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 545 546 if (size>0) { 547 if (nn->nfsd_serv) 548 /* Cannot change versions without updating 549 * nn->nfsd_serv->sv_xdrsize, and reallocing 550 * rq_argp and rq_resp 551 */ 552 return -EBUSY; 553 if (buf[size-1] != '\n') 554 return -EINVAL; 555 buf[size-1] = 0; 556 557 vers = mesg; 558 len = qword_get(&mesg, vers, size); 559 if (len <= 0) return -EINVAL; 560 do { 561 sign = *vers; 562 if (sign == '+' || sign == '-') 563 num = simple_strtol((vers+1), &minorp, 0); 564 else 565 num = simple_strtol(vers, &minorp, 0); 566 if (*minorp == '.') { 567 if (num != 4) 568 return -EINVAL; 569 minor = simple_strtoul(minorp+1, NULL, 0); 570 if (minor == 0) 571 return -EINVAL; 572 if (nfsd_minorversion(minor, sign == '-' ? 573 NFSD_CLEAR : NFSD_SET) < 0) 574 return -EINVAL; 575 goto next; 576 } 577 switch(num) { 578 case 2: 579 case 3: 580 case 4: 581 nfsd_vers(num, sign == '-' ? NFSD_CLEAR : NFSD_SET); 582 break; 583 default: 584 return -EINVAL; 585 } 586 next: 587 vers += len + 1; 588 } while ((len = qword_get(&mesg, vers, size)) > 0); 589 /* If all get turned off, turn them back on, as 590 * having no versions is BAD 591 */ 592 nfsd_reset_versions(); 593 } 594 595 /* Now write current state into reply buffer */ 596 len = 0; 597 sep = ""; 598 remaining = SIMPLE_TRANSACTION_LIMIT; 599 for (num=2 ; num <= 4 ; num++) 600 if (nfsd_vers(num, NFSD_AVAIL)) { 601 len = snprintf(buf, remaining, "%s%c%d", sep, 602 nfsd_vers(num, NFSD_TEST)?'+':'-', 603 num); 604 sep = " "; 605 606 if (len > remaining) 607 break; 608 remaining -= len; 609 buf += len; 610 tlen += len; 611 } 612 if (nfsd_vers(4, NFSD_AVAIL)) 613 for (minor = 1; minor <= NFSD_SUPPORTED_MINOR_VERSION; 614 minor++) { 615 len = snprintf(buf, remaining, " %c4.%u", 616 (nfsd_vers(4, NFSD_TEST) && 617 nfsd_minorversion(minor, NFSD_TEST)) ? 618 '+' : '-', 619 minor); 620 621 if (len > remaining) 622 break; 623 remaining -= len; 624 buf += len; 625 tlen += len; 626 } 627 628 len = snprintf(buf, remaining, "\n"); 629 if (len > remaining) 630 return -EINVAL; 631 return tlen + len; 632 } 633 634 /** 635 * write_versions - Set or report the available NFS protocol versions 636 * 637 * Input: 638 * buf: ignored 639 * size: zero 640 * Output: 641 * On success: passed-in buffer filled with '\n'-terminated C 642 * string containing positive or negative integer 643 * values representing the current status of each 644 * protocol version; 645 * return code is the size in bytes of the string 646 * On error: return code is zero or a negative errno value 647 * 648 * OR 649 * 650 * Input: 651 * buf: C string containing whitespace- 652 * separated positive or negative 653 * integer values representing NFS 654 * protocol versions to enable ("+n") 655 * or disable ("-n") 656 * size: non-zero length of C string in @buf 657 * Output: 658 * On success: status of zero or more protocol versions has 659 * been updated; passed-in buffer filled with 660 * '\n'-terminated C string containing positive 661 * or negative integer values representing the 662 * current status of each protocol version; 663 * return code is the size in bytes of the string 664 * On error: return code is zero or a negative errno value 665 */ 666 static ssize_t write_versions(struct file *file, char *buf, size_t size) 667 { 668 ssize_t rv; 669 670 mutex_lock(&nfsd_mutex); 671 rv = __write_versions(file, buf, size); 672 mutex_unlock(&nfsd_mutex); 673 return rv; 674 } 675 676 /* 677 * Zero-length write. Return a list of NFSD's current listener 678 * transports. 679 */ 680 static ssize_t __write_ports_names(char *buf, struct net *net) 681 { 682 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 683 684 if (nn->nfsd_serv == NULL) 685 return 0; 686 return svc_xprt_names(nn->nfsd_serv, buf, SIMPLE_TRANSACTION_LIMIT); 687 } 688 689 /* 690 * A single 'fd' number was written, in which case it must be for 691 * a socket of a supported family/protocol, and we use it as an 692 * nfsd listener. 693 */ 694 static ssize_t __write_ports_addfd(char *buf, struct net *net) 695 { 696 char *mesg = buf; 697 int fd, err; 698 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 699 700 err = get_int(&mesg, &fd); 701 if (err != 0 || fd < 0) 702 return -EINVAL; 703 704 if (svc_alien_sock(net, fd)) { 705 printk(KERN_ERR "%s: socket net is different to NFSd's one\n", __func__); 706 return -EINVAL; 707 } 708 709 err = nfsd_create_serv(net); 710 if (err != 0) 711 return err; 712 713 err = svc_addsock(nn->nfsd_serv, fd, buf, SIMPLE_TRANSACTION_LIMIT); 714 if (err < 0) { 715 nfsd_destroy(net); 716 return err; 717 } 718 719 /* Decrease the count, but don't shut down the service */ 720 nn->nfsd_serv->sv_nrthreads--; 721 return err; 722 } 723 724 /* 725 * A transport listener is added by writing it's transport name and 726 * a port number. 727 */ 728 static ssize_t __write_ports_addxprt(char *buf, struct net *net) 729 { 730 char transport[16]; 731 struct svc_xprt *xprt; 732 int port, err; 733 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 734 735 if (sscanf(buf, "%15s %5u", transport, &port) != 2) 736 return -EINVAL; 737 738 if (port < 1 || port > USHRT_MAX) 739 return -EINVAL; 740 741 err = nfsd_create_serv(net); 742 if (err != 0) 743 return err; 744 745 err = svc_create_xprt(nn->nfsd_serv, transport, net, 746 PF_INET, port, SVC_SOCK_ANONYMOUS); 747 if (err < 0) 748 goto out_err; 749 750 err = svc_create_xprt(nn->nfsd_serv, transport, net, 751 PF_INET6, port, SVC_SOCK_ANONYMOUS); 752 if (err < 0 && err != -EAFNOSUPPORT) 753 goto out_close; 754 755 /* Decrease the count, but don't shut down the service */ 756 nn->nfsd_serv->sv_nrthreads--; 757 return 0; 758 out_close: 759 xprt = svc_find_xprt(nn->nfsd_serv, transport, net, PF_INET, port); 760 if (xprt != NULL) { 761 svc_close_xprt(xprt); 762 svc_xprt_put(xprt); 763 } 764 out_err: 765 nfsd_destroy(net); 766 return err; 767 } 768 769 static ssize_t __write_ports(struct file *file, char *buf, size_t size, 770 struct net *net) 771 { 772 if (size == 0) 773 return __write_ports_names(buf, net); 774 775 if (isdigit(buf[0])) 776 return __write_ports_addfd(buf, net); 777 778 if (isalpha(buf[0])) 779 return __write_ports_addxprt(buf, net); 780 781 return -EINVAL; 782 } 783 784 /** 785 * write_ports - Pass a socket file descriptor or transport name to listen on 786 * 787 * Input: 788 * buf: ignored 789 * size: zero 790 * Output: 791 * On success: passed-in buffer filled with a '\n'-terminated C 792 * string containing a whitespace-separated list of 793 * named NFSD listeners; 794 * return code is the size in bytes of the string 795 * On error: return code is zero or a negative errno value 796 * 797 * OR 798 * 799 * Input: 800 * buf: C string containing an unsigned 801 * integer value representing a bound 802 * but unconnected socket that is to be 803 * used as an NFSD listener; listen(3) 804 * must be called for a SOCK_STREAM 805 * socket, otherwise it is ignored 806 * size: non-zero length of C string in @buf 807 * Output: 808 * On success: NFS service is started; 809 * passed-in buffer filled with a '\n'-terminated C 810 * string containing a unique alphanumeric name of 811 * the listener; 812 * return code is the size in bytes of the string 813 * On error: return code is a negative errno value 814 * 815 * OR 816 * 817 * Input: 818 * buf: C string containing a transport 819 * name and an unsigned integer value 820 * representing the port to listen on, 821 * separated by whitespace 822 * size: non-zero length of C string in @buf 823 * Output: 824 * On success: returns zero; NFS service is started 825 * On error: return code is a negative errno value 826 */ 827 static ssize_t write_ports(struct file *file, char *buf, size_t size) 828 { 829 ssize_t rv; 830 struct net *net = file->f_dentry->d_sb->s_fs_info; 831 832 mutex_lock(&nfsd_mutex); 833 rv = __write_ports(file, buf, size, net); 834 mutex_unlock(&nfsd_mutex); 835 return rv; 836 } 837 838 839 int nfsd_max_blksize; 840 841 /** 842 * write_maxblksize - Set or report the current NFS blksize 843 * 844 * Input: 845 * buf: ignored 846 * size: zero 847 * 848 * OR 849 * 850 * Input: 851 * buf: C string containing an unsigned 852 * integer value representing the new 853 * NFS blksize 854 * size: non-zero length of C string in @buf 855 * Output: 856 * On success: passed-in buffer filled with '\n'-terminated C string 857 * containing numeric value of the current NFS blksize 858 * setting; 859 * return code is the size in bytes of the string 860 * On error: return code is zero or a negative errno value 861 */ 862 static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 863 { 864 char *mesg = buf; 865 struct net *net = file->f_dentry->d_sb->s_fs_info; 866 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 867 868 if (size > 0) { 869 int bsize; 870 int rv = get_int(&mesg, &bsize); 871 if (rv) 872 return rv; 873 /* force bsize into allowed range and 874 * required alignment. 875 */ 876 bsize = max_t(int, bsize, 1024); 877 bsize = min_t(int, bsize, NFSSVC_MAXBLKSIZE); 878 bsize &= ~(1024-1); 879 mutex_lock(&nfsd_mutex); 880 if (nn->nfsd_serv) { 881 mutex_unlock(&nfsd_mutex); 882 return -EBUSY; 883 } 884 nfsd_max_blksize = bsize; 885 mutex_unlock(&nfsd_mutex); 886 } 887 888 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%d\n", 889 nfsd_max_blksize); 890 } 891 892 /** 893 * write_maxconn - Set or report the current max number of connections 894 * 895 * Input: 896 * buf: ignored 897 * size: zero 898 * OR 899 * 900 * Input: 901 * buf: C string containing an unsigned 902 * integer value representing the new 903 * number of max connections 904 * size: non-zero length of C string in @buf 905 * Output: 906 * On success: passed-in buffer filled with '\n'-terminated C string 907 * containing numeric value of max_connections setting 908 * for this net namespace; 909 * return code is the size in bytes of the string 910 * On error: return code is zero or a negative errno value 911 */ 912 static ssize_t write_maxconn(struct file *file, char *buf, size_t size) 913 { 914 char *mesg = buf; 915 struct net *net = file->f_dentry->d_sb->s_fs_info; 916 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 917 unsigned int maxconn = nn->max_connections; 918 919 if (size > 0) { 920 int rv = get_uint(&mesg, &maxconn); 921 922 if (rv) 923 return rv; 924 nn->max_connections = maxconn; 925 } 926 927 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%u\n", maxconn); 928 } 929 930 #ifdef CONFIG_NFSD_V4 931 static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size, 932 time_t *time, struct nfsd_net *nn) 933 { 934 char *mesg = buf; 935 int rv, i; 936 937 if (size > 0) { 938 if (nn->nfsd_serv) 939 return -EBUSY; 940 rv = get_int(&mesg, &i); 941 if (rv) 942 return rv; 943 /* 944 * Some sanity checking. We don't have a reason for 945 * these particular numbers, but problems with the 946 * extremes are: 947 * - Too short: the briefest network outage may 948 * cause clients to lose all their locks. Also, 949 * the frequent polling may be wasteful. 950 * - Too long: do you really want reboot recovery 951 * to take more than an hour? Or to make other 952 * clients wait an hour before being able to 953 * revoke a dead client's locks? 954 */ 955 if (i < 10 || i > 3600) 956 return -EINVAL; 957 *time = i; 958 } 959 960 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time); 961 } 962 963 static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size, 964 time_t *time, struct nfsd_net *nn) 965 { 966 ssize_t rv; 967 968 mutex_lock(&nfsd_mutex); 969 rv = __nfsd4_write_time(file, buf, size, time, nn); 970 mutex_unlock(&nfsd_mutex); 971 return rv; 972 } 973 974 /** 975 * write_leasetime - Set or report the current NFSv4 lease time 976 * 977 * Input: 978 * buf: ignored 979 * size: zero 980 * 981 * OR 982 * 983 * Input: 984 * buf: C string containing an unsigned 985 * integer value representing the new 986 * NFSv4 lease expiry time 987 * size: non-zero length of C string in @buf 988 * Output: 989 * On success: passed-in buffer filled with '\n'-terminated C 990 * string containing unsigned integer value of the 991 * current lease expiry time; 992 * return code is the size in bytes of the string 993 * On error: return code is zero or a negative errno value 994 */ 995 static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 996 { 997 struct net *net = file->f_dentry->d_sb->s_fs_info; 998 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 999 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); 1000 } 1001 1002 /** 1003 * write_gracetime - Set or report current NFSv4 grace period time 1004 * 1005 * As above, but sets the time of the NFSv4 grace period. 1006 * 1007 * Note this should never be set to less than the *previous* 1008 * lease-period time, but we don't try to enforce this. (In the common 1009 * case (a new boot), we don't know what the previous lease time was 1010 * anyway.) 1011 */ 1012 static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 1013 { 1014 struct net *net = file->f_dentry->d_sb->s_fs_info; 1015 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1016 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); 1017 } 1018 1019 static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size, 1020 struct nfsd_net *nn) 1021 { 1022 char *mesg = buf; 1023 char *recdir; 1024 int len, status; 1025 1026 if (size > 0) { 1027 if (nn->nfsd_serv) 1028 return -EBUSY; 1029 if (size > PATH_MAX || buf[size-1] != '\n') 1030 return -EINVAL; 1031 buf[size-1] = 0; 1032 1033 recdir = mesg; 1034 len = qword_get(&mesg, recdir, size); 1035 if (len <= 0) 1036 return -EINVAL; 1037 1038 status = nfs4_reset_recoverydir(recdir); 1039 if (status) 1040 return status; 1041 } 1042 1043 return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n", 1044 nfs4_recoverydir()); 1045 } 1046 1047 /** 1048 * write_recoverydir - Set or report the pathname of the recovery directory 1049 * 1050 * Input: 1051 * buf: ignored 1052 * size: zero 1053 * 1054 * OR 1055 * 1056 * Input: 1057 * buf: C string containing the pathname 1058 * of the directory on a local file 1059 * system containing permanent NFSv4 1060 * recovery data 1061 * size: non-zero length of C string in @buf 1062 * Output: 1063 * On success: passed-in buffer filled with '\n'-terminated C string 1064 * containing the current recovery pathname setting; 1065 * return code is the size in bytes of the string 1066 * On error: return code is zero or a negative errno value 1067 */ 1068 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 1069 { 1070 ssize_t rv; 1071 struct net *net = file->f_dentry->d_sb->s_fs_info; 1072 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1073 1074 mutex_lock(&nfsd_mutex); 1075 rv = __write_recoverydir(file, buf, size, nn); 1076 mutex_unlock(&nfsd_mutex); 1077 return rv; 1078 } 1079 1080 #endif 1081 1082 /*----------------------------------------------------------------------------*/ 1083 /* 1084 * populating the filesystem. 1085 */ 1086 1087 static int nfsd_fill_super(struct super_block * sb, void * data, int silent) 1088 { 1089 static struct tree_descr nfsd_files[] = { 1090 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO}, 1091 [NFSD_Export_features] = {"export_features", 1092 &export_features_operations, S_IRUGO}, 1093 [NFSD_FO_UnlockIP] = {"unlock_ip", 1094 &transaction_ops, S_IWUSR|S_IRUSR}, 1095 [NFSD_FO_UnlockFS] = {"unlock_filesystem", 1096 &transaction_ops, S_IWUSR|S_IRUSR}, 1097 [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR}, 1098 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, 1099 [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, 1100 [NFSD_Pool_Stats] = {"pool_stats", &pool_stats_operations, S_IRUGO}, 1101 [NFSD_Reply_Cache_Stats] = {"reply_cache_stats", &reply_cache_stats_operations, S_IRUGO}, 1102 [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, 1103 [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, 1104 [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, 1105 [NFSD_MaxConnections] = {"max_connections", &transaction_ops, S_IWUSR|S_IRUGO}, 1106 #if defined(CONFIG_SUNRPC_GSS) || defined(CONFIG_SUNRPC_GSS_MODULE) 1107 [NFSD_SupportedEnctypes] = {"supported_krb5_enctypes", &supported_enctypes_ops, S_IRUGO}, 1108 #endif /* CONFIG_SUNRPC_GSS or CONFIG_SUNRPC_GSS_MODULE */ 1109 #ifdef CONFIG_NFSD_V4 1110 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 1111 [NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR}, 1112 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, 1113 #endif 1114 /* last one */ {""} 1115 }; 1116 struct net *net = data; 1117 int ret; 1118 1119 ret = simple_fill_super(sb, 0x6e667364, nfsd_files); 1120 if (ret) 1121 return ret; 1122 sb->s_fs_info = get_net(net); 1123 return 0; 1124 } 1125 1126 static struct dentry *nfsd_mount(struct file_system_type *fs_type, 1127 int flags, const char *dev_name, void *data) 1128 { 1129 return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super); 1130 } 1131 1132 static void nfsd_umount(struct super_block *sb) 1133 { 1134 struct net *net = sb->s_fs_info; 1135 1136 kill_litter_super(sb); 1137 put_net(net); 1138 } 1139 1140 static struct file_system_type nfsd_fs_type = { 1141 .owner = THIS_MODULE, 1142 .name = "nfsd", 1143 .mount = nfsd_mount, 1144 .kill_sb = nfsd_umount, 1145 }; 1146 MODULE_ALIAS_FS("nfsd"); 1147 1148 #ifdef CONFIG_PROC_FS 1149 static int create_proc_exports_entry(void) 1150 { 1151 struct proc_dir_entry *entry; 1152 1153 entry = proc_mkdir("fs/nfs", NULL); 1154 if (!entry) 1155 return -ENOMEM; 1156 entry = proc_create("exports", 0, entry, 1157 &exports_proc_operations); 1158 if (!entry) { 1159 remove_proc_entry("fs/nfs", NULL); 1160 return -ENOMEM; 1161 } 1162 return 0; 1163 } 1164 #else /* CONFIG_PROC_FS */ 1165 static int create_proc_exports_entry(void) 1166 { 1167 return 0; 1168 } 1169 #endif 1170 1171 int nfsd_net_id; 1172 1173 static __net_init int nfsd_init_net(struct net *net) 1174 { 1175 int retval; 1176 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 1177 1178 retval = nfsd_export_init(net); 1179 if (retval) 1180 goto out_export_error; 1181 retval = nfsd_idmap_init(net); 1182 if (retval) 1183 goto out_idmap_error; 1184 nn->nfsd4_lease = 90; /* default lease time */ 1185 nn->nfsd4_grace = 90; 1186 return 0; 1187 1188 out_idmap_error: 1189 nfsd_export_shutdown(net); 1190 out_export_error: 1191 return retval; 1192 } 1193 1194 static __net_exit void nfsd_exit_net(struct net *net) 1195 { 1196 nfsd_idmap_shutdown(net); 1197 nfsd_export_shutdown(net); 1198 } 1199 1200 static struct pernet_operations nfsd_net_ops = { 1201 .init = nfsd_init_net, 1202 .exit = nfsd_exit_net, 1203 .id = &nfsd_net_id, 1204 .size = sizeof(struct nfsd_net), 1205 }; 1206 1207 static int __init init_nfsd(void) 1208 { 1209 int retval; 1210 printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n"); 1211 1212 retval = register_cld_notifier(); 1213 if (retval) 1214 return retval; 1215 retval = register_pernet_subsys(&nfsd_net_ops); 1216 if (retval < 0) 1217 goto out_unregister_notifier; 1218 retval = nfsd4_init_slabs(); 1219 if (retval) 1220 goto out_unregister_pernet; 1221 retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */ 1222 if (retval) 1223 goto out_free_slabs; 1224 nfsd_stat_init(); /* Statistics */ 1225 retval = nfsd_reply_cache_init(); 1226 if (retval) 1227 goto out_free_stat; 1228 nfsd_lockd_init(); /* lockd->nfsd callbacks */ 1229 retval = create_proc_exports_entry(); 1230 if (retval) 1231 goto out_free_lockd; 1232 retval = register_filesystem(&nfsd_fs_type); 1233 if (retval) 1234 goto out_free_all; 1235 return 0; 1236 out_free_all: 1237 remove_proc_entry("fs/nfs/exports", NULL); 1238 remove_proc_entry("fs/nfs", NULL); 1239 out_free_lockd: 1240 nfsd_lockd_shutdown(); 1241 nfsd_reply_cache_shutdown(); 1242 out_free_stat: 1243 nfsd_stat_shutdown(); 1244 nfsd_fault_inject_cleanup(); 1245 out_free_slabs: 1246 nfsd4_free_slabs(); 1247 out_unregister_pernet: 1248 unregister_pernet_subsys(&nfsd_net_ops); 1249 out_unregister_notifier: 1250 unregister_cld_notifier(); 1251 return retval; 1252 } 1253 1254 static void __exit exit_nfsd(void) 1255 { 1256 nfsd_reply_cache_shutdown(); 1257 remove_proc_entry("fs/nfs/exports", NULL); 1258 remove_proc_entry("fs/nfs", NULL); 1259 nfsd_stat_shutdown(); 1260 nfsd_lockd_shutdown(); 1261 nfsd4_free_slabs(); 1262 nfsd_fault_inject_cleanup(); 1263 unregister_filesystem(&nfsd_fs_type); 1264 unregister_pernet_subsys(&nfsd_net_ops); 1265 unregister_cld_notifier(); 1266 } 1267 1268 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); 1269 MODULE_LICENSE("GPL"); 1270 module_init(init_nfsd) 1271 module_exit(exit_nfsd) 1272