summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/refcounttree.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index dc57d06..47df8c5 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -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,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) {
@@ -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,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);
@@ -1894,12 +1896,12 @@ out:
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;
@@ -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 @@ out:
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,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;
OpenPOWER on IntegriCloud