aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4recover.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4recover.c')
-rw-r--r--fs/nfsd/nfs4recover.c103
1 files changed, 42 insertions, 61 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ed083b9..be26814 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -45,7 +45,6 @@
/* Globals */
static struct file *rec_file;
-static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
static int
nfs4_save_creds(const struct cred **original_creds)
@@ -130,7 +129,6 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
if (!rec_file || clp->cl_firststate)
return 0;
- clp->cl_firststate = 1;
status = nfs4_save_creds(&original_cred);
if (status < 0)
return status;
@@ -145,8 +143,10 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
goto out_unlock;
}
status = -EEXIST;
- if (dentry->d_inode)
+ if (dentry->d_inode) {
+ dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
goto out_put;
+ }
status = mnt_want_write(rec_file->f_path.mnt);
if (status)
goto out_put;
@@ -156,14 +156,12 @@ out_put:
dput(dentry);
out_unlock:
mutex_unlock(&dir->d_inode->i_mutex);
- if (status == 0)
+ if (status == 0) {
+ clp->cl_firststate = 1;
vfs_fsync(rec_file, 0);
- else
- printk(KERN_ERR "NFSD: failed to write recovery record"
- " (err %d); please check that %s exists"
- " and is writeable", status,
- user_recovery_dirname);
+ }
nfs4_reset_creds(original_cred);
+ dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
return status;
}
@@ -193,42 +191,52 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
}
static int
-nfsd4_list_rec_dir(recdir_func *f)
+nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
{
const struct cred *original_cred;
- struct dentry *dir = rec_file->f_path.dentry;
+ struct file *filp;
LIST_HEAD(names);
+ struct name_list *entry;
+ struct dentry *dentry;
int status;
+ if (!rec_file)
+ return 0;
+
status = nfs4_save_creds(&original_cred);
if (status < 0)
return status;
- status = vfs_llseek(rec_file, 0, SEEK_SET);
- if (status < 0) {
- nfs4_reset_creds(original_cred);
- return status;
- }
-
- status = vfs_readdir(rec_file, nfsd4_build_namelist, &names);
+ filp = dentry_open(dget(dir), mntget(rec_file->f_path.mnt), O_RDONLY,
+ current_cred());
+ status = PTR_ERR(filp);
+ if (IS_ERR(filp))
+ goto out;
+ status = vfs_readdir(filp, nfsd4_build_namelist, &names);
+ fput(filp);
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
while (!list_empty(&names)) {
- struct name_list *entry;
entry = list_entry(names.next, struct name_list, list);
- if (!status) {
- struct dentry *dentry;
- dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
- if (IS_ERR(dentry)) {
- status = PTR_ERR(dentry);
- break;
- }
- status = f(dir, dentry);
- dput(dentry);
+
+ dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
+ if (IS_ERR(dentry)) {
+ status = PTR_ERR(dentry);
+ break;
}
+ status = f(dir, dentry);
+ dput(dentry);
+ if (status)
+ break;
list_del(&entry->list);
kfree(entry);
}
mutex_unlock(&dir->d_inode->i_mutex);
+out:
+ while (!list_empty(&names)) {
+ entry = list_entry(names.next, struct name_list, list);
+ list_del(&entry->list);
+ kfree(entry);
+ }
nfs4_reset_creds(original_cred);
return status;
}
@@ -314,7 +322,7 @@ nfsd4_recdir_purge_old(void) {
status = mnt_want_write(rec_file->f_path.mnt);
if (status)
goto out;
- status = nfsd4_list_rec_dir(purge_old);
+ status = nfsd4_list_rec_dir(rec_file->f_path.dentry, purge_old);
if (status == 0)
vfs_fsync(rec_file, 0);
mnt_drop_write(rec_file->f_path.mnt);
@@ -344,7 +352,7 @@ nfsd4_recdir_load(void) {
if (!rec_file)
return 0;
- status = nfsd4_list_rec_dir(load_recdir);
+ status = nfsd4_list_rec_dir(rec_file->f_path.dentry, load_recdir);
if (status)
printk("nfsd4: failed loading clients from recovery"
" directory %s\n", rec_file->f_path.dentry->d_name.name);
@@ -356,13 +364,13 @@ nfsd4_recdir_load(void) {
*/
void
-nfsd4_init_recdir()
+nfsd4_init_recdir(char *rec_dirname)
{
const struct cred *original_cred;
int status;
printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
- user_recovery_dirname);
+ rec_dirname);
BUG_ON(rec_file);
@@ -374,10 +382,10 @@ nfsd4_init_recdir()
return;
}
- rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0);
+ rec_file = filp_open(rec_dirname, O_RDONLY | O_DIRECTORY, 0);
if (IS_ERR(rec_file)) {
printk("NFSD: unable to find recovery directory %s\n",
- user_recovery_dirname);
+ rec_dirname);
rec_file = NULL;
}
@@ -392,30 +400,3 @@ nfsd4_shutdown_recdir(void)
fput(rec_file);
rec_file = NULL;
}
-
-/*
- * Change the NFSv4 recovery directory to recdir.
- */
-int
-nfs4_reset_recoverydir(char *recdir)
-{
- int status;
- struct path path;
-
- status = kern_path(recdir, LOOKUP_FOLLOW, &path);
- if (status)
- return status;
- status = -ENOTDIR;
- if (S_ISDIR(path.dentry->d_inode->i_mode)) {
- strcpy(user_recovery_dirname, recdir);
- status = 0;
- }
- path_put(&path);
- return status;
-}
-
-char *
-nfs4_recoverydir(void)
-{
- return user_recovery_dirname;
-}