diff options
author | NeilBrown <neilb@cse.unsw.edu.au> | 2005-06-24 01:04:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 03:06:36 -0400 |
commit | 0964a3d3f1aa96468091924f6b0c391a46dc6d0b (patch) | |
tree | 0a6b0587d1922d64ca7e4aa7f306ad869bccf452 /fs/nfsd | |
parent | c7b9a45927e74c81d6562153f7fde9d32da00159 (diff) |
[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>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4recover.c | 1 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 37 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 23 |
3 files changed, 58 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 */ |
53 | char recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; | ||
54 | static struct nameidata rec_dir; | 53 | static struct nameidata rec_dir; |
55 | static int rec_dir_init = 0; | 54 | static 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 */ | |||
71 | static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); | 72 | static struct nfs4_stateid * find_stateid(stateid_t *stid, int flags); |
72 | static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); | 73 | static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, stateid_t *stid); |
73 | static void release_stateid_lockowners(struct nfs4_stateid *open_stp); | 74 | 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); | ||
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 | ||
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 | |||
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); | |||
66 | static ssize_t write_filehandle(struct file *file, char *buf, size_t size); | 67 | static ssize_t write_filehandle(struct file *file, char *buf, size_t size); |
67 | static ssize_t write_threads(struct file *file, char *buf, size_t size); | 68 | static ssize_t write_threads(struct file *file, char *buf, size_t size); |
68 | static ssize_t write_leasetime(struct file *file, char *buf, size_t size); | 69 | 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); | ||
69 | 71 | ||
70 | static ssize_t (*write_op[])(struct file *, char *, size_t) = { | 72 | static 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 | ||
83 | static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) | 86 | 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 | return strlen(buf); | 352 | return strlen(buf); |
350 | } | 353 | } |
351 | 354 | ||
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 | |||
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 | }; |