diff options
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index d8c78150e9ca..cf30bf58bfcf 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -601,6 +601,29 @@ static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry, | |||
601 | return 0; | 601 | return 0; |
602 | } | 602 | } |
603 | 603 | ||
604 | static int __rpc_unlink(struct inode *dir, struct dentry *dentry) | ||
605 | { | ||
606 | int ret; | ||
607 | |||
608 | dget(dentry); | ||
609 | ret = simple_unlink(dir, dentry); | ||
610 | d_delete(dentry); | ||
611 | dput(dentry); | ||
612 | return ret; | ||
613 | } | ||
614 | |||
615 | static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry) | ||
616 | { | ||
617 | struct inode *inode = dentry->d_inode; | ||
618 | struct rpc_inode *rpci = RPC_I(inode); | ||
619 | |||
620 | rpci->nkern_readwriters--; | ||
621 | if (rpci->nkern_readwriters != 0) | ||
622 | return 0; | ||
623 | rpc_close_pipes(inode); | ||
624 | return __rpc_unlink(dir, dentry); | ||
625 | } | ||
626 | |||
604 | /* | 627 | /* |
605 | * FIXME: This probably has races. | 628 | * FIXME: This probably has races. |
606 | */ | 629 | */ |
@@ -848,14 +871,15 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name, | |||
848 | rpci->ops != ops || | 871 | rpci->ops != ops || |
849 | rpci->flags != flags) { | 872 | rpci->flags != flags) { |
850 | dput (dentry); | 873 | dput (dentry); |
851 | dentry = ERR_PTR(-EBUSY); | 874 | err = -EBUSY; |
875 | goto out_err; | ||
852 | } | 876 | } |
853 | rpci->nkern_readwriters++; | 877 | rpci->nkern_readwriters++; |
854 | goto out; | 878 | goto out; |
855 | } | 879 | } |
856 | 880 | ||
857 | err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops, | 881 | err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops, |
858 | private, ops, flags); | 882 | private, ops, flags); |
859 | if (err) | 883 | if (err) |
860 | goto out_err; | 884 | goto out_err; |
861 | dget(dentry); | 885 | dget(dentry); |
@@ -889,12 +913,7 @@ rpc_unlink(struct dentry *dentry) | |||
889 | parent = dget_parent(dentry); | 913 | parent = dget_parent(dentry); |
890 | dir = parent->d_inode; | 914 | dir = parent->d_inode; |
891 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 915 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
892 | if (--RPC_I(dentry->d_inode)->nkern_readwriters == 0) { | 916 | error = __rpc_rmpipe(dir, dentry); |
893 | rpc_close_pipes(dentry->d_inode); | ||
894 | error = simple_unlink(dir, dentry); | ||
895 | if (!error) | ||
896 | d_delete(dentry); | ||
897 | } | ||
898 | dput(dentry); | 917 | dput(dentry); |
899 | mutex_unlock(&dir->i_mutex); | 918 | mutex_unlock(&dir->i_mutex); |
900 | dput(parent); | 919 | dput(parent); |