diff options
Diffstat (limited to 'fs/nfsd/nfs4recover.c')
-rw-r--r-- | fs/nfsd/nfs4recover.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 29d77f60585b..ed083b9a731b 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -45,6 +45,7 @@ | |||
45 | 45 | ||
46 | /* Globals */ | 46 | /* Globals */ |
47 | static struct file *rec_file; | 47 | static struct file *rec_file; |
48 | static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery"; | ||
48 | 49 | ||
49 | static int | 50 | static int |
50 | nfs4_save_creds(const struct cred **original_creds) | 51 | nfs4_save_creds(const struct cred **original_creds) |
@@ -88,7 +89,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname) | |||
88 | struct xdr_netobj cksum; | 89 | struct xdr_netobj cksum; |
89 | struct hash_desc desc; | 90 | struct hash_desc desc; |
90 | struct scatterlist sg; | 91 | struct scatterlist sg; |
91 | __be32 status = nfserr_resource; | 92 | __be32 status = nfserr_jukebox; |
92 | 93 | ||
93 | dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", | 94 | dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", |
94 | clname->len, clname->data); | 95 | clname->len, clname->data); |
@@ -129,6 +130,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
129 | if (!rec_file || clp->cl_firststate) | 130 | if (!rec_file || clp->cl_firststate) |
130 | return 0; | 131 | return 0; |
131 | 132 | ||
133 | clp->cl_firststate = 1; | ||
132 | status = nfs4_save_creds(&original_cred); | 134 | status = nfs4_save_creds(&original_cred); |
133 | if (status < 0) | 135 | if (status < 0) |
134 | return status; | 136 | return status; |
@@ -143,10 +145,8 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
143 | goto out_unlock; | 145 | goto out_unlock; |
144 | } | 146 | } |
145 | status = -EEXIST; | 147 | status = -EEXIST; |
146 | if (dentry->d_inode) { | 148 | if (dentry->d_inode) |
147 | dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n"); | ||
148 | goto out_put; | 149 | goto out_put; |
149 | } | ||
150 | status = mnt_want_write(rec_file->f_path.mnt); | 150 | status = mnt_want_write(rec_file->f_path.mnt); |
151 | if (status) | 151 | if (status) |
152 | goto out_put; | 152 | goto out_put; |
@@ -156,12 +156,14 @@ out_put: | |||
156 | dput(dentry); | 156 | dput(dentry); |
157 | out_unlock: | 157 | out_unlock: |
158 | mutex_unlock(&dir->d_inode->i_mutex); | 158 | mutex_unlock(&dir->d_inode->i_mutex); |
159 | if (status == 0) { | 159 | if (status == 0) |
160 | clp->cl_firststate = 1; | ||
161 | vfs_fsync(rec_file, 0); | 160 | vfs_fsync(rec_file, 0); |
162 | } | 161 | else |
162 | printk(KERN_ERR "NFSD: failed to write recovery record" | ||
163 | " (err %d); please check that %s exists" | ||
164 | " and is writeable", status, | ||
165 | user_recovery_dirname); | ||
163 | nfs4_reset_creds(original_cred); | 166 | nfs4_reset_creds(original_cred); |
164 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); | ||
165 | return status; | 167 | return status; |
166 | } | 168 | } |
167 | 169 | ||
@@ -354,13 +356,13 @@ nfsd4_recdir_load(void) { | |||
354 | */ | 356 | */ |
355 | 357 | ||
356 | void | 358 | void |
357 | nfsd4_init_recdir(char *rec_dirname) | 359 | nfsd4_init_recdir() |
358 | { | 360 | { |
359 | const struct cred *original_cred; | 361 | const struct cred *original_cred; |
360 | int status; | 362 | int status; |
361 | 363 | ||
362 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", | 364 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", |
363 | rec_dirname); | 365 | user_recovery_dirname); |
364 | 366 | ||
365 | BUG_ON(rec_file); | 367 | BUG_ON(rec_file); |
366 | 368 | ||
@@ -372,10 +374,10 @@ nfsd4_init_recdir(char *rec_dirname) | |||
372 | return; | 374 | return; |
373 | } | 375 | } |
374 | 376 | ||
375 | rec_file = filp_open(rec_dirname, O_RDONLY | O_DIRECTORY, 0); | 377 | rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0); |
376 | if (IS_ERR(rec_file)) { | 378 | if (IS_ERR(rec_file)) { |
377 | printk("NFSD: unable to find recovery directory %s\n", | 379 | printk("NFSD: unable to find recovery directory %s\n", |
378 | rec_dirname); | 380 | user_recovery_dirname); |
379 | rec_file = NULL; | 381 | rec_file = NULL; |
380 | } | 382 | } |
381 | 383 | ||
@@ -390,3 +392,30 @@ nfsd4_shutdown_recdir(void) | |||
390 | fput(rec_file); | 392 | fput(rec_file); |
391 | rec_file = NULL; | 393 | rec_file = NULL; |
392 | } | 394 | } |
395 | |||
396 | /* | ||
397 | * Change the NFSv4 recovery directory to recdir. | ||
398 | */ | ||
399 | int | ||
400 | nfs4_reset_recoverydir(char *recdir) | ||
401 | { | ||
402 | int status; | ||
403 | struct path path; | ||
404 | |||
405 | status = kern_path(recdir, LOOKUP_FOLLOW, &path); | ||
406 | if (status) | ||
407 | return status; | ||
408 | status = -ENOTDIR; | ||
409 | if (S_ISDIR(path.dentry->d_inode->i_mode)) { | ||
410 | strcpy(user_recovery_dirname, recdir); | ||
411 | status = 0; | ||
412 | } | ||
413 | path_put(&path); | ||
414 | return status; | ||
415 | } | ||
416 | |||
417 | char * | ||
418 | nfs4_recoverydir(void) | ||
419 | { | ||
420 | return user_recovery_dirname; | ||
421 | } | ||