aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-06-10 08:40:36 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-06-23 13:02:49 -0400
commit3dd98a3bccb1bdd30b8a4a755e7bead1b64160ec (patch)
tree53b124bc44b33330102ef73f170fa91e785633bc
parentbedbdd8bada194a690d2901801bf8451965086b3 (diff)
knfsd: clean up nfsd filesystem interfaces
Several of the nfsd filesystem interfaces allow changes to parameters that don't have any effect on a running nfsd service. They are only ever checked when nfsd is started. This patch fixes it so that changes to those procfiles return -EBUSY if nfsd is already running to make it clear that changes on the fly don't work. The patch should also close some relatively harmless races between changing the info in those interfaces and starting nfsd, since these variables are being moved under the protection of the nfsd_mutex. Finally, the nfsv4recoverydir file always returns -EINVAL if read. This patch fixes it to return the recoverydir path as expected. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfs4state.c17
-rw-r--r--fs/nfsd/nfsctl.c66
-rw-r--r--fs/nfsd/nfssvc.c8
3 files changed, 74 insertions, 17 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5c97d47676ae..bf11d6879ab4 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3249,12 +3249,14 @@ nfs4_state_shutdown(void)
3249 nfs4_unlock_state(); 3249 nfs4_unlock_state();
3250} 3250}
3251 3251
3252/*
3253 * user_recovery_dirname is protected by the nfsd_mutex since it's only
3254 * accessed when nfsd is starting.
3255 */
3252static void 3256static void
3253nfs4_set_recdir(char *recdir) 3257nfs4_set_recdir(char *recdir)
3254{ 3258{
3255 nfs4_lock_state();
3256 strcpy(user_recovery_dirname, recdir); 3259 strcpy(user_recovery_dirname, recdir);
3257 nfs4_unlock_state();
3258} 3260}
3259 3261
3260/* 3262/*
@@ -3278,6 +3280,12 @@ nfs4_reset_recoverydir(char *recdir)
3278 return status; 3280 return status;
3279} 3281}
3280 3282
3283char *
3284nfs4_recoverydir(void)
3285{
3286 return user_recovery_dirname;
3287}
3288
3281/* 3289/*
3282 * Called when leasetime is changed. 3290 * Called when leasetime is changed.
3283 * 3291 *
@@ -3286,11 +3294,12 @@ nfs4_reset_recoverydir(char *recdir)
3286 * we start to register any changes in lease time. If the administrator 3294 * we start to register any changes in lease time. If the administrator
3287 * really wants to change the lease time *now*, they can go ahead and bring 3295 * really wants to change the lease time *now*, they can go ahead and bring
3288 * nfsd down and then back up again after changing the lease time. 3296 * nfsd down and then back up again after changing the lease time.
3297 *
3298 * user_lease_time is protected by nfsd_mutex since it's only really accessed
3299 * when nfsd is starting
3289 */ 3300 */
3290void 3301void
3291nfs4_reset_lease(time_t leasetime) 3302nfs4_reset_lease(time_t leasetime)
3292{ 3303{
3293 lock_kernel();
3294 user_lease_time = leasetime; 3304 user_lease_time = leasetime;
3295 unlock_kernel();
3296} 3305}
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 049d2a9c7715..2c2eb8796c10 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -509,7 +509,7 @@ out_free:
509 return rv; 509 return rv;
510} 510}
511 511
512static ssize_t write_versions(struct file *file, char *buf, size_t size) 512static ssize_t __write_versions(struct file *file, char *buf, size_t size)
513{ 513{
514 /* 514 /*
515 * Format: 515 * Format:
@@ -572,6 +572,16 @@ static ssize_t write_versions(struct file *file, char *buf, size_t size)
572 return len; 572 return len;
573} 573}
574 574
575static ssize_t write_versions(struct file *file, char *buf, size_t size)
576{
577 ssize_t rv;
578
579 mutex_lock(&nfsd_mutex);
580 rv = __write_versions(file, buf, size);
581 mutex_unlock(&nfsd_mutex);
582 return rv;
583}
584
575static ssize_t __write_ports(struct file *file, char *buf, size_t size) 585static ssize_t __write_ports(struct file *file, char *buf, size_t size)
576{ 586{
577 if (size == 0) { 587 if (size == 0) {
@@ -675,6 +685,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size)
675static ssize_t write_ports(struct file *file, char *buf, size_t size) 685static ssize_t write_ports(struct file *file, char *buf, size_t size)
676{ 686{
677 ssize_t rv; 687 ssize_t rv;
688
678 mutex_lock(&nfsd_mutex); 689 mutex_lock(&nfsd_mutex);
679 rv = __write_ports(file, buf, size); 690 rv = __write_ports(file, buf, size);
680 mutex_unlock(&nfsd_mutex); 691 mutex_unlock(&nfsd_mutex);
@@ -714,16 +725,17 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
714#ifdef CONFIG_NFSD_V4 725#ifdef CONFIG_NFSD_V4
715extern time_t nfs4_leasetime(void); 726extern time_t nfs4_leasetime(void);
716 727
717static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 728static ssize_t __write_leasetime(struct file *file, char *buf, size_t size)
718{ 729{
719 /* if size > 10 seconds, call 730 /* if size > 10 seconds, call
720 * nfs4_reset_lease() then write out the new lease (seconds) as reply 731 * nfs4_reset_lease() then write out the new lease (seconds) as reply
721 */ 732 */
722 char *mesg = buf; 733 char *mesg = buf;
723 int rv; 734 int rv, lease;
724 735
725 if (size > 0) { 736 if (size > 0) {
726 int lease; 737 if (nfsd_serv)
738 return -EBUSY;
727 rv = get_int(&mesg, &lease); 739 rv = get_int(&mesg, &lease);
728 if (rv) 740 if (rv)
729 return rv; 741 return rv;
@@ -735,24 +747,52 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
735 return strlen(buf); 747 return strlen(buf);
736} 748}
737 749
738static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 750static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
751{
752 ssize_t rv;
753
754 mutex_lock(&nfsd_mutex);
755 rv = __write_leasetime(file, buf, size);
756 mutex_unlock(&nfsd_mutex);
757 return rv;
758}
759
760extern char *nfs4_recoverydir(void);
761
762static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size)
739{ 763{
740 char *mesg = buf; 764 char *mesg = buf;
741 char *recdir; 765 char *recdir;
742 int len, status; 766 int len, status;
743 767
744 if (size == 0 || size > PATH_MAX || buf[size-1] != '\n') 768 if (size > 0) {
745 return -EINVAL; 769 if (nfsd_serv)
746 buf[size-1] = 0; 770 return -EBUSY;
771 if (size > PATH_MAX || buf[size-1] != '\n')
772 return -EINVAL;
773 buf[size-1] = 0;
747 774
748 recdir = mesg; 775 recdir = mesg;
749 len = qword_get(&mesg, recdir, size); 776 len = qword_get(&mesg, recdir, size);
750 if (len <= 0) 777 if (len <= 0)
751 return -EINVAL; 778 return -EINVAL;
752 779
753 status = nfs4_reset_recoverydir(recdir); 780 status = nfs4_reset_recoverydir(recdir);
781 }
782 sprintf(buf, "%s\n", nfs4_recoverydir());
754 return strlen(buf); 783 return strlen(buf);
755} 784}
785
786static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
787{
788 ssize_t rv;
789
790 mutex_lock(&nfsd_mutex);
791 rv = __write_recoverydir(file, buf, size);
792 mutex_unlock(&nfsd_mutex);
793 return rv;
794}
795
756#endif 796#endif
757 797
758/*----------------------------------------------------------------------------*/ 798/*----------------------------------------------------------------------------*/
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 512bd04c6dda..929af233510e 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -70,6 +70,14 @@ static DEFINE_SPINLOCK(nfsd_call_lock);
70 * Transitions of the thread count between zero and non-zero are of particular 70 * Transitions of the thread count between zero and non-zero are of particular
71 * interest since the svc_serv needs to be created and initialized at that 71 * interest since the svc_serv needs to be created and initialized at that
72 * point, or freed. 72 * point, or freed.
73 *
74 * Finally, the nfsd_mutex also protects some of the global variables that are
75 * accessed when nfsd starts and that are settable via the write_* routines in
76 * nfsctl.c. In particular:
77 *
78 * user_recovery_dirname
79 * user_lease_time
80 * nfsd_versions
73 */ 81 */
74DEFINE_MUTEX(nfsd_mutex); 82DEFINE_MUTEX(nfsd_mutex);
75struct svc_serv *nfsd_serv; 83struct svc_serv *nfsd_serv;