--- 8371a2527a9a317d2f54432eb6e6bc9914e06c6d +++ 03a1ab83a65b08544c0b9c7493431b0a122ab35a @@ -969,103 +969,6 @@ out: } /* - * Find the end range for a leaf refcount block indicated by - * el->l_recs[index].e_blkno. - */ -static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, - struct buffer_head *ref_root_bh, - struct ocfs2_extent_block *eb, - struct ocfs2_extent_list *el, - int index, u32 *cpos_end) -{ - int ret, i, subtree_root; - u32 cpos; - u64 blkno; - struct super_block *sb = ocfs2_metadata_cache_get_super(ci); - struct ocfs2_path *left_path = NULL, *right_path = NULL; - struct ocfs2_extent_tree et; - struct ocfs2_extent_list *tmp_el; - - if (index < le16_to_cpu(el->l_next_free_rec) - 1) { - /* - * We have a extent rec after index, so just use the e_cpos - * of the next extent rec. - */ - *cpos_end = le32_to_cpu(el->l_recs[index+1].e_cpos); - return 0; - } - - if (!eb || (eb && !eb->h_next_leaf_blk)) { - /* - * We are the last extent rec, so any high cpos should - * be stored in this leaf refcount block. - */ - *cpos_end = UINT_MAX; - return 0; - } - - /* - * If the extent block isn't the last one, we have to find - * the subtree root between this extent block and the next - * leaf extent block and get the corresponding e_cpos from - * the subroot. Otherwise we may corrupt the b-tree. - */ - ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh); - - left_path = ocfs2_new_path_from_et(&et); - if (!left_path) { - ret = -ENOMEM; - mlog_errno(ret); - goto out; - } - - cpos = le32_to_cpu(eb->h_list.l_recs[index].e_cpos); - ret = ocfs2_find_path(ci, left_path, cpos); - if (ret) { - mlog_errno(ret); - goto out; - } - - right_path = ocfs2_new_path_from_path(left_path); - if (!right_path) { - ret = -ENOMEM; - mlog_errno(ret); - goto out; - } - - ret = ocfs2_find_cpos_for_right_leaf(sb, left_path, &cpos); - if (ret) { - mlog_errno(ret); - goto out; - } - - ret = ocfs2_find_path(ci, right_path, cpos); - if (ret) { - mlog_errno(ret); - goto out; - } - - subtree_root = ocfs2_find_subtree_root(&et, left_path, - right_path); - - tmp_el = left_path->p_node[subtree_root].el; - blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; - for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { - if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { - *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); - break; - } - } - - BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); - -out: - ocfs2_free_path(left_path); - ocfs2_free_path(right_path); - return ret; -} - -/* * Given a cpos and len, try to find the refcount record which contains cpos. * 1. If cpos can be found in one refcount record, return the record. * 2. If cpos can't be found, return a fake record which start from cpos @@ -1080,10 +983,10 @@ static int ocfs2_get_refcount_rec(struct struct buffer_head **ret_bh) { int ret = 0, i, found; - u32 low_cpos, uninitialized_var(cpos_end); + u32 low_cpos; struct ocfs2_extent_list *el; - struct ocfs2_extent_rec *rec = NULL; - struct ocfs2_extent_block *eb = NULL; + struct ocfs2_extent_rec *tmp, *rec = NULL; + struct ocfs2_extent_block *eb; struct buffer_head *eb_bh = NULL, *ref_leaf_bh = NULL; struct super_block *sb = ocfs2_metadata_cache_get_super(ci); struct ocfs2_refcount_block *rb = @@ -1131,16 +1034,12 @@ static int ocfs2_get_refcount_rec(struct } } - if (found) { - ret = ocfs2_get_refcount_cpos_end(ci, ref_root_bh, - eb, el, i, &cpos_end); - if (ret) { - mlog_errno(ret); - goto out; - } + /* adjust len when we have ocfs2_extent_rec after it. */ + if (found && i < le16_to_cpu(el->l_next_free_rec) - 1) { + tmp = &el->l_recs[i+1]; - if (cpos_end < low_cpos + len) - len = cpos_end - low_cpos; + if (le32_to_cpu(tmp->e_cpos) < cpos + len) + len = le32_to_cpu(tmp->e_cpos) - cpos; } ret = ocfs2_read_refcount_block(ci, le64_to_cpu(rec->e_blkno), @@ -2454,26 +2353,16 @@ static int ocfs2_calc_refcount_meta_cred len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) + le32_to_cpu(rec.r_clusters)) - cpos; /* + * If the refcount rec already exist, cool. We just need + * to check whether there is a split. Otherwise we just need + * to increase the refcount. + * If we will insert one, increases recs_add. + * * We record all the records which will be inserted to the * same refcount block, so that we can tell exactly whether * we need a new refcount block or not. - * - * If we will insert a new one, this is easy and only happens - * during adding refcounted flag to the extent, so we don't - * have a chance of spliting. We just need one record. - * - * If the refcount rec already exists, that would be a little - * complicated. we may have to: - * 1) split at the beginning if the start pos isn't aligned. - * we need 1 more record in this case. - * 2) split int the end if the end pos isn't aligned. - * we need 1 more record in this case. - * 3) split in the middle because of file system fragmentation. - * we need 2 more records in this case(we can't detect this - * beforehand, so always think of the worst case). */ if (rec.r_refcount) { - recs_add += 2; /* Check whether we need a split at the beginning. */ if (cpos == start_cpos && cpos != le64_to_cpu(rec.r_cpos)) @@ -3236,7 +3125,7 @@ static int ocfs2_make_clusters_writable( u32 num_clusters, unsigned int e_flags) { int ret, delete, index, credits = 0; - u32 new_bit, new_len, orig_num_clusters; + u32 new_bit, new_len; unsigned int set_len; struct ocfs2_super *osb = OCFS2_SB(sb); handle_t *handle; @@ -3269,8 +3158,6 @@ static int ocfs2_make_clusters_writable( goto out; } - orig_num_clusters = num_clusters; - while (num_clusters) { ret = ocfs2_get_refcount_rec(ref_ci, context->ref_root_bh, p_cluster, num_clusters, @@ -3358,8 +3245,7 @@ static int ocfs2_make_clusters_writable( * in write-back mode. */ if (context->get_clusters == ocfs2_di_get_clusters) { - ret = ocfs2_cow_sync_writeback(sb, context, cpos, - orig_num_clusters); + ret = ocfs2_cow_sync_writeback(sb, context, cpos, num_clusters); if (ret) mlog_errno(ret); }