aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r--fs/nfsd/nfsctl.c118
1 files changed, 86 insertions, 32 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 5ac00c4fee91..1955a2702e60 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -310,9 +310,12 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size)
310 310
311static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size) 311static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
312{ 312{
313 __be32 server_ip; 313 struct sockaddr_in sin = {
314 char *fo_path, c; 314 .sin_family = AF_INET,
315 };
315 int b1, b2, b3, b4; 316 int b1, b2, b3, b4;
317 char c;
318 char *fo_path;
316 319
317 /* sanity check */ 320 /* sanity check */
318 if (size == 0) 321 if (size == 0)
@@ -326,11 +329,13 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
326 return -EINVAL; 329 return -EINVAL;
327 330
328 /* get ipv4 address */ 331 /* get ipv4 address */
329 if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4) 332 if (sscanf(fo_path, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) != 4)
330 return -EINVAL; 333 return -EINVAL;
331 server_ip = htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); 334 if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255)
335 return -EINVAL;
336 sin.sin_addr.s_addr = htonl((b1 << 24) | (b2 << 16) | (b3 << 8) | b4);
332 337
333 return nlmsvc_unlock_all_by_ip(server_ip); 338 return nlmsvc_unlock_all_by_ip((struct sockaddr *)&sin);
334} 339}
335 340
336static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size) 341static ssize_t failover_unlock_fs(struct file *file, char *buf, size_t size)
@@ -450,22 +455,26 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
450 int i; 455 int i;
451 int rv; 456 int rv;
452 int len; 457 int len;
453 int npools = nfsd_nrpools(); 458 int npools;
454 int *nthreads; 459 int *nthreads;
455 460
461 mutex_lock(&nfsd_mutex);
462 npools = nfsd_nrpools();
456 if (npools == 0) { 463 if (npools == 0) {
457 /* 464 /*
458 * NFS is shut down. The admin can start it by 465 * NFS is shut down. The admin can start it by
459 * writing to the threads file but NOT the pool_threads 466 * writing to the threads file but NOT the pool_threads
460 * file, sorry. Report zero threads. 467 * file, sorry. Report zero threads.
461 */ 468 */
469 mutex_unlock(&nfsd_mutex);
462 strcpy(buf, "0\n"); 470 strcpy(buf, "0\n");
463 return strlen(buf); 471 return strlen(buf);
464 } 472 }
465 473
466 nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); 474 nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL);
475 rv = -ENOMEM;
467 if (nthreads == NULL) 476 if (nthreads == NULL)
468 return -ENOMEM; 477 goto out_free;
469 478
470 if (size > 0) { 479 if (size > 0) {
471 for (i = 0; i < npools; i++) { 480 for (i = 0; i < npools; i++) {
@@ -496,14 +505,16 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
496 mesg += len; 505 mesg += len;
497 } 506 }
498 507
508 mutex_unlock(&nfsd_mutex);
499 return (mesg-buf); 509 return (mesg-buf);
500 510
501out_free: 511out_free:
502 kfree(nthreads); 512 kfree(nthreads);
513 mutex_unlock(&nfsd_mutex);
503 return rv; 514 return rv;
504} 515}
505 516
506static ssize_t write_versions(struct file *file, char *buf, size_t size) 517static ssize_t __write_versions(struct file *file, char *buf, size_t size)
507{ 518{
508 /* 519 /*
509 * Format: 520 * Format:
@@ -566,14 +577,23 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
566 return len; 577 return len;
567} 578}
568 579
569static ssize_t write_ports(struct file *file, char *buf, size_t size) 580static ssize_t write_versions(struct file *file, char *buf, size_t size)
581{
582 ssize_t rv;
583
584 mutex_lock(&nfsd_mutex);
585 rv = __write_versions(file, buf, size);
586 mutex_unlock(&nfsd_mutex);
587 return rv;
588}
589
590static ssize_t __write_ports(struct file *file, char *buf, size_t size)
570{ 591{
571 if (size == 0) { 592 if (size == 0) {
572 int len = 0; 593 int len = 0;
573 lock_kernel(); 594
574 if (nfsd_serv) 595 if (nfsd_serv)
575 len = svc_xprt_names(nfsd_serv, buf, 0); 596 len = svc_xprt_names(nfsd_serv, buf, 0);
576 unlock_kernel();
577 return len; 597 return len;
578 } 598 }
579 /* Either a single 'fd' number is written, in which 599 /* Either a single 'fd' number is written, in which
@@ -603,9 +623,7 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
603 /* Decrease the count, but don't shutdown the 623 /* Decrease the count, but don't shutdown the
604 * the service 624 * the service
605 */ 625 */
606 lock_kernel();
607 nfsd_serv->sv_nrthreads--; 626 nfsd_serv->sv_nrthreads--;
608 unlock_kernel();
609 } 627 }
610 return err < 0 ? err : 0; 628 return err < 0 ? err : 0;
611 } 629 }
@@ -614,10 +632,8 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
614 int len = 0; 632 int len = 0;
615 if (!toclose) 633 if (!toclose)
616 return -ENOMEM; 634 return -ENOMEM;
617 lock_kernel();
618 if (nfsd_serv) 635 if (nfsd_serv)
619 len = svc_sock_names(buf, nfsd_serv, toclose); 636 len = svc_sock_names(buf, nfsd_serv, toclose);
620 unlock_kernel();
621 if (len >= 0) 637 if (len >= 0)
622 lockd_down(); 638 lockd_down();
623 kfree(toclose); 639 kfree(toclose);
@@ -655,7 +671,6 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
655 if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) { 671 if (sscanf(&buf[1], "%15s %4d", transport, &port) == 2) {
656 if (port == 0) 672 if (port == 0)
657 return -EINVAL; 673 return -EINVAL;
658 lock_kernel();
659 if (nfsd_serv) { 674 if (nfsd_serv) {
660 xprt = svc_find_xprt(nfsd_serv, transport, 675 xprt = svc_find_xprt(nfsd_serv, transport,
661 AF_UNSPEC, port); 676 AF_UNSPEC, port);
@@ -666,13 +681,23 @@ static ssize_t write_ports(struct file *file, char *buf, size_t size)
666 } else 681 } else
667 err = -ENOTCONN; 682 err = -ENOTCONN;
668 } 683 }
669 unlock_kernel();
670 return err < 0 ? err : 0; 684 return err < 0 ? err : 0;
671 } 685 }
672 } 686 }
673 return -EINVAL; 687 return -EINVAL;
674} 688}
675 689
690static ssize_t write_ports(struct file *file, char *buf, size_t size)
691{
692 ssize_t rv;
693
694 mutex_lock(&nfsd_mutex);
695 rv = __write_ports(file, buf, size);
696 mutex_unlock(&nfsd_mutex);
697 return rv;
698}
699
700
676int nfsd_max_blksize; 701int nfsd_max_blksize;
677 702
678static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 703static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
@@ -691,13 +716,13 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
691 if (bsize > NFSSVC_MAXBLKSIZE) 716 if (bsize > NFSSVC_MAXBLKSIZE)
692 bsize = NFSSVC_MAXBLKSIZE; 717 bsize = NFSSVC_MAXBLKSIZE;
693 bsize &= ~(1024-1); 718 bsize &= ~(1024-1);
694 lock_kernel(); 719 mutex_lock(&nfsd_mutex);
695 if (nfsd_serv && nfsd_serv->sv_nrthreads) { 720 if (nfsd_serv && nfsd_serv->sv_nrthreads) {
696 unlock_kernel(); 721 mutex_unlock(&nfsd_mutex);
697 return -EBUSY; 722 return -EBUSY;
698 } 723 }
699 nfsd_max_blksize = bsize; 724 nfsd_max_blksize = bsize;
700 unlock_kernel(); 725 mutex_unlock(&nfsd_mutex);
701 } 726 }
702 return sprintf(buf, "%d\n", nfsd_max_blksize); 727 return sprintf(buf, "%d\n", nfsd_max_blksize);
703} 728}
@@ -705,16 +730,17 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
705#ifdef CONFIG_NFSD_V4 730#ifdef CONFIG_NFSD_V4
706extern time_t nfs4_leasetime(void); 731extern time_t nfs4_leasetime(void);
707 732
708static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 733static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
709{ 734{
710 /* if size > 10 seconds, call 735 /* if size > 10 seconds, call
711 * nfs4_reset_lease() then write out the new lease (seconds) as reply 736 * nfs4_reset_lease() then write out the new lease (seconds) as reply
712 */ 737 */
713 char *mesg = buf; 738 char *mesg = buf;
714 int rv; 739 int rv, lease;
715 740
716 if (size > 0) { 741 if (size > 0) {
717 int lease; 742 if (nfsd_serv)
743 return -EBUSY;
718 rv = get_int(&mesg, &lease); 744 rv = get_int(&mesg, &lease);
719 if (rv) 745 if (rv)
720 return rv; 746 return rv;
@@ -726,24 +752,52 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
726 return strlen(buf); 752 return strlen(buf);
727} 753}
728 754
729static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 755static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
756{
757 ssize_t rv;
758
759 mutex_lock(&nfsd_mutex);
760 rv = __write_leasetime(file, buf, size);
761 mutex_unlock(&nfsd_mutex);
762 return rv;
763}
764
765extern char *nfs4_recoverydir(void);
766
767static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
730{ 768{
731 char *mesg = buf; 769 char *mesg = buf;
732 char *recdir; 770 char *recdir;
733 int len, status; 771 int len, status;
734 772
735 if (size == 0 || size > PATH_MAX || buf[size-1] != '\n') 773 if (size > 0) {
736 return -EINVAL; 774 if (nfsd_serv)
737 buf[size-1] = 0; 775 return -EBUSY;
776 if (size > PATH_MAX || buf[size-1] != '\n')
777 return -EINVAL;
778 buf[size-1] = 0;
738 779
739 recdir = mesg; 780 recdir = mesg;
740 len = qword_get(&mesg, recdir, size); 781 len = qword_get(&mesg, recdir, size);
741 if (len <= 0) 782 if (len <= 0)
742 return -EINVAL; 783 return -EINVAL;
743 784
744 status = nfs4_reset_recoverydir(recdir); 785 status = nfs4_reset_recoverydir(recdir);
786 }
787 sprintf(buf, "%s\n", nfs4_recoverydir());
745 return strlen(buf); 788 return strlen(buf);
746} 789}
790
791static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
792{
793 ssize_t rv;
794
795 mutex_lock(&nfsd_mutex);
796 rv = __write_recoverydir(file, buf, size);
797 mutex_unlock(&nfsd_mutex);
798 return rv;
799}
800
747#endif 801#endif
748 802
749/*----------------------------------------------------------------------------*/ 803/*----------------------------------------------------------------------------*/