Updated to 2.6.32.27
/fs/ocfs2/refcounttree.c
blob:10e9527dda1f98cf0b0d5e0fa2c4610610990973 -> blob:03a1ab83a65b08544c0b9c7493431b0a122ab35a
--- fs/ocfs2/refcounttree.c
+++ fs/ocfs2/refcounttree.c
@@ -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))