Skip to content

Commit 0964a3d

Browse files
NeilBrownLinus Torvalds
authored andcommitted
[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 <[email protected]> Signed-off-by: J. Bruce Fields <[email protected]> Signed-off-by: Neil Brown <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent c7b9a45 commit 0964a3d

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed

fs/nfsd/nfs4recover.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
#define NFSDDBG_FACILITY NFSDDBG_PROC
5151

5252
/* Globals */
53-
char recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
5453
static struct nameidata rec_dir;
5554
static int rec_dir_init = 0;
5655

fs/nfsd/nfs4state.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <linux/nfs4.h>
4949
#include <linux/nfsd/state.h>
5050
#include <linux/nfsd/xdr4.h>
51+
#include <linux/namei.h>
5152

5253
#define NFSDDBG_FACILITY NFSDDBG_PROC
5354

@@ -71,7 +72,8 @@ static stateid_t onestateid; /* bits all 1 */
7172
static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags);
7273
static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid);
7374
static void release_stateid_lockowners(struct nfs4_stateid *open_stp);
74-
extern char recovery_dirname[];
75+
static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
76+
static void nfs4_set_recdir(char *recdir);
7577

7678
/* Locking:
7779
*
@@ -3224,8 +3226,10 @@ nfsd4_load_reboot_recovery_data(void)
32243226
{
32253227
int status;
32263228

3227-
nfsd4_init_recdir(recovery_dirname);
3229+
nfs4_lock_state();
3230+
nfsd4_init_recdir(user_recovery_dirname);
32283231
status = nfsd4_recdir_load();
3232+
nfs4_unlock_state();
32293233
if (status)
32303234
printk("NFSD: Failure reading reboot recovery data\n");
32313235
}
@@ -3329,6 +3333,35 @@ nfs4_state_shutdown(void)
33293333
nfs4_unlock_state();
33303334
}
33313335

3336+
static void
3337+
nfs4_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+
*/
3347+
int
3348+
nfs4_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+
33323365
/*
33333366
* Called when leasetime is changed.
33343367
*

fs/nfsd/nfsctl.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ enum {
5151
NFSD_Fh,
5252
NFSD_Threads,
5353
NFSD_Leasetime,
54+
NFSD_RecoveryDir,
5455
};
5556

5657
/*
@@ -66,6 +67,7 @@ static ssize_t write_getfs(struct file *file, char *buf, size_t size);
6667
static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
6768
static ssize_t write_threads(struct file *file, char *buf, size_t size);
6869
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
70+
static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
6971

7072
static ssize_t (*write_op[])(struct file *, char *, size_t) = {
7173
[NFSD_Svc] = write_svc,
@@ -78,6 +80,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
7880
[NFSD_Fh] = write_filehandle,
7981
[NFSD_Threads] = write_threads,
8082
[NFSD_Leasetime] = write_leasetime,
83+
[NFSD_RecoveryDir] = write_recoverydir,
8184
};
8285

8386
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)
349352
return strlen(buf);
350353
}
351354

355+
static 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+
352374
/*----------------------------------------------------------------------------*/
353375
/*
354376
* populating the filesystem.
@@ -369,6 +391,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
369391
[NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
370392
#ifdef CONFIG_NFSD_V4
371393
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
394+
[NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
372395
#endif
373396
/* last one */ {""}
374397
};

include/linux/nfsd/nfsd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,14 @@ int nfs4_state_start(void);
150150
void nfs4_state_shutdown(void);
151151
time_t nfs4_lease_time(void);
152152
void nfs4_reset_lease(time_t leasetime);
153+
int nfs4_reset_recoverydir(char *recdir);
153154
#else
154155
static inline void nfs4_state_init(void){};
155156
static inline int nfs4_state_start(void){return 0;}
156157
static inline void nfs4_state_shutdown(void){}
157158
static inline time_t nfs4_lease_time(void){return 0;}
158159
static inline void nfs4_reset_lease(time_t leasetime){}
160+
static inline int nfs4_reset_recoverydir(char *recdir) {return 0;}
159161
#endif
160162

161163
/*

0 commit comments

Comments
 (0)