aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/nfs4recover.c1
-rw-r--r--fs/nfsd/nfs4state.c37
-rw-r--r--fs/nfsd/nfsctl.c23
-rw-r--r--include/linux/nfsd/nfsd.h2
4 files changed, 60 insertions, 3 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 2805c5245eac..095f1740f3ae 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -50,7 +50,6 @@
50#define NFSDDBG_FACILITY NFSDDBG_PROC 50#define NFSDDBG_FACILITY NFSDDBG_PROC
51 51
52/* Globals */ 52/* Globals */
53char recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
54static struct nameidata rec_dir; 53static struct nameidata rec_dir;
55static int rec_dir_init = 0; 54static int rec_dir_init = 0;
56 55
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 6cca358cd650..89e36526d7f2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -48,6 +48,7 @@
48#include <linux/nfs4.h> 48#include <linux/nfs4.h>
49#include <linux/nfsd/state.h> 49#include <linux/nfsd/state.h>
50#include <linux/nfsd/xdr4.h> 50#include <linux/nfsd/xdr4.h>
51#include <linux/namei.h>
51 52
52#define NFSDDBG_FACILITY NFSDDBG_PROC 53#define NFSDDBG_FACILITY NFSDDBG_PROC
53 54
@@ -71,7 +72,8 @@ static stateid_t onestateid; /* bits all 1 */
71static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); 72static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
72static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); 73static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
73static void release_stateid_lockowners(struct nfs4_stateid *open_stp); 74static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
74extern char recovery_dirname[]; 75static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
76static void nfs4_set_recdir(char *recdir);
75 77
76/* Locking: 78/* Locking:
77 * 79 *
@@ -3224,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void)
3224{ 3226{
3225 int status; 3227 int status;
3226 3228
3227 nfsd4_init_recdir(recovery_dirname); 3229 nfs4_lock_state();
3230 nfsd4_init_recdir(user_recovery_dirname);
3228 status = nfsd4_recdir_load(); 3231 status = nfsd4_recdir_load();
3232 nfs4_unlock_state();
3229 if (status) 3233 if (status)
3230 printk("NFSD: Failure reading reboot recovery data\n"); 3234 printk("NFSD: Failure reading reboot recovery data\n");
3231} 3235}
@@ -3329,6 +3333,35 @@ nfs4_state_shutdown(void)
3329 nfs4_unlock_state(); 3333 nfs4_unlock_state();
3330} 3334}
3331 3335
3336static void
3337nfs4_set_recdir(char *recdir)
3338{
3339 nfs4_lock_state();
3340 strcpy(user_recovery_dirname, recdir);
3341 nfs4_unlock_state();
3342}
3343
3344/*
3345 * Change the NFSv4 recovery directory to recdir.
3346 */
3347int
3348nfs4_reset_recoverydir(char *recdir)
3349{
3350 int status;
3351 struct nameidata nd;
3352
3353 status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
3354 if (status)
3355 return status;
3356 status = -ENOTDIR;
3357 if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
3358 nfs4_set_recdir(recdir);
3359 status = 0;
3360 }
3361 path_release(&nd);
3362 return status;
3363}
3364
3332/* 3365/*
3333 * Called when leasetime is changed. 3366 * Called when leasetime is changed.
3334 * 3367 *
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 3da43a3ed32c..841c562991e8 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -51,6 +51,7 @@ enum {
51 NFSD_Fh, 51 NFSD_Fh,
52 NFSD_Threads, 52 NFSD_Threads,
53 NFSD_Leasetime, 53 NFSD_Leasetime,
54 NFSD_RecoveryDir,
54}; 55};
55 56
56/* 57/*
@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size);
66static ssize_t write_filehandle(struct file *file, char *buf, size_t size); 67static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
67static ssize_t write_threads(struct file *file, char *buf, size_t size); 68static ssize_t write_threads(struct file *file, char *buf, size_t size);
68static ssize_t write_leasetime(struct file *file, char *buf, size_t size); 69static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
70static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
69 71
70static ssize_t (*write_op[])(struct file *, char *, size_t) = { 72static ssize_t (*write_op[])(struct file *, char *, size_t) = {
71 [NFSD_Svc] = write_svc, 73 [NFSD_Svc] = write_svc,
@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
78 [NFSD_Fh] = write_filehandle, 80 [NFSD_Fh] = write_filehandle,
79 [NFSD_Threads] = write_threads, 81 [NFSD_Threads] = write_threads,
80 [NFSD_Leasetime] = write_leasetime, 82 [NFSD_Leasetime] = write_leasetime,
83 [NFSD_RecoveryDir] = write_recoverydir,
81}; 84};
82 85
83static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 86static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -349,6 +352,25 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
349 return strlen(buf); 352 return strlen(buf);
350} 353}
351 354
355static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
356{
357 char *mesg = buf;
358 char *recdir;
359 int len, status;
360
361 if (size > PATH_MAX || buf[size-1] != '\n')
362 return -EINVAL;
363 buf[size-1] = 0;
364
365 recdir = mesg;
366 len = qword_get(&mesg, recdir, size);
367 if (len <= 0)
368 return -EINVAL;
369
370 status = nfs4_reset_recoverydir(recdir);
371 return strlen(buf);
372}
373
352/*----------------------------------------------------------------------------*/ 374/*----------------------------------------------------------------------------*/
353/* 375/*
354 * populating the filesystem. 376 * populating the filesystem.
@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
369 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, 391 [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
370#ifdef CONFIG_NFSD_V4 392#ifdef CONFIG_NFSD_V4
371 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, 393 [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
394 [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
372#endif 395#endif
373 /* last one */ {""} 396 /* last one */ {""}
374 }; 397 };
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index 21c6e9d86e4f..5791dfd30dd0 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -150,12 +150,14 @@ int nfs4_state_start(void);
150void nfs4_state_shutdown(void); 150void nfs4_state_shutdown(void);
151time_t nfs4_lease_time(void); 151time_t nfs4_lease_time(void);
152void nfs4_reset_lease(time_t leasetime); 152void nfs4_reset_lease(time_t leasetime);
153int nfs4_reset_recoverydir(char *recdir);
153#else 154#else
154static inline void nfs4_state_init(void){}; 155static inline void nfs4_state_init(void){};
155static inline int nfs4_state_start(void){return 0;} 156static inline int nfs4_state_start(void){return 0;}
156static inline void nfs4_state_shutdown(void){} 157static inline void nfs4_state_shutdown(void){}
157static inline time_t nfs4_lease_time(void){return 0;} 158static inline time_t nfs4_lease_time(void){return 0;}
158static inline void nfs4_reset_lease(time_t leasetime){} 159static inline void nfs4_reset_lease(time_t leasetime){}
160static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
159#endif 161#endif
160 162
161/* 163/*