aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/inode.c65
-rw-r--r--fs/ocfs2/inode.h2
-rw-r--r--fs/ocfs2/namei.c1
3 files changed, 39 insertions, 29 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 07cc8bb68b6d..26399202be7d 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -639,11 +639,13 @@ static int ocfs2_remove_inode(struct inode *inode,
639 goto bail_unlock; 639 goto bail_unlock;
640 } 640 }
641 641
642 status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, 642 if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
643 orphan_dir_bh); 643 status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
644 if (status < 0) { 644 orphan_dir_bh);
645 mlog_errno(status); 645 if (status < 0) {
646 goto bail_commit; 646 mlog_errno(status);
647 goto bail_commit;
648 }
647 } 649 }
648 650
649 /* set the inodes dtime */ 651 /* set the inodes dtime */
@@ -726,34 +728,35 @@ static int ocfs2_wipe_inode(struct inode *inode,
726 struct inode *orphan_dir_inode = NULL; 728 struct inode *orphan_dir_inode = NULL;
727 struct buffer_head *orphan_dir_bh = NULL; 729 struct buffer_head *orphan_dir_bh = NULL;
728 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 730 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
729 struct ocfs2_dinode *di; 731 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
730 732
731 di = (struct ocfs2_dinode *) di_bh->b_data; 733 if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
732 orphaned_slot = le16_to_cpu(di->i_orphaned_slot); 734 orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
733 735
734 status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); 736 status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
735 if (status) 737 if (status)
736 return status; 738 return status;
737 739
738 orphan_dir_inode = ocfs2_get_system_file_inode(osb, 740 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
739 ORPHAN_DIR_SYSTEM_INODE, 741 ORPHAN_DIR_SYSTEM_INODE,
740 orphaned_slot); 742 orphaned_slot);
741 if (!orphan_dir_inode) { 743 if (!orphan_dir_inode) {
742 status = -EEXIST; 744 status = -EEXIST;
743 mlog_errno(status); 745 mlog_errno(status);
744 goto bail; 746 goto bail;
745 } 747 }
746 748
747 /* Lock the orphan dir. The lock will be held for the entire 749 /* Lock the orphan dir. The lock will be held for the entire
748 * delete_inode operation. We do this now to avoid races with 750 * delete_inode operation. We do this now to avoid races with
749 * recovery completion on other nodes. */ 751 * recovery completion on other nodes. */
750 mutex_lock(&orphan_dir_inode->i_mutex); 752 mutex_lock(&orphan_dir_inode->i_mutex);
751 status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); 753 status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
752 if (status < 0) { 754 if (status < 0) {
753 mutex_unlock(&orphan_dir_inode->i_mutex); 755 mutex_unlock(&orphan_dir_inode->i_mutex);
754 756
755 mlog_errno(status); 757 mlog_errno(status);
756 goto bail; 758 goto bail;
759 }
757 } 760 }
758 761
759 /* we do this while holding the orphan dir lock because we 762 /* we do this while holding the orphan dir lock because we
@@ -794,6 +797,9 @@ static int ocfs2_wipe_inode(struct inode *inode,
794 mlog_errno(status); 797 mlog_errno(status);
795 798
796bail_unlock_dir: 799bail_unlock_dir:
800 if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
801 return status;
802
797 ocfs2_inode_unlock(orphan_dir_inode, 1); 803 ocfs2_inode_unlock(orphan_dir_inode, 1);
798 mutex_unlock(&orphan_dir_inode->i_mutex); 804 mutex_unlock(&orphan_dir_inode->i_mutex);
799 brelse(orphan_dir_bh); 805 brelse(orphan_dir_bh);
@@ -889,7 +895,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
889 895
890 /* Do some basic inode verification... */ 896 /* Do some basic inode verification... */
891 di = (struct ocfs2_dinode *) di_bh->b_data; 897 di = (struct ocfs2_dinode *) di_bh->b_data;
892 if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { 898 if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
899 !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
893 /* 900 /*
894 * Inodes in the orphan dir must have ORPHANED_FL. The only 901 * Inodes in the orphan dir must have ORPHANED_FL. The only
895 * inodes that come back out of the orphan dir are reflink 902 * inodes that come back out of the orphan dir are reflink
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index ba4fe07b293c..0b28e1921a39 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -100,6 +100,8 @@ struct ocfs2_inode_info
100#define OCFS2_INODE_MAYBE_ORPHANED 0x00000020 100#define OCFS2_INODE_MAYBE_ORPHANED 0x00000020
101/* Does someone have the file open O_DIRECT */ 101/* Does someone have the file open O_DIRECT */
102#define OCFS2_INODE_OPEN_DIRECT 0x00000040 102#define OCFS2_INODE_OPEN_DIRECT 0x00000040
103/* Tell the inode wipe code it's not in orphan dir */
104#define OCFS2_INODE_SKIP_ORPHAN_DIR 0x00000080
103 105
104static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) 106static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
105{ 107{
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index b1eb50ae4097..ae315c9c768f 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1976,6 +1976,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
1976 } 1976 }
1977 1977
1978 le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL); 1978 le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
1979 OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
1979 1980
1980 /* Record which orphan dir our inode now resides 1981 /* Record which orphan dir our inode now resides
1981 * in. delete_inode will use this to determine which orphan 1982 * in. delete_inode will use this to determine which orphan