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.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 4e9a21db867a..105a3b080d12 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -240,11 +240,16 @@ struct name_list {
240 struct list_head list; 240 struct list_head list;
241}; 241};
242 242
243struct nfs4_dir_ctx {
244 struct dir_context ctx;
245 struct list_head names;
246};
247
243static int 248static int
244nfsd4_build_namelist(void *arg, const char *name, int namlen, 249nfsd4_build_namelist(void *arg, const char *name, int namlen,
245 loff_t offset, u64 ino, unsigned int d_type) 250 loff_t offset, u64 ino, unsigned int d_type)
246{ 251{
247 struct list_head *names = arg; 252 struct nfs4_dir_ctx *ctx = arg;
248 struct name_list *entry; 253 struct name_list *entry;
249 254
250 if (namlen != HEXDIR_LEN - 1) 255 if (namlen != HEXDIR_LEN - 1)
@@ -254,7 +259,7 @@ nfsd4_build_namelist(void *arg, const char *name, int namlen,
254 return -ENOMEM; 259 return -ENOMEM;
255 memcpy(entry->name, name, HEXDIR_LEN - 1); 260 memcpy(entry->name, name, HEXDIR_LEN - 1);
256 entry->name[HEXDIR_LEN - 1] = '\0'; 261 entry->name[HEXDIR_LEN - 1] = '\0';
257 list_add(&entry->list, names); 262 list_add(&entry->list, &ctx->names);
258 return 0; 263 return 0;
259} 264}
260 265
@@ -263,7 +268,10 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
263{ 268{
264 const struct cred *original_cred; 269 const struct cred *original_cred;
265 struct dentry *dir = nn->rec_file->f_path.dentry; 270 struct dentry *dir = nn->rec_file->f_path.dentry;
266 LIST_HEAD(names); 271 struct nfs4_dir_ctx ctx = {
272 .ctx.actor = nfsd4_build_namelist,
273 .names = LIST_HEAD_INIT(ctx.names)
274 };
267 int status; 275 int status;
268 276
269 status = nfs4_save_creds(&original_cred); 277 status = nfs4_save_creds(&original_cred);
@@ -276,11 +284,11 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
276 return status; 284 return status;
277 } 285 }
278 286
279 status = vfs_readdir(nn->rec_file, nfsd4_build_namelist, &names); 287 status = iterate_dir(nn->rec_file, &ctx.ctx);
280 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); 288 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
281 while (!list_empty(&names)) { 289 while (!list_empty(&ctx.names)) {
282 struct name_list *entry; 290 struct name_list *entry;
283 entry = list_entry(names.next, struct name_list, list); 291 entry = list_entry(ctx.names.next, struct name_list, list);
284 if (!status) { 292 if (!status) {
285 struct dentry *dentry; 293 struct dentry *dentry;
286 dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1); 294 dentry = lookup_one_len(entry->name, dir, HEXDIR_LEN-1);