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_populate(): lift cleanup into callers

rpc_populate() is called either from fill_super (where we don't
need to remove any files on failure - rpc_kill_sb() will take
them all out anyway) or from rpc_mkdir_populate(), where we need
to remove the directory we'd been trying to populate along with
whatever we'd put into it before we failed. Simpler to combine
that into simple_recursive_removal() there.

Note that rpc_pipe is overlocking directories quite a bit -
locked parent is no obstacle to finding a child in dcache, so
keeping it locked won't prevent userland observing a partially
built subtree.

All we need is to follow minimal VFS requirements; it's not
as if clients used directory locking for exclusion - tree
changes are serialized, but that's done on ->pipefs_sb_lock.

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

+5 -66
+5 -66
net/sunrpc/rpc_pipe.c
··· 594 594 return 0; 595 595 } 596 596 597 - static int __rpc_rmdir(struct inode *dir, struct dentry *dentry) 598 - { 599 - int ret; 600 - 601 - dget(dentry); 602 - ret = simple_rmdir(dir, dentry); 603 - d_drop(dentry); 604 - if (!ret) 605 - fsnotify_rmdir(dir, dentry); 606 - dput(dentry); 607 - return ret; 608 - } 609 - 610 - static int __rpc_unlink(struct inode *dir, struct dentry *dentry) 611 - { 612 - int ret; 613 - 614 - dget(dentry); 615 - ret = simple_unlink(dir, dentry); 616 - d_drop(dentry); 617 - if (!ret) 618 - fsnotify_unlink(dir, dentry); 619 - dput(dentry); 620 - return ret; 621 - } 622 - 623 597 static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent, 624 598 const char *name) 625 599 { ··· 608 634 return dentry; 609 635 dput(dentry); 610 636 return ERR_PTR(-EEXIST); 611 - } 612 - 613 - /* 614 - * FIXME: This probably has races. 615 - */ 616 - static void __rpc_depopulate(struct dentry *parent, 617 - const struct rpc_filelist *files, 618 - int start, int eof) 619 - { 620 - struct inode *dir = d_inode(parent); 621 - struct dentry *dentry; 622 - struct qstr name; 623 - int i; 624 - 625 - for (i = start; i < eof; i++) { 626 - name.name = files[i].name; 627 - name.len = strlen(files[i].name); 628 - dentry = try_lookup_noperm(&name, parent); 629 - 630 - if (dentry == NULL) 631 - continue; 632 - if (d_really_is_negative(dentry)) 633 - goto next; 634 - switch (d_inode(dentry)->i_mode & S_IFMT) { 635 - default: 636 - BUG(); 637 - case S_IFREG: 638 - __rpc_unlink(dir, dentry); 639 - break; 640 - case S_IFDIR: 641 - __rpc_rmdir(dir, dentry); 642 - } 643 - next: 644 - dput(dentry); 645 - } 646 637 } 647 638 648 639 static int rpc_populate(struct dentry *parent, ··· 646 707 inode_unlock(dir); 647 708 return 0; 648 709 out_bad: 649 - __rpc_depopulate(parent, files, start, eof); 650 710 inode_unlock(dir); 651 711 printk(KERN_WARNING "%s: %s failed to populate directory %pd\n", 652 712 __FILE__, __func__, parent); ··· 669 731 goto out_err; 670 732 if (populate != NULL) { 671 733 error = populate(dentry, args_populate); 672 - if (error) 673 - goto err_rmdir; 734 + if (error) { 735 + inode_unlock(dir); 736 + simple_recursive_removal(dentry, NULL); 737 + return ERR_PTR(error); 738 + } 674 739 } 675 740 out: 676 741 inode_unlock(dir); 677 742 return dentry; 678 - err_rmdir: 679 - __rpc_rmdir(dir, dentry); 680 743 out_err: 681 744 dentry = ERR_PTR(error); 682 745 goto out;