diff options
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r-- | fs/nfsd/nfsctl.c | 49 |
1 files changed, 43 insertions, 6 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 5c6a477c20ec..39aed901514b 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -57,6 +57,7 @@ enum { | |||
57 | NFSD_Pool_Threads, | 57 | NFSD_Pool_Threads, |
58 | NFSD_Versions, | 58 | NFSD_Versions, |
59 | NFSD_Ports, | 59 | NFSD_Ports, |
60 | NFSD_MaxBlkSize, | ||
60 | /* | 61 | /* |
61 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] | 62 | * The below MUST come last. Otherwise we leave a hole in nfsd_files[] |
62 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops | 63 | * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops |
@@ -82,6 +83,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size); | |||
82 | static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); | 83 | static ssize_t write_pool_threads(struct file *file, char *buf, size_t size); |
83 | static ssize_t write_versions(struct file *file, char *buf, size_t size); | 84 | static ssize_t write_versions(struct file *file, char *buf, size_t size); |
84 | static ssize_t write_ports(struct file *file, char *buf, size_t size); | 85 | static ssize_t write_ports(struct file *file, char *buf, size_t size); |
86 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size); | ||
85 | #ifdef CONFIG_NFSD_V4 | 87 | #ifdef CONFIG_NFSD_V4 |
86 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); | 88 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); |
87 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); | 89 | static ssize_t write_recoverydir(struct file *file, char *buf, size_t size); |
@@ -100,6 +102,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { | |||
100 | [NFSD_Pool_Threads] = write_pool_threads, | 102 | [NFSD_Pool_Threads] = write_pool_threads, |
101 | [NFSD_Versions] = write_versions, | 103 | [NFSD_Versions] = write_versions, |
102 | [NFSD_Ports] = write_ports, | 104 | [NFSD_Ports] = write_ports, |
105 | [NFSD_MaxBlkSize] = write_maxblksize, | ||
103 | #ifdef CONFIG_NFSD_V4 | 106 | #ifdef CONFIG_NFSD_V4 |
104 | [NFSD_Leasetime] = write_leasetime, | 107 | [NFSD_Leasetime] = write_leasetime, |
105 | [NFSD_RecoveryDir] = write_recoverydir, | 108 | [NFSD_RecoveryDir] = write_recoverydir, |
@@ -523,18 +526,20 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
523 | err = nfsd_create_serv(); | 526 | err = nfsd_create_serv(); |
524 | if (!err) { | 527 | if (!err) { |
525 | int proto = 0; | 528 | int proto = 0; |
526 | err = lockd_up(proto); | 529 | err = svc_addsock(nfsd_serv, fd, buf, &proto); |
527 | if (!err) { | 530 | if (err >= 0) { |
528 | err = svc_addsock(nfsd_serv, fd, buf, &proto); | 531 | err = lockd_up(proto); |
529 | if (err) | 532 | if (err < 0) |
530 | lockd_down(); | 533 | svc_sock_names(buf+strlen(buf)+1, nfsd_serv, buf); |
531 | } | 534 | } |
532 | /* Decrease the count, but don't shutdown the | 535 | /* Decrease the count, but don't shutdown the |
533 | * the service | 536 | * the service |
534 | */ | 537 | */ |
538 | lock_kernel(); | ||
535 | nfsd_serv->sv_nrthreads--; | 539 | nfsd_serv->sv_nrthreads--; |
540 | unlock_kernel(); | ||
536 | } | 541 | } |
537 | return err; | 542 | return err < 0 ? err : 0; |
538 | } | 543 | } |
539 | if (buf[0] == '-') { | 544 | if (buf[0] == '-') { |
540 | char *toclose = kstrdup(buf+1, GFP_KERNEL); | 545 | char *toclose = kstrdup(buf+1, GFP_KERNEL); |
@@ -545,12 +550,43 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
545 | if (nfsd_serv) | 550 | if (nfsd_serv) |
546 | len = svc_sock_names(buf, nfsd_serv, toclose); | 551 | len = svc_sock_names(buf, nfsd_serv, toclose); |
547 | unlock_kernel(); | 552 | unlock_kernel(); |
553 | if (len >= 0) | ||
554 | lockd_down(); | ||
548 | kfree(toclose); | 555 | kfree(toclose); |
549 | return len; | 556 | return len; |
550 | } | 557 | } |
551 | return -EINVAL; | 558 | return -EINVAL; |
552 | } | 559 | } |
553 | 560 | ||
561 | int nfsd_max_blksize; | ||
562 | |||
563 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) | ||
564 | { | ||
565 | char *mesg = buf; | ||
566 | if (size > 0) { | ||
567 | int bsize; | ||
568 | int rv = get_int(&mesg, &bsize); | ||
569 | if (rv) | ||
570 | return rv; | ||
571 | /* force bsize into allowed range and | ||
572 | * required alignment. | ||
573 | */ | ||
574 | if (bsize < 1024) | ||
575 | bsize = 1024; | ||
576 | if (bsize > NFSSVC_MAXBLKSIZE) | ||
577 | bsize = NFSSVC_MAXBLKSIZE; | ||
578 | bsize &= ~(1024-1); | ||
579 | lock_kernel(); | ||
580 | if (nfsd_serv && nfsd_serv->sv_nrthreads) { | ||
581 | unlock_kernel(); | ||
582 | return -EBUSY; | ||
583 | } | ||
584 | nfsd_max_blksize = bsize; | ||
585 | unlock_kernel(); | ||
586 | } | ||
587 | return sprintf(buf, "%d\n", nfsd_max_blksize); | ||
588 | } | ||
589 | |||
554 | #ifdef CONFIG_NFSD_V4 | 590 | #ifdef CONFIG_NFSD_V4 |
555 | extern time_t nfs4_leasetime(void); | 591 | extern time_t nfs4_leasetime(void); |
556 | 592 | ||
@@ -616,6 +652,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
616 | [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, | 652 | [NFSD_Pool_Threads] = {"pool_threads", &transaction_ops, S_IWUSR|S_IRUSR}, |
617 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, | 653 | [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR}, |
618 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, | 654 | [NFSD_Ports] = {"portlist", &transaction_ops, S_IWUSR|S_IRUGO}, |
655 | [NFSD_MaxBlkSize] = {"max_block_size", &transaction_ops, S_IWUSR|S_IRUGO}, | ||
619 | #ifdef CONFIG_NFSD_V4 | 656 | #ifdef CONFIG_NFSD_V4 |
620 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, | 657 | [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, |
621 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, | 658 | [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR}, |