diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/inode.c | 65 | ||||
-rw-r--r-- | fs/ocfs2/inode.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/namei.c | 1 |
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 | ||
796 | bail_unlock_dir: | 799 | bail_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 | ||
104 | static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) | 106 | static 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 |