Commit 7540c1a7 authored by Tao Ma's avatar Tao Ma Committed by Joel Becker

ocfs2: Don't merge in 1st refcount ops of reflink.

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: default avatarTao Ma <tao.ma@oracle.com>
parent ce9c5a54
......@@ -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 =
......@@ -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);
......@@ -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;
......@@ -1710,6 +1710,7 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
le16_add_cpu(&rf_list->rl_used, 1);
if (merge)
ocfs2_refcount_rec_merge(rb, index);
ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
......@@ -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)
{
......@@ -1882,6 +1883,7 @@ 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);
if (merge)
ocfs2_refcount_rec_merge(rb, index);
}
......@@ -1894,10 +1896,10 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
return ret;
}
int ocfs2_increase_refcount(handle_t *handle,
static int __ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh,
u64 cpos, u32 len,
u64 cpos, u32 len, int merge,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc)
{
......@@ -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;
......@@ -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;
......@@ -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);
......@@ -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,
......@@ -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);
......@@ -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);
}
......@@ -3631,8 +3647,8 @@ 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,
ret = __ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
p_cluster, num_clusters, 0,
meta_ac, dealloc);
if (ret) {
mlog_errno(ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment