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 |
