[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: Andy Adamson <andros@citi.umich.edu> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
c7b9a45927
commit
0964a3d3f1
4 changed files with 60 additions and 3 deletions
|
@ -50,7 +50,6 @@
|
|||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
/* Globals */
|
||||
char recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
|
||||
static struct nameidata rec_dir;
|
||||
static int rec_dir_init = 0;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <linux/nfs4.h>
|
||||
#include <linux/nfsd/state.h>
|
||||
#include <linux/nfsd/xdr4.h>
|
||||
#include <linux/namei.h>
|
||||
|
||||
#define NFSDDBG_FACILITY NFSDDBG_PROC
|
||||
|
||||
|
@ -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_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
|
||||
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:
|
||||
*
|
||||
|
@ -3224,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void)
|
|||
{
|
||||
int status;
|
||||
|
||||
nfsd4_init_recdir(recovery_dirname);
|
||||
nfs4_lock_state();
|
||||
nfsd4_init_recdir(user_recovery_dirname);
|
||||
status = nfsd4_recdir_load();
|
||||
nfs4_unlock_state();
|
||||
if (status)
|
||||
printk("NFSD: Failure reading reboot recovery data\n");
|
||||
}
|
||||
|
@ -3329,6 +3333,35 @@ nfs4_state_shutdown(void)
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -51,6 +51,7 @@ enum {
|
|||
NFSD_Fh,
|
||||
NFSD_Threads,
|
||||
NFSD_Leasetime,
|
||||
NFSD_RecoveryDir,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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_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_recoverydir(struct file *file, char *buf, size_t size);
|
||||
|
||||
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
|
||||
[NFSD_Svc] = write_svc,
|
||||
|
@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
|
|||
[NFSD_Fh] = write_filehandle,
|
||||
[NFSD_Threads] = write_threads,
|
||||
[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)
|
||||
|
@ -349,6 +352,25 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
|
|||
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.
|
||||
|
@ -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},
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
|
||||
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
|
||||
#endif
|
||||
/* last one */ {""}
|
||||
};
|
||||
|
|
|
@ -150,12 +150,14 @@ int nfs4_state_start(void);
|
|||
void nfs4_state_shutdown(void);
|
||||
time_t nfs4_lease_time(void);
|
||||
void nfs4_reset_lease(time_t leasetime);
|
||||
int nfs4_reset_recoverydir(char *recdir);
|
||||
#else
|
||||
static inline void nfs4_state_init(void){};
|
||||
static inline int nfs4_state_start(void){return 0;}
|
||||
static inline void nfs4_state_shutdown(void){}
|
||||
static inline time_t nfs4_lease_time(void){return 0;}
|
||||
static inline void nfs4_reset_lease(time_t leasetime){}
|
||||
static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue