aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/namei.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index dc2e89a0c4af..f64cff0ceed8 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -813,6 +813,7 @@ static int ocfs2_unlink(struct inode *dir,
813 struct dentry *dentry) 813 struct dentry *dentry)
814{ 814{
815 int status; 815 int status;
816 int child_locked = 0;
816 struct inode *inode = dentry->d_inode; 817 struct inode *inode = dentry->d_inode;
817 struct inode *orphan_dir = NULL; 818 struct inode *orphan_dir = NULL;
818 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); 819 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
@@ -835,22 +836,14 @@ static int ocfs2_unlink(struct inode *dir,
835 836
836 if (inode == osb->root_inode) { 837 if (inode == osb->root_inode) {
837 mlog(0, "Cannot delete the root directory\n"); 838 mlog(0, "Cannot delete the root directory\n");
838 status = -EPERM; 839 return -EPERM;
839 goto leave;
840 }
841
842 handle = ocfs2_alloc_handle(osb);
843 if (handle == NULL) {
844 status = -ENOMEM;
845 mlog_errno(status);
846 goto leave;
847 } 840 }
848 841
849 status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1); 842 status = ocfs2_meta_lock(dir, NULL, &parent_node_bh, 1);
850 if (status < 0) { 843 if (status < 0) {
851 if (status != -ENOENT) 844 if (status != -ENOENT)
852 mlog_errno(status); 845 mlog_errno(status);
853 goto leave; 846 return status;
854 } 847 }
855 848
856 status = ocfs2_find_files_on_disk(dentry->d_name.name, 849 status = ocfs2_find_files_on_disk(dentry->d_name.name,
@@ -871,12 +864,13 @@ static int ocfs2_unlink(struct inode *dir,
871 goto leave; 864 goto leave;
872 } 865 }
873 866
874 status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); 867 status = ocfs2_meta_lock(inode, NULL, &fe_bh, 1);
875 if (status < 0) { 868 if (status < 0) {
876 if (status != -ENOENT) 869 if (status != -ENOENT)
877 mlog_errno(status); 870 mlog_errno(status);
878 goto leave; 871 goto leave;
879 } 872 }
873 child_locked = 1;
880 874
881 if (S_ISDIR(inode->i_mode)) { 875 if (S_ISDIR(inode->i_mode)) {
882 if (!ocfs2_empty_dir(inode)) { 876 if (!ocfs2_empty_dir(inode)) {
@@ -906,7 +900,7 @@ static int ocfs2_unlink(struct inode *dir,
906 } 900 }
907 } 901 }
908 902
909 handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); 903 handle = ocfs2_start_trans(osb, NULL, OCFS2_UNLINK_CREDITS);
910 if (IS_ERR(handle)) { 904 if (IS_ERR(handle)) {
911 status = PTR_ERR(handle); 905 status = PTR_ERR(handle);
912 handle = NULL; 906 handle = NULL;
@@ -964,6 +958,11 @@ leave:
964 if (handle) 958 if (handle)
965 ocfs2_commit_trans(handle); 959 ocfs2_commit_trans(handle);
966 960
961 if (child_locked)
962 ocfs2_meta_unlock(inode, 1);
963
964 ocfs2_meta_unlock(dir, 1);
965
967 if (orphan_dir) { 966 if (orphan_dir) {
968 /* This was locked for us in ocfs2_prepare_orphan_dir() */ 967 /* This was locked for us in ocfs2_prepare_orphan_dir() */
969 ocfs2_meta_unlock(orphan_dir, 1); 968 ocfs2_meta_unlock(orphan_dir, 1);