diff options
Diffstat (limited to 'fs/nfsd/nfs4recover.c')
-rw-r--r-- | fs/nfsd/nfs4recover.c | 103 |
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; -} |