提交 7540c1a7 编写于 作者: T Tao Ma 提交者: 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: NTao Ma <tao.ma@oracle.com>
上级 ce9c5a54
...@@ -1147,7 +1147,7 @@ static void ocfs2_refcount_rec_merge(struct ocfs2_refcount_block *rb, ...@@ -1147,7 +1147,7 @@ static void ocfs2_refcount_rec_merge(struct ocfs2_refcount_block *rb,
static int ocfs2_change_refcount_rec(handle_t *handle, static int ocfs2_change_refcount_rec(handle_t *handle,
struct ocfs2_caching_info *ci, struct ocfs2_caching_info *ci,
struct buffer_head *ref_leaf_bh, struct buffer_head *ref_leaf_bh,
int index, int change) int index, int merge, int change)
{ {
int ret; int ret;
struct ocfs2_refcount_block *rb = struct ocfs2_refcount_block *rb =
...@@ -1176,7 +1176,7 @@ static int ocfs2_change_refcount_rec(handle_t *handle, ...@@ -1176,7 +1176,7 @@ static int ocfs2_change_refcount_rec(handle_t *handle,
} }
le16_add_cpu(&rl->rl_used, -1); le16_add_cpu(&rl->rl_used, -1);
} else } else if (merge)
ocfs2_refcount_rec_merge(rb, index); ocfs2_refcount_rec_merge(rb, index);
ret = ocfs2_journal_dirty(handle, ref_leaf_bh); ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
...@@ -1652,7 +1652,7 @@ static int ocfs2_insert_refcount_rec(handle_t *handle, ...@@ -1652,7 +1652,7 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
struct buffer_head *ref_root_bh, struct buffer_head *ref_root_bh,
struct buffer_head *ref_leaf_bh, struct buffer_head *ref_leaf_bh,
struct ocfs2_refcount_rec *rec, struct ocfs2_refcount_rec *rec,
int index, int index, int merge,
struct ocfs2_alloc_context *meta_ac) struct ocfs2_alloc_context *meta_ac)
{ {
int ret; int ret;
...@@ -1710,7 +1710,8 @@ static int ocfs2_insert_refcount_rec(handle_t *handle, ...@@ -1710,7 +1710,8 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
le16_add_cpu(&rf_list->rl_used, 1); 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); ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
if (ret) { if (ret) {
...@@ -1744,7 +1745,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle, ...@@ -1744,7 +1745,7 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
struct buffer_head *ref_root_bh, struct buffer_head *ref_root_bh,
struct buffer_head *ref_leaf_bh, struct buffer_head *ref_leaf_bh,
struct ocfs2_refcount_rec *split_rec, struct ocfs2_refcount_rec *split_rec,
int index, int index, int merge,
struct ocfs2_alloc_context *meta_ac, struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc) struct ocfs2_cached_dealloc_ctxt *dealloc)
{ {
...@@ -1882,7 +1883,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle, ...@@ -1882,7 +1883,8 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
le32_to_cpu(split_rec->r_refcount), le32_to_cpu(split_rec->r_refcount),
(unsigned long long)ref_leaf_bh->b_blocknr, index); (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); ret = ocfs2_journal_dirty(handle, ref_leaf_bh);
...@@ -1894,12 +1896,12 @@ static int ocfs2_split_refcount_rec(handle_t *handle, ...@@ -1894,12 +1896,12 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
return ret; return ret;
} }
int ocfs2_increase_refcount(handle_t *handle, static int __ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_caching_info *ci, struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh, struct buffer_head *ref_root_bh,
u64 cpos, u32 len, u64 cpos, u32 len, int merge,
struct ocfs2_alloc_context *meta_ac, struct ocfs2_alloc_context *meta_ac,
struct ocfs2_cached_dealloc_ctxt *dealloc) struct ocfs2_cached_dealloc_ctxt *dealloc)
{ {
int ret = 0, index; int ret = 0, index;
struct buffer_head *ref_leaf_bh = NULL; struct buffer_head *ref_leaf_bh = NULL;
...@@ -1937,7 +1939,8 @@ int ocfs2_increase_refcount(handle_t *handle, ...@@ -1937,7 +1939,8 @@ int ocfs2_increase_refcount(handle_t *handle,
"count %u\n", (unsigned long long)cpos, set_len, "count %u\n", (unsigned long long)cpos, set_len,
le32_to_cpu(rec.r_refcount)); le32_to_cpu(rec.r_refcount));
ret = ocfs2_change_refcount_rec(handle, ci, ret = ocfs2_change_refcount_rec(handle, ci,
ref_leaf_bh, index, 1); ref_leaf_bh, index,
merge, 1);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
...@@ -1950,7 +1953,8 @@ int ocfs2_increase_refcount(handle_t *handle, ...@@ -1950,7 +1953,8 @@ int ocfs2_increase_refcount(handle_t *handle,
set_len); set_len);
ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh, ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh,
ref_leaf_bh, ref_leaf_bh,
&rec, index, meta_ac); &rec, index,
merge, meta_ac);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
...@@ -1968,7 +1972,7 @@ int ocfs2_increase_refcount(handle_t *handle, ...@@ -1968,7 +1972,7 @@ int ocfs2_increase_refcount(handle_t *handle,
set_len, le32_to_cpu(rec.r_refcount)); set_len, le32_to_cpu(rec.r_refcount));
ret = ocfs2_split_refcount_rec(handle, ci, ret = ocfs2_split_refcount_rec(handle, ci,
ref_root_bh, ref_leaf_bh, ref_root_bh, ref_leaf_bh,
&rec, index, &rec, index, merge,
meta_ac, dealloc); meta_ac, dealloc);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
...@@ -2061,6 +2065,18 @@ static int ocfs2_remove_refcount_extent(handle_t *handle, ...@@ -2061,6 +2065,18 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
return ret; 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, static int ocfs2_decrease_refcount_rec(handle_t *handle,
struct ocfs2_caching_info *ci, struct ocfs2_caching_info *ci,
struct buffer_head *ref_root_bh, struct buffer_head *ref_root_bh,
...@@ -2081,7 +2097,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle, ...@@ -2081,7 +2097,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
if (cpos == le64_to_cpu(rec->r_cpos) && if (cpos == le64_to_cpu(rec->r_cpos) &&
len == le32_to_cpu(rec->r_clusters)) len == le32_to_cpu(rec->r_clusters))
ret = ocfs2_change_refcount_rec(handle, ci, ret = ocfs2_change_refcount_rec(handle, ci,
ref_leaf_bh, index, -1); ref_leaf_bh, index, 1, -1);
else { else {
struct ocfs2_refcount_rec split = *rec; struct ocfs2_refcount_rec split = *rec;
split.r_cpos = cpu_to_le64(cpos); split.r_cpos = cpu_to_le64(cpos);
...@@ -2097,7 +2113,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle, ...@@ -2097,7 +2113,7 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
le32_to_cpu(rec->r_clusters)); le32_to_cpu(rec->r_clusters));
ret = ocfs2_split_refcount_rec(handle, ci, ret = ocfs2_split_refcount_rec(handle, ci,
ref_root_bh, ref_leaf_bh, ref_root_bh, ref_leaf_bh,
&split, index, &split, index, 1,
meta_ac, dealloc); meta_ac, dealloc);
} }
...@@ -3631,9 +3647,9 @@ int ocfs2_add_refcount_flag(struct inode *inode, ...@@ -3631,9 +3647,9 @@ int ocfs2_add_refcount_flag(struct inode *inode,
goto out_commit; goto out_commit;
} }
ret = ocfs2_increase_refcount(handle, ref_ci, ref_root_bh, ret = __ocfs2_increase_refcount(handle, ref_ci, ref_root_bh,
p_cluster, num_clusters, p_cluster, num_clusters, 0,
meta_ac, dealloc); meta_ac, dealloc);
if (ret) { if (ret) {
mlog_errno(ret); mlog_errno(ret);
goto out_commit; goto out_commit;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册