Skip to content

Commit

Permalink
ocfs2: Don't merge in 1st refcount ops of reflink.
Browse files Browse the repository at this point in the history
Actually the whole reflink will touch refcount tree 2 times:
1. It will add the clusters in the extent record to the tree if it
   isn't refcounted before.
2. It will add 1 refcount to these clusters when it add these
   extent records to the tree.

So actually we shouldn't do merge in the 1st operation since the 2nd
one will soon be called and we may have to split it again. Do a merge
first and split soon is a waste of time. So we only merge in the 2nd
round. This is done by adding a new internal __ocfs2_increase_refcount
and call it with "not-merge" for 1st refcount operation in reflink.

This also has a side-effect that we don't need to worry too much about
the metadata allocation in the 2nd round since it will only merge and
no split will happen for those records.

Signed-off-by: Tao Ma <tao.ma@oracle.com>
  • Loading branch information
Tao Ma authored and Joel Becker committed Sep 23, 2009
1 parent ce9c5a5 commit 7540c1a
Showing 1 changed file with 36 additions and 20 deletions.
56 changes: 36 additions & 20 deletions fs/ocfs2/refcounttree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ static void ocfs2_refcount_rec_merge(struct ocfs2_refcount_block *rb,
static int ocfs2_change_refcount_rec(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_leaf_bh,
int index, int change)
int index, int merge, int change)
{
int ret;
struct ocfs2_refcount_block *rb =
Expand Down Expand Up @@ -1176,7 +1176,7 @@ static int ocfs2_change_refcount_rec(handle_t *handle,
}

le16_add_cpu(&rl->rl_used, -1);
} else
} else if (merge)
ocfs2_refcount_rec_merge(rb, index);

ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
Expand Down Expand Up @@ -1652,7 +1652,7 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
struct buffer_head *ref_root_bh,
struct buffer_head *ref_leaf_bh,
struct ocfs2_refcount_rec *rec,
int index,
int index, int merge,
struct ocfs2_alloc_context *meta_ac)
{
int ret;
Expand Down Expand Up @@ -1710,7 +1710,8 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,

le16_add_cpu(&rf_list->rl_used, 1);

ocfs2_refcount_rec_merge(rb, index);
if (merge)
ocfs2_refcount_rec_merge(rb, index);

ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
if (ret) {
Expand Down Expand Up @@ -1744,7 +1745,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
struct buffer_head *ref_root_bh,
struct buffer_head *ref_leaf_bh,
struct ocfs2_refcount_rec *split_rec,
int index,
int index, int merge,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
{
Expand Down Expand Up @@ -1882,7 +1883,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
le32_to_cpu(split_rec->r_refcount),
(unsigned long long)ref_leaf_bh->b_blocknr, index);

ocfs2_refcount_rec_merge(rb, index);
if (merge)
ocfs2_refcount_rec_merge(rb, index);
}

ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
Expand All @@ -1894,12 +1896,12 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
return ret;
}

int ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh,
u64 cpos, u32 len,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
static int __ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh,
u64 cpos, u32 len, int merge,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
{
int ret = 0, index;
struct buffer_head *ref_leaf_bh = NULL;
Expand Down Expand Up @@ -1937,7 +1939,8 @@ int ocfs2_increase_refcount(handle_t *handle,
"count %u\n", (unsigned long long)cpos, set_len,
le32_to_cpu(rec.r_refcount));
ret = ocfs2_change_refcount_rec(handle, ci,
ref_leaf_bh, index, 1);
ref_leaf_bh, index,
merge, 1);
if (ret) {
mlog_errno(ret);
goto out;
Expand All @@ -1950,7 +1953,8 @@ int ocfs2_increase_refcount(handle_t *handle,
set_len);
ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh,
ref_leaf_bh,
&rec, index, meta_ac);
&rec, index,
merge, meta_ac);
if (ret) {
mlog_errno(ret);
goto out;
Expand All @@ -1968,7 +1972,7 @@ int ocfs2_increase_refcount(handle_t *handle,
set_len, le32_to_cpu(rec.r_refcount));
ret = ocfs2_split_refcount_rec(handle, ci,
ref_root_bh, ref_leaf_bh,
&rec, index,
&rec, index, merge,
meta_ac, dealloc);
if (ret) {
mlog_errno(ret);
Expand Down Expand Up @@ -2061,6 +2065,18 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
return ret;
}

int ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh,
u64 cpos, u32 len,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
{
return __ocfs2_increase_refcount(handle, ci, ref_root_bh,
cpos, len, 1,
meta_ac, dealloc);
}

static int ocfs2_decrease_refcount_rec(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh,
Expand All @@ -2081,7 +2097,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
if (cpos == le64_to_cpu(rec->r_cpos) &&
len == le32_to_cpu(rec->r_clusters))
ret = ocfs2_change_refcount_rec(handle, ci,
ref_leaf_bh, index, -1);
ref_leaf_bh, index, 1, -1);
else {
struct ocfs2_refcount_rec split = *rec;
split.r_cpos = cpu_to_le64(cpos);
Expand All @@ -2097,7 +2113,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
le32_to_cpu(rec->r_clusters));
ret = ocfs2_split_refcount_rec(handle, ci,
ref_root_bh, ref_leaf_bh,
&split, index,
&split, index, 1,
meta_ac, dealloc);
}

Expand Down Expand Up @@ -3631,9 +3647,9 @@ int ocfs2_add_refcount_flag(struct inode *inode,
goto out_commit;
}

ret = ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
p_cluster, num_clusters,
meta_ac, dealloc);
ret = __ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
p_cluster, num_clusters, 0,
meta_ac, dealloc);
if (ret) {
mlog_errno(ret);
goto out_commit;
Expand Down

0 comments on commit 7540c1a

Please sign in to comment.