diff options
Diffstat (limited to 'fs/ocfs2/inode.c')
-rw-r--r-- | fs/ocfs2/inode.c | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 07cc8bb68b6d..af189887201c 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -558,6 +558,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
558 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | 558 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
559 | if (IS_ERR(handle)) { | 559 | if (IS_ERR(handle)) { |
560 | status = PTR_ERR(handle); | 560 | status = PTR_ERR(handle); |
561 | handle = NULL; | ||
561 | mlog_errno(status); | 562 | mlog_errno(status); |
562 | goto out; | 563 | goto out; |
563 | } | 564 | } |
@@ -639,11 +640,13 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
639 | goto bail_unlock; | 640 | goto bail_unlock; |
640 | } | 641 | } |
641 | 642 | ||
642 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, | 643 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
643 | orphan_dir_bh); | 644 | status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode, |
644 | if (status < 0) { | 645 | orphan_dir_bh); |
645 | mlog_errno(status); | 646 | if (status < 0) { |
646 | goto bail_commit; | 647 | mlog_errno(status); |
648 | goto bail_commit; | ||
649 | } | ||
647 | } | 650 | } |
648 | 651 | ||
649 | /* set the inodes dtime */ | 652 | /* set the inodes dtime */ |
@@ -722,38 +725,39 @@ static void ocfs2_signal_wipe_completion(struct ocfs2_super *osb, | |||
722 | static int ocfs2_wipe_inode(struct inode *inode, | 725 | static int ocfs2_wipe_inode(struct inode *inode, |
723 | struct buffer_head *di_bh) | 726 | struct buffer_head *di_bh) |
724 | { | 727 | { |
725 | int status, orphaned_slot; | 728 | int status, orphaned_slot = -1; |
726 | struct inode *orphan_dir_inode = NULL; | 729 | struct inode *orphan_dir_inode = NULL; |
727 | struct buffer_head *orphan_dir_bh = NULL; | 730 | struct buffer_head *orphan_dir_bh = NULL; |
728 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 731 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
729 | struct ocfs2_dinode *di; | 732 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
730 | 733 | ||
731 | di = (struct ocfs2_dinode *) di_bh->b_data; | 734 | if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { |
732 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); | 735 | orphaned_slot = le16_to_cpu(di->i_orphaned_slot); |
733 | 736 | ||
734 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); | 737 | status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot); |
735 | if (status) | 738 | if (status) |
736 | return status; | 739 | return status; |
737 | 740 | ||
738 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 741 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
739 | ORPHAN_DIR_SYSTEM_INODE, | 742 | ORPHAN_DIR_SYSTEM_INODE, |
740 | orphaned_slot); | 743 | orphaned_slot); |
741 | if (!orphan_dir_inode) { | 744 | if (!orphan_dir_inode) { |
742 | status = -EEXIST; | 745 | status = -EEXIST; |
743 | mlog_errno(status); | 746 | mlog_errno(status); |
744 | goto bail; | 747 | goto bail; |
745 | } | 748 | } |
746 | 749 | ||
747 | /* Lock the orphan dir. The lock will be held for the entire | 750 | /* Lock the orphan dir. The lock will be held for the entire |
748 | * delete_inode operation. We do this now to avoid races with | 751 | * delete_inode operation. We do this now to avoid races with |
749 | * recovery completion on other nodes. */ | 752 | * recovery completion on other nodes. */ |
750 | mutex_lock(&orphan_dir_inode->i_mutex); | 753 | mutex_lock(&orphan_dir_inode->i_mutex); |
751 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); | 754 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
752 | if (status < 0) { | 755 | if (status < 0) { |
753 | mutex_unlock(&orphan_dir_inode->i_mutex); | 756 | mutex_unlock(&orphan_dir_inode->i_mutex); |
754 | 757 | ||
755 | mlog_errno(status); | 758 | mlog_errno(status); |
756 | goto bail; | 759 | goto bail; |
760 | } | ||
757 | } | 761 | } |
758 | 762 | ||
759 | /* we do this while holding the orphan dir lock because we | 763 | /* we do this while holding the orphan dir lock because we |
@@ -794,6 +798,9 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
794 | mlog_errno(status); | 798 | mlog_errno(status); |
795 | 799 | ||
796 | bail_unlock_dir: | 800 | bail_unlock_dir: |
801 | if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR) | ||
802 | return status; | ||
803 | |||
797 | ocfs2_inode_unlock(orphan_dir_inode, 1); | 804 | ocfs2_inode_unlock(orphan_dir_inode, 1); |
798 | mutex_unlock(&orphan_dir_inode->i_mutex); | 805 | mutex_unlock(&orphan_dir_inode->i_mutex); |
799 | brelse(orphan_dir_bh); | 806 | brelse(orphan_dir_bh); |
@@ -889,7 +896,8 @@ static int ocfs2_query_inode_wipe(struct inode *inode, | |||
889 | 896 | ||
890 | /* Do some basic inode verification... */ | 897 | /* Do some basic inode verification... */ |
891 | di = (struct ocfs2_dinode *) di_bh->b_data; | 898 | di = (struct ocfs2_dinode *) di_bh->b_data; |
892 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) { | 899 | if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) && |
900 | !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) { | ||
893 | /* | 901 | /* |
894 | * Inodes in the orphan dir must have ORPHANED_FL. The only | 902 | * Inodes in the orphan dir must have ORPHANED_FL. The only |
895 | * inodes that come back out of the orphan dir are reflink | 903 | * inodes that come back out of the orphan dir are reflink |