Skip to content

Commit 89bd77c

Browse files
NeilBrownchucklever
authored andcommitted
nfsd: move name lookup out of nfsd4_list_rec_dir()
nfsd4_list_rec_dir() is called with two different callbacks. One of the callbacks uses vfs_rmdir() to remove the directory. The other doesn't use the dentry at all, just the name. As only one callback needs the dentry, this patch moves the lookup into that callback. This prepares of changes to how directory operations are locked. Signed-off-by: NeilBrown <neil@brown.name> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent bf94dea commit 89bd77c

1 file changed

Lines changed: 26 additions & 28 deletions

File tree

fs/nfsd/nfs4recover.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
237237
nfs4_reset_creds(original_cred);
238238
}
239239

240-
typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *);
240+
typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *);
241241

242242
struct name_list {
243243
char name[HEXDIR_LEN];
@@ -291,24 +291,14 @@ nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
291291
}
292292

293293
status = iterate_dir(nn->rec_file, &ctx.ctx);
294-
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
295294

296295
list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
297-
if (!status) {
298-
struct dentry *dentry;
299-
dentry = lookup_one(&nop_mnt_idmap,
300-
&QSTR(entry->name), dir);
301-
if (IS_ERR(dentry)) {
302-
status = PTR_ERR(dentry);
303-
break;
304-
}
305-
status = f(dir, dentry, nn);
306-
dput(dentry);
307-
}
296+
if (!status)
297+
status = f(dir, entry->name, nn);
298+
308299
list_del(&entry->list);
309300
kfree(entry);
310301
}
311-
inode_unlock(d_inode(dir));
312302
nfs4_reset_creds(original_cred);
313303

314304
list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
@@ -406,18 +396,19 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
406396
}
407397

408398
static int
409-
purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
399+
purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
410400
{
411401
int status;
402+
struct dentry *child;
412403
struct xdr_netobj name;
413404

414-
if (child->d_name.len != HEXDIR_LEN - 1) {
415-
printk("%s: illegal name %pd in recovery directory\n",
416-
__func__, child);
405+
if (strlen(cname) != HEXDIR_LEN - 1) {
406+
printk("%s: illegal name %s in recovery directory\n",
407+
__func__, cname);
417408
/* Keep trying; maybe the others are OK: */
418409
return 0;
419410
}
420-
name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
411+
name.data = kstrdup(cname, GFP_KERNEL);
421412
if (!name.data) {
422413
dprintk("%s: failed to allocate memory for name.data!\n",
423414
__func__);
@@ -427,10 +418,17 @@ purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
427418
if (nfs4_has_reclaimed_state(name, nn))
428419
goto out_free;
429420

430-
status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child);
431-
if (status)
432-
printk("failed to remove client recovery directory %pd\n",
433-
child);
421+
inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
422+
child = lookup_one(&nop_mnt_idmap, &QSTR(cname), parent);
423+
if (!IS_ERR(child)) {
424+
status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child);
425+
if (status)
426+
printk("failed to remove client recovery directory %pd\n",
427+
child);
428+
dput(child);
429+
}
430+
inode_unlock(d_inode(parent));
431+
434432
out_free:
435433
kfree(name.data);
436434
out:
@@ -461,18 +459,18 @@ nfsd4_recdir_purge_old(struct nfsd_net *nn)
461459
}
462460

463461
static int
464-
load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn)
462+
load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
465463
{
466464
struct xdr_netobj name;
467465
struct xdr_netobj princhash = { .len = 0, .data = NULL };
468466

469-
if (child->d_name.len != HEXDIR_LEN - 1) {
470-
printk("%s: illegal name %pd in recovery directory\n",
471-
__func__, child);
467+
if (strlen(cname) != HEXDIR_LEN - 1) {
468+
printk("%s: illegal name %s in recovery directory\n",
469+
__func__, cname);
472470
/* Keep trying; maybe the others are OK: */
473471
return 0;
474472
}
475-
name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL);
473+
name.data = kstrdup(cname, GFP_KERNEL);
476474
if (!name.data) {
477475
dprintk("%s: failed to allocate memory for name.data!\n",
478476
__func__);

0 commit comments

Comments
 (0)