diff options
Diffstat (limited to 'net/sunrpc/rpc_pipe.c')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 61 |
1 files changed, 25 insertions, 36 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index dc6cb93c883..0b1a1ac8a4b 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -539,6 +539,7 @@ repeat: | |||
539 | rpc_close_pipes(dentry->d_inode); | 539 | rpc_close_pipes(dentry->d_inode); |
540 | simple_unlink(dir, dentry); | 540 | simple_unlink(dir, dentry); |
541 | } | 541 | } |
542 | inode_dir_notify(dir, DN_DELETE); | ||
542 | dput(dentry); | 543 | dput(dentry); |
543 | } while (n); | 544 | } while (n); |
544 | goto repeat; | 545 | goto repeat; |
@@ -610,8 +611,8 @@ __rpc_rmdir(struct inode *dir, struct dentry *dentry) | |||
610 | int error; | 611 | int error; |
611 | 612 | ||
612 | shrink_dcache_parent(dentry); | 613 | shrink_dcache_parent(dentry); |
613 | if (dentry->d_inode) | 614 | if (d_unhashed(dentry)) |
614 | rpc_close_pipes(dentry->d_inode); | 615 | return 0; |
615 | if ((error = simple_rmdir(dir, dentry)) != 0) | 616 | if ((error = simple_rmdir(dir, dentry)) != 0) |
616 | return error; | 617 | return error; |
617 | if (!error) { | 618 | if (!error) { |
@@ -667,10 +668,11 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | |||
667 | RPCAUTH_info, RPCAUTH_EOF); | 668 | RPCAUTH_info, RPCAUTH_EOF); |
668 | if (error) | 669 | if (error) |
669 | goto err_depopulate; | 670 | goto err_depopulate; |
671 | dget(dentry); | ||
670 | out: | 672 | out: |
671 | mutex_unlock(&dir->i_mutex); | 673 | mutex_unlock(&dir->i_mutex); |
672 | rpc_release_path(&nd); | 674 | rpc_release_path(&nd); |
673 | return dget(dentry); | 675 | return dentry; |
674 | err_depopulate: | 676 | err_depopulate: |
675 | rpc_depopulate(dentry); | 677 | rpc_depopulate(dentry); |
676 | __rpc_rmdir(dir, dentry); | 678 | __rpc_rmdir(dir, dentry); |
@@ -683,28 +685,20 @@ err_dput: | |||
683 | } | 685 | } |
684 | 686 | ||
685 | int | 687 | int |
686 | rpc_rmdir(char *path) | 688 | rpc_rmdir(struct dentry *dentry) |
687 | { | 689 | { |
688 | struct nameidata nd; | 690 | struct dentry *parent; |
689 | struct dentry *dentry; | ||
690 | struct inode *dir; | 691 | struct inode *dir; |
691 | int error; | 692 | int error; |
692 | 693 | ||
693 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 694 | parent = dget_parent(dentry); |
694 | return error; | 695 | dir = parent->d_inode; |
695 | dir = nd.dentry->d_inode; | ||
696 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 696 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
697 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); | ||
698 | if (IS_ERR(dentry)) { | ||
699 | error = PTR_ERR(dentry); | ||
700 | goto out_release; | ||
701 | } | ||
702 | rpc_depopulate(dentry); | 697 | rpc_depopulate(dentry); |
703 | error = __rpc_rmdir(dir, dentry); | 698 | error = __rpc_rmdir(dir, dentry); |
704 | dput(dentry); | 699 | dput(dentry); |
705 | out_release: | ||
706 | mutex_unlock(&dir->i_mutex); | 700 | mutex_unlock(&dir->i_mutex); |
707 | rpc_release_path(&nd); | 701 | dput(parent); |
708 | return error; | 702 | return error; |
709 | } | 703 | } |
710 | 704 | ||
@@ -731,10 +725,11 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) | |||
731 | rpci->flags = flags; | 725 | rpci->flags = flags; |
732 | rpci->ops = ops; | 726 | rpci->ops = ops; |
733 | inode_dir_notify(dir, DN_CREATE); | 727 | inode_dir_notify(dir, DN_CREATE); |
728 | dget(dentry); | ||
734 | out: | 729 | out: |
735 | mutex_unlock(&dir->i_mutex); | 730 | mutex_unlock(&dir->i_mutex); |
736 | rpc_release_path(&nd); | 731 | rpc_release_path(&nd); |
737 | return dget(dentry); | 732 | return dentry; |
738 | err_dput: | 733 | err_dput: |
739 | dput(dentry); | 734 | dput(dentry); |
740 | dentry = ERR_PTR(-ENOMEM); | 735 | dentry = ERR_PTR(-ENOMEM); |
@@ -744,32 +739,26 @@ err_dput: | |||
744 | } | 739 | } |
745 | 740 | ||
746 | int | 741 | int |
747 | rpc_unlink(char *path) | 742 | rpc_unlink(struct dentry *dentry) |
748 | { | 743 | { |
749 | struct nameidata nd; | 744 | struct dentry *parent; |
750 | struct dentry *dentry; | ||
751 | struct inode *dir; | 745 | struct inode *dir; |
752 | int error; | 746 | int error = 0; |
753 | 747 | ||
754 | if ((error = rpc_lookup_parent(path, &nd)) != 0) | 748 | parent = dget_parent(dentry); |
755 | return error; | 749 | dir = parent->d_inode; |
756 | dir = nd.dentry->d_inode; | ||
757 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 750 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
758 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); | 751 | if (!d_unhashed(dentry)) { |
759 | if (IS_ERR(dentry)) { | 752 | d_drop(dentry); |
760 | error = PTR_ERR(dentry); | 753 | if (dentry->d_inode) { |
761 | goto out_release; | 754 | rpc_close_pipes(dentry->d_inode); |
762 | } | 755 | error = simple_unlink(dir, dentry); |
763 | d_drop(dentry); | 756 | } |
764 | if (dentry->d_inode) { | 757 | inode_dir_notify(dir, DN_DELETE); |
765 | rpc_close_pipes(dentry->d_inode); | ||
766 | error = simple_unlink(dir, dentry); | ||
767 | } | 758 | } |
768 | dput(dentry); | 759 | dput(dentry); |
769 | inode_dir_notify(dir, DN_DELETE); | ||
770 | out_release: | ||
771 | mutex_unlock(&dir->i_mutex); | 760 | mutex_unlock(&dir->i_mutex); |
772 | rpc_release_path(&nd); | 761 | dput(parent); |
773 | return error; | 762 | return error; |
774 | } | 763 | } |
775 | 764 | ||