aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/alloc.c94
1 files changed, 86 insertions, 8 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index f63cb32e224d..7d81aa6f5672 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -3782,20 +3782,57 @@ out:
3782} 3782}
3783 3783
3784static enum ocfs2_contig_type 3784static enum ocfs2_contig_type
3785ocfs2_figure_merge_contig_type(struct inode *inode, 3785ocfs2_figure_merge_contig_type(struct inode *inode, struct ocfs2_path *path,
3786 struct ocfs2_extent_list *el, int index, 3786 struct ocfs2_extent_list *el, int index,
3787 struct ocfs2_extent_rec *split_rec) 3787 struct ocfs2_extent_rec *split_rec)
3788{ 3788{
3789 struct ocfs2_extent_rec *rec; 3789 int status;
3790 enum ocfs2_contig_type ret = CONTIG_NONE; 3790 enum ocfs2_contig_type ret = CONTIG_NONE;
3791 u32 left_cpos, right_cpos;
3792 struct ocfs2_extent_rec *rec = NULL;
3793 struct ocfs2_extent_list *new_el;
3794 struct ocfs2_path *left_path = NULL, *right_path = NULL;
3795 struct buffer_head *bh;
3796 struct ocfs2_extent_block *eb;
3797
3798 if (index > 0) {
3799 rec = &el->l_recs[index - 1];
3800 } else if (path->p_tree_depth > 0) {
3801 status = ocfs2_find_cpos_for_left_leaf(inode->i_sb,
3802 path, &left_cpos);
3803 if (status)
3804 goto out;
3805
3806 if (left_cpos != 0) {
3807 left_path = ocfs2_new_path(path_root_bh(path),
3808 path_root_el(path));
3809 if (!left_path)
3810 goto out;
3811
3812 status = ocfs2_find_path(inode, left_path, left_cpos);
3813 if (status)
3814 goto out;
3815
3816 new_el = path_leaf_el(left_path);
3817
3818 if (le16_to_cpu(new_el->l_next_free_rec) !=
3819 le16_to_cpu(new_el->l_count)) {
3820 bh = path_leaf_bh(left_path);
3821 eb = (struct ocfs2_extent_block *)bh->b_data;
3822 OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb,
3823 eb);
3824 goto out;
3825 }
3826 rec = &new_el->l_recs[
3827 le16_to_cpu(new_el->l_next_free_rec) - 1];
3828 }
3829 }
3791 3830
3792 /* 3831 /*
3793 * We're careful to check for an empty extent record here - 3832 * We're careful to check for an empty extent record here -
3794 * the merge code will know what to do if it sees one. 3833 * the merge code will know what to do if it sees one.
3795 */ 3834 */
3796 3835 if (rec) {
3797 if (index > 0) {
3798 rec = &el->l_recs[index - 1];
3799 if (index == 1 && ocfs2_is_empty_extent(rec)) { 3836 if (index == 1 && ocfs2_is_empty_extent(rec)) {
3800 if (split_rec->e_cpos == el->l_recs[index].e_cpos) 3837 if (split_rec->e_cpos == el->l_recs[index].e_cpos)
3801 ret = CONTIG_RIGHT; 3838 ret = CONTIG_RIGHT;
@@ -3804,10 +3841,45 @@ ocfs2_figure_merge_contig_type(struct inode *inode,
3804 } 3841 }
3805 } 3842 }
3806 3843
3807 if (index < (le16_to_cpu(el->l_next_free_rec) - 1)) { 3844 rec = NULL;
3845 if (index < (le16_to_cpu(el->l_next_free_rec) - 1))
3846 rec = &el->l_recs[index + 1];
3847 else if (le16_to_cpu(el->l_next_free_rec) == le16_to_cpu(el->l_count) &&
3848 path->p_tree_depth > 0) {
3849 status = ocfs2_find_cpos_for_right_leaf(inode->i_sb,
3850 path, &right_cpos);
3851 if (status)
3852 goto out;
3853
3854 if (right_cpos == 0)
3855 goto out;
3856
3857 right_path = ocfs2_new_path(path_root_bh(path),
3858 path_root_el(path));
3859 if (!right_path)
3860 goto out;
3861
3862 status = ocfs2_find_path(inode, right_path, right_cpos);
3863 if (status)
3864 goto out;
3865
3866 new_el = path_leaf_el(right_path);
3867 rec = &new_el->l_recs[0];
3868 if (ocfs2_is_empty_extent(rec)) {
3869 if (le16_to_cpu(new_el->l_next_free_rec) <= 1) {
3870 bh = path_leaf_bh(right_path);
3871 eb = (struct ocfs2_extent_block *)bh->b_data;
3872 OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb,
3873 eb);
3874 goto out;
3875 }
3876 rec = &new_el->l_recs[1];
3877 }
3878 }
3879
3880 if (rec) {
3808 enum ocfs2_contig_type contig_type; 3881 enum ocfs2_contig_type contig_type;
3809 3882
3810 rec = &el->l_recs[index + 1];
3811 contig_type = ocfs2_extent_contig(inode, rec, split_rec); 3883 contig_type = ocfs2_extent_contig(inode, rec, split_rec);
3812 3884
3813 if (contig_type == CONTIG_LEFT && ret == CONTIG_RIGHT) 3885 if (contig_type == CONTIG_LEFT && ret == CONTIG_RIGHT)
@@ -3816,6 +3888,12 @@ ocfs2_figure_merge_contig_type(struct inode *inode,
3816 ret = contig_type; 3888 ret = contig_type;
3817 } 3889 }
3818 3890
3891out:
3892 if (left_path)
3893 ocfs2_free_path(left_path);
3894 if (right_path)
3895 ocfs2_free_path(right_path);
3896
3819 return ret; 3897 return ret;
3820} 3898}
3821 3899
@@ -4278,7 +4356,7 @@ static int __ocfs2_mark_extent_written(struct inode *inode,
4278 goto out; 4356 goto out;
4279 } 4357 }
4280 4358
4281 ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, el, 4359 ctxt.c_contig_type = ocfs2_figure_merge_contig_type(inode, path, el,
4282 split_index, 4360 split_index,
4283 split_rec); 4361 split_rec);
4284 4362