diff options
Diffstat (limited to 'fs/nfsd/nfs4recover.c')
-rw-r--r-- | fs/nfsd/nfs4recover.c | 20 |
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 | ||
243 | struct nfs4_dir_ctx { | ||
244 | struct dir_context ctx; | ||
245 | struct list_head names; | ||
246 | }; | ||
247 | |||
243 | static int | 248 | static int |
244 | nfsd4_build_namelist(void *arg, const char *name, int namlen, | 249 | nfsd4_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); |