aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsctl.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2008-06-10 08:40:35 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-06-23 13:02:49 -0400
commitbedbdd8bada194a690d2901801bf8451965086b3 (patch)
treedc7ea15dd52370429bd63cd6803d6402cebbd50b /fs/nfsd/nfsctl.c
parent0d169ca136357d51a65d686f3c84866a8ba20ae9 (diff)
knfsd: Replace lock_kernel with a mutex for nfsd thread startup/shutdown locking.
This removes the BKL from the RPC service creation codepath. The BKL really isn't adequate for this job since some of this info needs protection across sleeps. Also, add some comments to try and clarify how the locking should work and to make it clear that the BKL isn't necessary as long as there is adequate locking between tasks when touching the svc_serv fields. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r--fs/nfsd/nfsctl.c37
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
501out_free: 506out_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
569static ssize_t write_ports(struct file *file, char *buf, size_t size) 575static 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
675static 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
676int nfsd_max_blksize; 685int nfsd_max_blksize;
677 686
678static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 687static 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}