Commit 0964a3d3 authored by NeilBrown's avatar NeilBrown Committed by Linus Torvalds

[PATCH] knfsd: nfsd4 reboot dirname fix

Set the recovery directory via /proc/fs/nfsd/nfs4recoverydir.

It may be changed any time, but is used only on startup.
Signed-off-by: default avatarAndy Adamson <andros@citi.umich.edu>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: default avatarNeil Brown <neilb@cse.unsw.edu.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c7b9a459
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
#define NFSDDBG_FACILITY NFSDDBG_PROC #define NFSDDBG_FACILITY NFSDDBG_PROC
/* Globals */ /* Globals */
char recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
static struct nameidata rec_dir; static struct nameidata rec_dir;
static int rec_dir_init = 0; static int rec_dir_init = 0;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include <linux/nfs4.h> #include <linux/nfs4.h>
#include <linux/nfsd/state.h> #include <linux/nfsd/state.h>
#include <linux/nfsd/xdr4.h> #include <linux/nfsd/xdr4.h>
#include <linux/namei.h>
#define NFSDDBG_FACILITY NFSDDBG_PROC #define NFSDDBG_FACILITY NFSDDBG_PROC
...@@ -71,7 +72,8 @@ static stateid_t onestateid; /* bits all 1 */ ...@@ -71,7 +72,8 @@ static stateid_t onestateid; /* bits all 1 */
static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
static void release_stateid_lockowners(struct nfs4_stateid *open_stp); static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
extern char recovery_dirname[]; static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
static void nfs4_set_recdir(char *recdir);
/* Locking: /* Locking:
* *
...@@ -3224,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void) ...@@ -3224,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void)
{ {
int status; int status;
nfsd4_init_recdir(recovery_dirname); nfs4_lock_state();
nfsd4_init_recdir(user_recovery_dirname);
status = nfsd4_recdir_load(); status = nfsd4_recdir_load();
nfs4_unlock_state();
if (status) if (status)
printk("NFSD: Failure reading reboot recovery data\n"); printk("NFSD: Failure reading reboot recovery data\n");
} }
...@@ -3329,6 +3333,35 @@ nfs4_state_shutdown(void) ...@@ -3329,6 +3333,35 @@ nfs4_state_shutdown(void)
nfs4_unlock_state(); nfs4_unlock_state();
} }
static void
nfs4_set_recdir(char *recdir)
{
nfs4_lock_state();
strcpy(user_recovery_dirname, recdir);
nfs4_unlock_state();
}
/*
* Change the NFSv4 recovery directory to recdir.
*/
int
nfs4_reset_recoverydir(char *recdir)
{
int status;
struct nameidata nd;
status = path_lookup(recdir, LOOKUP_FOLLOW, &nd);
if (status)
return status;
status = -ENOTDIR;
if (S_ISDIR(nd.dentry->d_inode->i_mode)) {
nfs4_set_recdir(recdir);
status = 0;
}
path_release(&nd);
return status;
}
/* /*
* Called when leasetime is changed. * Called when leasetime is changed.
* *
......
...@@ -51,6 +51,7 @@ enum { ...@@ -51,6 +51,7 @@ enum {
NFSD_Fh, NFSD_Fh,
NFSD_Threads, NFSD_Threads,
NFSD_Leasetime, NFSD_Leasetime,
NFSD_RecoveryDir,
}; };
/* /*
...@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size); ...@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size);
static ssize_t write_filehandle(struct file *file, char *buf, size_t size); static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
static ssize_t write_threads(struct file *file, char *buf, size_t size); static ssize_t write_threads(struct file *file, char *buf, size_t size);
static ssize_t write_leasetime(struct file *file, char *buf, size_t size); static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
static ssize_t (*write_op[])(struct file *, char *, size_t) = { static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Svc] = write_svc, [NFSD_Svc] = write_svc,
...@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { ...@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
[NFSD_Fh] = write_filehandle, [NFSD_Fh] = write_filehandle,
[NFSD_Threads] = write_threads, [NFSD_Threads] = write_threads,
[NFSD_Leasetime] = write_leasetime, [NFSD_Leasetime] = write_leasetime,
[NFSD_RecoveryDir] = write_recoverydir,
}; };
static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) static 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,6 +352,25 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
return strlen(buf); return strlen(buf);
} }
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
{
char *mesg = buf;
char *recdir;
int len, status;
if (size > PATH_MAX || buf[size-1] != '\n')
return -EINVAL;
buf[size-1] = 0;
recdir = mesg;
len = qword_get(&mesg, recdir, size);
if (len <= 0)
return -EINVAL;
status = nfs4_reset_recoverydir(recdir);
return strlen(buf);
}
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* /*
* populating the filesystem. * populating the filesystem.
...@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) ...@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
#ifdef CONFIG_NFSD_V4 #ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR}, [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
#endif #endif
/* last one */ {""} /* last one */ {""}
}; };
......
...@@ -150,12 +150,14 @@ int nfs4_state_start(void); ...@@ -150,12 +150,14 @@ int nfs4_state_start(void);
void nfs4_state_shutdown(void); void nfs4_state_shutdown(void);
time_t nfs4_lease_time(void); time_t nfs4_lease_time(void);
void nfs4_reset_lease(time_t leasetime); void nfs4_reset_lease(time_t leasetime);
int nfs4_reset_recoverydir(char *recdir);
#else #else
static inline void nfs4_state_init(void){}; static inline void nfs4_state_init(void){};
static inline int nfs4_state_start(void){return 0;} static inline int nfs4_state_start(void){return 0;}
static inline void nfs4_state_shutdown(void){} static inline void nfs4_state_shutdown(void){}
static inline time_t nfs4_lease_time(void){return 0;} static inline time_t nfs4_lease_time(void){return 0;}
static inline void nfs4_reset_lease(time_t leasetime){} static inline void nfs4_reset_lease(time_t leasetime){}
static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
#endif #endif
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment