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.

rpc_pipe: don't overdo directory locking

Don't try to hold directories locked more than VFS requires;
lock just before getting a child to be made positive (using
simple_start_creating()) and unlock as soon as the child is
created. There's no benefit in keeping the parent locked
while populating the child - it won't stop dcache lookups anyway.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

+9 -35
+9 -35
net/sunrpc/rpc_pipe.c
··· 594 594 return 0; 595 595 } 596 596 597 - static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, 598 - const char *name) 599 - { 600 - struct qstr q = QSTR(name); 601 - struct dentry *dentry = try_lookup_noperm(&q, parent); 602 - if (!dentry) { 603 - dentry = d_alloc(parent, &q); 604 - if (!dentry) 605 - return ERR_PTR(-ENOMEM); 606 - } 607 - if (d_really_is_negative(dentry)) 608 - return dentry; 609 - dput(dentry); 610 - return ERR_PTR(-EEXIST); 611 - } 612 - 613 597 static int rpc_populate(struct dentry *parent, 614 598 const struct rpc_filelist *files, 615 599 int start, int eof, ··· 603 619 struct dentry *dentry; 604 620 int i, err; 605 621 606 - inode_lock(dir); 607 622 for (i = start; i < eof; i++) { 608 - dentry = __rpc_lookup_create_exclusive(parent, files[i].name); 623 + dentry = simple_start_creating(parent, files[i].name); 609 624 err = PTR_ERR(dentry); 610 625 if (IS_ERR(dentry)) 611 626 goto out_bad; ··· 616 633 files[i].mode, 617 634 files[i].i_fop, 618 635 private); 636 + inode_unlock(dir); 619 637 break; 620 638 case S_IFDIR: 621 639 err = __rpc_mkdir(dir, dentry, 622 640 files[i].mode, 623 641 NULL, 624 642 private); 643 + inode_unlock(dir); 625 644 } 626 645 if (err != 0) 627 646 goto out_bad; 628 647 } 629 - inode_unlock(dir); 630 648 return 0; 631 649 out_bad: 632 - inode_unlock(dir); 633 650 printk(KERN_WARNING "%s: %s failed to populate directory %pd\n", 634 651 __FILE__, __func__, parent); 635 652 return err; ··· 643 660 struct inode *dir = d_inode(parent); 644 661 int error; 645 662 646 - inode_lock_nested(dir, I_MUTEX_PARENT); 647 - dentry = __rpc_lookup_create_exclusive(parent, name); 663 + dentry = simple_start_creating(parent, name); 648 664 if (IS_ERR(dentry)) 649 - goto out; 665 + return dentry; 650 666 error = __rpc_mkdir(dir, dentry, mode, NULL, private); 667 + inode_unlock(dir); 651 668 if (error != 0) 652 - goto out_err; 669 + return ERR_PTR(error); 653 670 if (populate != NULL) { 654 671 error = populate(dentry, args_populate); 655 672 if (error) { 656 - inode_unlock(dir); 657 673 simple_recursive_removal(dentry, NULL); 658 674 return ERR_PTR(error); 659 675 } 660 676 } 661 - out: 662 - inode_unlock(dir); 663 677 return dentry; 664 - out_err: 665 - dentry = ERR_PTR(error); 666 - goto out; 667 678 } 668 679 669 680 /** ··· 692 715 if (pipe->ops->downcall == NULL) 693 716 umode &= ~0222; 694 717 695 - inode_lock_nested(dir, I_MUTEX_PARENT); 696 - dentry = __rpc_lookup_create_exclusive(parent, name); 697 - if (IS_ERR(dentry)) { 698 - inode_unlock(dir); 718 + dentry = simple_start_creating(parent, name); 719 + if (IS_ERR(dentry)) 699 720 return PTR_ERR(dentry); 700 - } 701 721 err = __rpc_mkpipe_dentry(dir, dentry, umode, &rpc_pipe_fops, 702 722 private, pipe); 703 723 if (unlikely(err))