|
@@ -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;
|