Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

NeilBrown and committed by
Chuck Lever
89bd77cf bf94dea7

+26 -28
+26 -28
fs/nfsd/nfs4recover.c
··· 237 237 nfs4_reset_creds(original_cred); 238 238 } 239 239 240 - typedef int (recdir_func)(struct dentry *, struct dentry *, struct nfsd_net *); 240 + typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *); 241 241 242 242 struct name_list { 243 243 char name[HEXDIR_LEN]; ··· 291 291 } 292 292 293 293 status = iterate_dir(nn->rec_file, &ctx.ctx); 294 - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT); 295 294 296 295 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 + 308 299 list_del(&entry->list); 309 300 kfree(entry); 310 301 } 311 - inode_unlock(d_inode(dir)); 312 302 nfs4_reset_creds(original_cred); 313 303 314 304 list_for_each_entry_safe(entry, tmp, &ctx.names, list) { ··· 396 406 } 397 407 398 408 static int 399 - purge_old(struct dentry *parent, struct dentry *child, struct nfsd_net *nn) 409 + purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn) 400 410 { 401 411 int status; 412 + struct dentry *child; 402 413 struct xdr_netobj name; 403 414 404 - if (child->d_name.len != HEXDIR_LEN - 1) { 405 - printk("%s: illegal name %pd in recovery directory\n", 406 - __func__, child); 415 + if (strlen(cname) != HEXDIR_LEN - 1) { 416 + printk("%s: illegal name %s in recovery directory\n", 417 + __func__, cname); 407 418 /* Keep trying; maybe the others are OK: */ 408 419 return 0; 409 420 } 410 - name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL); 421 + name.data = kstrdup(cname, GFP_KERNEL); 411 422 if (!name.data) { 412 423 dprintk("%s: failed to allocate memory for name.data!\n", 413 424 __func__); ··· 418 427 if (nfs4_has_reclaimed_state(name, nn)) 419 428 goto out_free; 420 429 421 - status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child); 422 - if (status) 423 - printk("failed to remove client recovery directory %pd\n", 424 - child); 430 + inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); 431 + child = lookup_one(&nop_mnt_idmap, &QSTR(cname), parent); 432 + if (!IS_ERR(child)) { 433 + status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child); 434 + if (status) 435 + printk("failed to remove client recovery directory %pd\n", 436 + child); 437 + dput(child); 438 + } 439 + inode_unlock(d_inode(parent)); 440 + 425 441 out_free: 426 442 kfree(name.data); 427 443 out: ··· 459 461 } 460 462 461 463 static int 462 - load_recdir(struct dentry *parent, struct dentry *child, struct nfsd_net *nn) 464 + load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn) 463 465 { 464 466 struct xdr_netobj name; 465 467 struct xdr_netobj princhash = { .len = 0, .data = NULL }; 466 468 467 - if (child->d_name.len != HEXDIR_LEN - 1) { 468 - printk("%s: illegal name %pd in recovery directory\n", 469 - __func__, child); 469 + if (strlen(cname) != HEXDIR_LEN - 1) { 470 + printk("%s: illegal name %s in recovery directory\n", 471 + __func__, cname); 470 472 /* Keep trying; maybe the others are OK: */ 471 473 return 0; 472 474 } 473 - name.data = kmemdup_nul(child->d_name.name, child->d_name.len, GFP_KERNEL); 475 + name.data = kstrdup(cname, GFP_KERNEL); 474 476 if (!name.data) { 475 477 dprintk("%s: failed to allocate memory for name.data!\n", 476 478 __func__);