diff options
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r-- | fs/nfsd/nfsctl.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 5ac00c4fee91..049d2a9c7715 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -450,22 +450,26 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) | |||
450 | int i; | 450 | int i; |
451 | int rv; | 451 | int rv; |
452 | int len; | 452 | int len; |
453 | int npools = nfsd_nrpools(); | 453 | int npools; |
454 | int *nthreads; | 454 | int *nthreads; |
455 | 455 | ||
456 | mutex_lock(&nfsd_mutex); | ||
457 | npools = nfsd_nrpools(); | ||
456 | if (npools == 0) { | 458 | if (npools == 0) { |
457 | /* | 459 | /* |
458 | * NFS is shut down. The admin can start it by | 460 | * NFS is shut down. The admin can start it by |
459 | * writing to the threads file but NOT the pool_threads | 461 | * writing to the threads file but NOT the pool_threads |
460 | * file, sorry. Report zero threads. | 462 | * file, sorry. Report zero threads. |
461 | */ | 463 | */ |
464 | mutex_unlock(&nfsd_mutex); | ||
462 | strcpy(buf, "0\n"); | 465 | strcpy(buf, "0\n"); |
463 | return strlen(buf); | 466 | return strlen(buf); |
464 | } | 467 | } |
465 | 468 | ||
466 | nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); | 469 | nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); |
470 | rv = -ENOMEM; | ||
467 | if (nthreads == NULL) | 471 | if (nthreads == NULL) |
468 | return -ENOMEM; | 472 | goto out_free; |
469 | 473 | ||
470 | if (size > 0) { | 474 | if (size > 0) { |
471 | for (i = 0; i < npools; i++) { | 475 | for (i = 0; i < npools; i++) { |
@@ -496,10 +500,12 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) | |||
496 | mesg += len; | 500 | mesg += len; |
497 | } | 501 | } |
498 | 502 | ||
503 | mutex_unlock(&nfsd_mutex); | ||
499 | return (mesg-buf); | 504 | return (mesg-buf); |
500 | 505 | ||
501 | out_free: | 506 | out_free: |
502 | kfree(nthreads); | 507 | kfree(nthreads); |
508 | mutex_unlock(&nfsd_mutex); | ||
503 | return rv; | 509 | return rv; |
504 | } | 510 | } |
505 | 511 | ||
@@ -566,14 +572,13 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size) | |||
566 | return len; | 572 | return len; |
567 | } | 573 | } |
568 | 574 | ||
569 | static ssize_t write_ports(struct file *file, char *buf, size_t size) | 575 | static ssize_t __write_ports(struct file *file, char *buf, size_t size) |
570 | { | 576 | { |
571 | if (size == 0) { | 577 | if (size == 0) { |
572 | int len = 0; | 578 | int len = 0; |
573 | lock_kernel(); | 579 | |
574 | if (nfsd_serv) | 580 | if (nfsd_serv) |
575 | len = svc_xprt_names(nfsd_serv, buf, 0); | 581 | len = svc_xprt_names(nfsd_serv, buf, 0); |
576 | unlock_kernel(); | ||
577 | return len; | 582 | return len; |
578 | } | 583 | } |
579 | /* Either a single 'fd' number is written, in which | 584 | /* Either a single 'fd' number is written, in which |
@@ -603,9 +608,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
603 | /* Decrease the count, but don't shutdown the | 608 | /* Decrease the count, but don't shutdown the |
604 | * the service | 609 | * the service |
605 | */ | 610 | */ |
606 | lock_kernel(); | ||
607 | nfsd_serv->sv_nrthreads--; | 611 | nfsd_serv->sv_nrthreads--; |
608 | unlock_kernel(); | ||
609 | } | 612 | } |
610 | return err < 0 ? err : 0; | 613 | return err < 0 ? err : 0; |
611 | } | 614 | } |
@@ -614,10 +617,8 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
614 | int len = 0; | 617 | int len = 0; |
615 | if (!toclose) | 618 | if (!toclose) |
616 | return -ENOMEM; | 619 | return -ENOMEM; |
617 | lock_kernel(); | ||
618 | if (nfsd_serv) | 620 | if (nfsd_serv) |
619 | len = svc_sock_names(buf, nfsd_serv, toclose); | 621 | len = svc_sock_names(buf, nfsd_serv, toclose); |
620 | unlock_kernel(); | ||
621 | if (len >= 0) | 622 | if (len >= 0) |
622 | lockd_down(); | 623 | lockd_down(); |
623 | kfree(toclose); | 624 | kfree(toclose); |
@@ -655,7 +656,6 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
655 | if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) { | 656 | if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) { |
656 | if (port == 0) | 657 | if (port == 0) |
657 | return -EINVAL; | 658 | return -EINVAL; |
658 | lock_kernel(); | ||
659 | if (nfsd_serv) { | 659 | if (nfsd_serv) { |
660 | xprt = svc_find_xprt(nfsd_serv, transport, | 660 | xprt = svc_find_xprt(nfsd_serv, transport, |
661 | AF_UNSPEC, port); | 661 | AF_UNSPEC, port); |
@@ -666,13 +666,22 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size) | |||
666 | } else | 666 | } else |
667 | err = -ENOTCONN; | 667 | err = -ENOTCONN; |
668 | } | 668 | } |
669 | unlock_kernel(); | ||
670 | return err < 0 ? err : 0; | 669 | return err < 0 ? err : 0; |
671 | } | 670 | } |
672 | } | 671 | } |
673 | return -EINVAL; | 672 | return -EINVAL; |
674 | } | 673 | } |
675 | 674 | ||
675 | static ssize_t write_ports(struct file *file, char *buf, size_t size) | ||
676 | { | ||
677 | ssize_t rv; | ||
678 | mutex_lock(&nfsd_mutex); | ||
679 | rv = __write_ports(file, buf, size); | ||
680 | mutex_unlock(&nfsd_mutex); | ||
681 | return rv; | ||
682 | } | ||
683 | |||
684 | |||
676 | int nfsd_max_blksize; | 685 | int nfsd_max_blksize; |
677 | 686 | ||
678 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) | 687 | static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) |
@@ -691,13 +700,13 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) | |||
691 | if (bsize > NFSSVC_MAXBLKSIZE) | 700 | if (bsize > NFSSVC_MAXBLKSIZE) |
692 | bsize = NFSSVC_MAXBLKSIZE; | 701 | bsize = NFSSVC_MAXBLKSIZE; |
693 | bsize &= ~(1024-1); | 702 | bsize &= ~(1024-1); |
694 | lock_kernel(); | 703 | mutex_lock(&nfsd_mutex); |
695 | if (nfsd_serv && nfsd_serv->sv_nrthreads) { | 704 | if (nfsd_serv && nfsd_serv->sv_nrthreads) { |
696 | unlock_kernel(); | 705 | mutex_unlock(&nfsd_mutex); |
697 | return -EBUSY; | 706 | return -EBUSY; |
698 | } | 707 | } |
699 | nfsd_max_blksize = bsize; | 708 | nfsd_max_blksize = bsize; |
700 | unlock_kernel(); | 709 | mutex_unlock(&nfsd_mutex); |
701 | } | 710 | } |
702 | return sprintf(buf, "%d\n", nfsd_max_blksize); | 711 | return sprintf(buf, "%d\n", nfsd_max_blksize); |
703 | } | 712 | } |