ocfs2: Don't merge in 1st refcount ops of reflink.
[pandora-kernel.git] / fs / ocfs2 / refcounttree.c
index dc57d06..47df8c5 100644 (file)
@@ -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;