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