Merge branch develop-3.10-next
[firefly-linux-kernel-4.4.55.git] / fs / nfsd / nfs4recover.c
index 899ca26dd194d73f43234ba08447f1533428eff6..105a3b080d1236c24afed6267354705fd8da5d94 100644 (file)
@@ -146,7 +146,7 @@ out_no_tfm:
  * then disable recovery tracking.
  */
 static void
-legacy_recdir_name_error(int error)
+legacy_recdir_name_error(struct nfs4_client *clp, int error)
 {
        printk(KERN_ERR "NFSD: unable to generate recoverydir "
                        "name (%d).\n", error);
@@ -159,9 +159,7 @@ legacy_recdir_name_error(int error)
        if (error == -ENOENT) {
                printk(KERN_ERR "NFSD: disabling legacy clientid tracking. "
                        "Reboot recovery will not function correctly!\n");
-
-               /* the argument is ignored by the legacy exit function */
-               nfsd4_client_tracking_exit(NULL);
+               nfsd4_client_tracking_exit(clp->net);
        }
 }
 
@@ -184,7 +182,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
 
        status = nfs4_make_rec_clidname(dname, &clp->cl_name);
        if (status)
-               return legacy_recdir_name_error(status);
+               return legacy_recdir_name_error(clp, status);
 
        status = nfs4_save_creds(&original_cred);
        if (status < 0)
@@ -242,11 +240,16 @@ struct name_list {
        struct list_head list;
 };
 
+struct nfs4_dir_ctx {
+       struct dir_context ctx;
+       struct list_head names;
+};
+
 static int
 nfsd4_build_namelist(void *arg, const char *name, int namlen,
                loff_t offset, u64 ino, unsigned int d_type)
 {
-       struct list_head *names = arg;
+       struct nfs4_dir_ctx *ctx = arg;
        struct name_list *entry;
 
        if (namlen != HEXDIR_LEN - 1)
@@ -256,7 +259,7 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
                return -ENOMEM;
        memcpy(entry->name, name, HEXDIR_LEN - 1);
        entry->name[HEXDIR_LEN - 1] = '\0';
-       list_add(&entry->list, names);
+       list_add(&entry->list, &ctx->names);
        return 0;
 }
 
@@ -265,7 +268,10 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
 {
        const struct cred *original_cred;
        struct dentry *dir = nn->rec_file->f_path.dentry;
-       LIST_HEAD(names);
+       struct nfs4_dir_ctx ctx = {
+               .ctx.actor = nfsd4_build_namelist,
+               .names = LIST_HEAD_INIT(ctx.names)
+       };
        int status;
 
        status = nfs4_save_creds(&original_cred);
@@ -278,11 +284,11 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
                return status;
        }
 
-       status = vfs_readdir(nn->rec_file, nfsd4_build_namelist, &names);
+       status = iterate_dir(nn->rec_file, &ctx.ctx);
        mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
-       while (!list_empty(&names)) {
+       while (!list_empty(&ctx.names)) {
                struct name_list *entry;
-               entry = list_entry(names.next, struct name_list, list);
+               entry = list_entry(ctx.names.next, struct name_list, list);
                if (!status) {
                        struct dentry *dentry;
                        dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);
@@ -341,7 +347,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
 
        status = nfs4_make_rec_clidname(dname, &clp->cl_name);
        if (status)
-               return legacy_recdir_name_error(status);
+               return legacy_recdir_name_error(clp, status);
 
        status = mnt_want_write_file(nn->rec_file);
        if (status)
@@ -601,7 +607,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
 
        status = nfs4_make_rec_clidname(dname, &clp->cl_name);
        if (status) {
-               legacy_recdir_name_error(status);
+               legacy_recdir_name_error(clp, status);
                return status;
        }