aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-08-10 17:51:46 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-08-24 15:50:42 -0400
commit68adb0af51ebccb72ffb14d49cb8121b1afc4259 (patch)
treecfe18744aa4a96680cf344092cff9a741fe152c3
parentdff02cc1a34fcb60904a2c57cb351857cc11219e (diff)
SUNRPC: rpc_unlink() must check for unhashed dentries
A prior call to rpc_depopulate() by rpc_rmdir() on the parent directory may have already called simple_unlink() on this entry. Add the same check to rpc_rmdir(). Also remove a redundant call to rpc_close_pipes() in rpc_rmdir. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> (cherry picked from 0bbfb9d20f6437c4031aa3bf9b4d311a053e58e3 commit)
-rw-r--r--net/sunrpc/rpc_pipe.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 9c355e1ae61a..0b1a1ac8a4bc 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) {
@@ -747,13 +748,15 @@ rpc_unlink(struct dentry *dentry)
747 parent = dget_parent(dentry); 748 parent = dget_parent(dentry);
748 dir = parent->d_inode; 749 dir = parent->d_inode;
749 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); 750 mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
750 d_drop(dentry); 751 if (!d_unhashed(dentry)) {
751 if (dentry->d_inode) { 752 d_drop(dentry);
752 rpc_close_pipes(dentry->d_inode); 753 if (dentry->d_inode) {
753 error = simple_unlink(dir, dentry); 754 rpc_close_pipes(dentry->d_inode);
755 error = simple_unlink(dir, dentry);
756 }
757 inode_dir_notify(dir, DN_DELETE);
754 } 758 }
755 dput(dentry); 759 dput(dentry);
756 inode_dir_notify(dir, DN_DELETE);
757 mutex_unlock(&dir->i_mutex); 760 mutex_unlock(&dir->i_mutex);
758 dput(parent); 761 dput(parent);
759 return error; 762 return error;