nfsd4_list_rec_dir(): don't bother with reopening rec_file
Al Viro [Thu, 7 Jul 2011 22:43:21 +0000 (18:43 -0400)]
just rewind it to the beginning before vfs_readdir() and be
done with that...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

fs/nfsd/nfs4recover.c

index ffb59ef..29d77f6 100644 (file)
@@ -191,52 +191,42 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
 }
 
 static int
-nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
+nfsd4_list_rec_dir(recdir_func *f)
 {
        const struct cred *original_cred;
-       struct file *filp;
+       struct dentry *dir = rec_file->f_path.dentry;
        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;
 
-       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);
+       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);
        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);
-
-               dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
-               if (IS_ERR(dentry)) {
-                       status = PTR_ERR(dentry);
-                       break;
+               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);
                }
-               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;
 }
@@ -322,7 +312,7 @@ nfsd4_recdir_purge_old(void) {
        status = mnt_want_write(rec_file->f_path.mnt);
        if (status)
                goto out;
-       status = nfsd4_list_rec_dir(rec_file->f_path.dentry, purge_old);
+       status = nfsd4_list_rec_dir(purge_old);
        if (status == 0)
                vfs_fsync(rec_file, 0);
        mnt_drop_write(rec_file->f_path.mnt);
@@ -352,7 +342,7 @@ nfsd4_recdir_load(void) {
        if (!rec_file)
                return 0;
 
-       status = nfsd4_list_rec_dir(rec_file->f_path.dentry, load_recdir);
+       status = nfsd4_list_rec_dir(load_recdir);
        if (status)
                printk("nfsd4: failed loading clients from recovery"
                        " directory %s\n", rec_file->f_path.dentry->d_name.name);