MIPS: Oprofile: Loongson: Unify macro for setting events
[cascardo/linux.git] / fs / ocfs2 / alloc.c
index 9f8bd91..215e12c 100644 (file)
@@ -1006,7 +1006,7 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
        int count, status, i;
        u16 suballoc_bit_start;
        u32 num_got;
-       u64 first_blkno;
+       u64 suballoc_loc, first_blkno;
        struct ocfs2_super *osb =
                OCFS2_SB(ocfs2_metadata_cache_get_super(et->et_ci));
        struct ocfs2_extent_block *eb;
@@ -1015,10 +1015,10 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
 
        count = 0;
        while (count < wanted) {
-               status = ocfs2_claim_metadata(osb,
-                                             handle,
+               status = ocfs2_claim_metadata(handle,
                                              meta_ac,
                                              wanted - count,
+                                             &suballoc_loc,
                                              &suballoc_bit_start,
                                              &num_got,
                                              &first_blkno);
@@ -1052,6 +1052,7 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
                        eb->h_fs_generation = cpu_to_le32(osb->fs_generation);
                        eb->h_suballoc_slot =
                                cpu_to_le16(meta_ac->ac_alloc_slot);
+                       eb->h_suballoc_loc = cpu_to_le64(suballoc_loc);
                        eb->h_suballoc_bit = cpu_to_le16(suballoc_bit_start);
                        eb->h_list.l_count =
                                cpu_to_le16(ocfs2_extent_recs_per_eb(osb->sb));
@@ -1061,11 +1062,7 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
 
                        /* We'll also be dirtied by the caller, so
                         * this isn't absolutely necessary. */
-                       status = ocfs2_journal_dirty(handle, bhs[i]);
-                       if (status < 0) {
-                               mlog_errno(status);
-                               goto bail;
-                       }
+                       ocfs2_journal_dirty(handle, bhs[i]);
                }
 
                count += num_got;
@@ -1129,8 +1126,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle,
                goto out;
        }
 
-       status = ocfs2_extend_trans(handle, path_num_items(path) +
-                                   handle->h_buffer_credits);
+       status = ocfs2_extend_trans(handle, path_num_items(path));
        if (status < 0) {
                mlog_errno(status);
                goto out;
@@ -1270,12 +1266,7 @@ static int ocfs2_add_branch(handle_t *handle,
                if (!eb_el->l_tree_depth)
                        new_last_eb_blk = le64_to_cpu(eb->h_blkno);
 
-               status = ocfs2_journal_dirty(handle, bh);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-
+               ocfs2_journal_dirty(handle, bh);
                next_blkno = le64_to_cpu(eb->h_blkno);
        }
 
@@ -1321,17 +1312,10 @@ static int ocfs2_add_branch(handle_t *handle,
        eb = (struct ocfs2_extent_block *) (*last_eb_bh)->b_data;
        eb->h_next_leaf_blk = cpu_to_le64(new_last_eb_blk);
 
-       status = ocfs2_journal_dirty(handle, *last_eb_bh);
-       if (status < 0)
-               mlog_errno(status);
-       status = ocfs2_journal_dirty(handle, et->et_root_bh);
-       if (status < 0)
-               mlog_errno(status);
-       if (eb_bh) {
-               status = ocfs2_journal_dirty(handle, eb_bh);
-               if (status < 0)
-                       mlog_errno(status);
-       }
+       ocfs2_journal_dirty(handle, *last_eb_bh);
+       ocfs2_journal_dirty(handle, et->et_root_bh);
+       if (eb_bh)
+               ocfs2_journal_dirty(handle, eb_bh);
 
        /*
         * Some callers want to track the rightmost leaf so pass it
@@ -1399,11 +1383,7 @@ static int ocfs2_shift_tree_depth(handle_t *handle,
        for (i = 0; i < le16_to_cpu(root_el->l_next_free_rec); i++)
                eb_el->l_recs[i] = root_el->l_recs[i];
 
-       status = ocfs2_journal_dirty(handle, new_eb_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
+       ocfs2_journal_dirty(handle, new_eb_bh);
 
        status = ocfs2_et_root_journal_access(handle, et,
                                              OCFS2_JOURNAL_ACCESS_WRITE);
@@ -1428,11 +1408,7 @@ static int ocfs2_shift_tree_depth(handle_t *handle,
        if (root_el->l_tree_depth == cpu_to_le16(1))
                ocfs2_et_set_last_eb_blk(et, le64_to_cpu(eb->h_blkno));
 
-       status = ocfs2_journal_dirty(handle, et->et_root_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
+       ocfs2_journal_dirty(handle, et->et_root_bh);
 
        *ret_new_eb_bh = new_eb_bh;
        new_eb_bh = NULL;
@@ -2064,7 +2040,7 @@ static void ocfs2_complete_edge_insert(handle_t *handle,
                                       struct ocfs2_path *right_path,
                                       int subtree_index)
 {
-       int ret, i, idx;
+       int i, idx;
        struct ocfs2_extent_list *el, *left_el, *right_el;
        struct ocfs2_extent_rec *left_rec, *right_rec;
        struct buffer_head *root_bh = left_path->p_node[subtree_index].bh;
@@ -2102,13 +2078,8 @@ static void ocfs2_complete_edge_insert(handle_t *handle,
                ocfs2_adjust_adjacent_records(left_rec, left_el, right_rec,
                                              right_el);
 
-               ret = ocfs2_journal_dirty(handle, left_path->p_node[i].bh);
-               if (ret)
-                       mlog_errno(ret);
-
-               ret = ocfs2_journal_dirty(handle, right_path->p_node[i].bh);
-               if (ret)
-                       mlog_errno(ret);
+               ocfs2_journal_dirty(handle, left_path->p_node[i].bh);
+               ocfs2_journal_dirty(handle, right_path->p_node[i].bh);
 
                /*
                 * Setup our list pointers now so that the current
@@ -2132,9 +2103,7 @@ static void ocfs2_complete_edge_insert(handle_t *handle,
 
        root_bh = left_path->p_node[subtree_index].bh;
 
-       ret = ocfs2_journal_dirty(handle, root_bh);
-       if (ret)
-               mlog_errno(ret);
+       ocfs2_journal_dirty(handle, root_bh);
 }
 
 static int ocfs2_rotate_subtree_right(handle_t *handle,
@@ -2207,11 +2176,7 @@ static int ocfs2_rotate_subtree_right(handle_t *handle,
 
        ocfs2_create_empty_extent(right_el);
 
-       ret = ocfs2_journal_dirty(handle, right_leaf_bh);
-       if (ret) {
-               mlog_errno(ret);
-               goto out;
-       }
+       ocfs2_journal_dirty(handle, right_leaf_bh);
 
        /* Do the copy now. */
        i = le16_to_cpu(left_el->l_next_free_rec) - 1;
@@ -2230,11 +2195,7 @@ static int ocfs2_rotate_subtree_right(handle_t *handle,
        memset(&left_el->l_recs[0], 0, sizeof(struct ocfs2_extent_rec));
        le16_add_cpu(&left_el->l_next_free_rec, 1);
 
-       ret = ocfs2_journal_dirty(handle, left_leaf_bh);
-       if (ret) {
-               mlog_errno(ret);
-               goto out;
-       }
+       ocfs2_journal_dirty(handle, left_leaf_bh);
 
        ocfs2_complete_edge_insert(handle, left_path, right_path,
                                   subtree_index);
@@ -2249,8 +2210,8 @@ out:
  *
  * Will return zero if the path passed in is already the leftmost path.
  */
-static int ocfs2_find_cpos_for_left_leaf(struct super_block *sb,
-                                        struct ocfs2_path *path, u32 *cpos)
+int ocfs2_find_cpos_for_left_leaf(struct super_block *sb,
+                                 struct ocfs2_path *path, u32 *cpos)
 {
        int i, j, ret = 0;
        u64 blkno;
@@ -2327,20 +2288,14 @@ static int ocfs2_extend_rotate_transaction(handle_t *handle, int subtree_depth,
                                           int op_credits,
                                           struct ocfs2_path *path)
 {
-       int ret;
+       int ret = 0;
        int credits = (path->p_tree_depth - subtree_depth) * 2 + 1 + op_credits;
 
-       if (handle->h_buffer_credits < credits) {
+       if (handle->h_buffer_credits < credits)
                ret = ocfs2_extend_trans(handle,
                                         credits - handle->h_buffer_credits);
-               if (ret)
-                       return ret;
 
-               if (unlikely(handle->h_buffer_credits < credits))
-                       return ocfs2_extend_trans(handle, credits);
-       }
-
-       return 0;
+       return ret;
 }
 
 /*
@@ -2584,8 +2539,7 @@ static int ocfs2_update_edge_lengths(handle_t *handle,
         * records for all the bh in the path.
         * So we have to allocate extra credits and access them.
         */
-       ret = ocfs2_extend_trans(handle,
-                                handle->h_buffer_credits + subtree_index);
+       ret = ocfs2_extend_trans(handle, subtree_index);
        if (ret) {
                mlog_errno(ret);
                goto out;
@@ -2823,12 +2777,8 @@ static int ocfs2_rotate_subtree_left(handle_t *handle,
                ocfs2_remove_empty_extent(right_leaf_el);
        }
 
-       ret = ocfs2_journal_dirty(handle, path_leaf_bh(left_path));
-       if (ret)
-               mlog_errno(ret);
-       ret = ocfs2_journal_dirty(handle, path_leaf_bh(right_path));
-       if (ret)
-               mlog_errno(ret);
+       ocfs2_journal_dirty(handle, path_leaf_bh(left_path));
+       ocfs2_journal_dirty(handle, path_leaf_bh(right_path));
 
        if (del_right_subtree) {
                ocfs2_unlink_subtree(handle, et, left_path, right_path,
@@ -2851,9 +2801,7 @@ static int ocfs2_rotate_subtree_left(handle_t *handle,
                if (right_has_empty)
                        ocfs2_remove_empty_extent(left_leaf_el);
 
-               ret = ocfs2_journal_dirty(handle, et_root_bh);
-               if (ret)
-                       mlog_errno(ret);
+               ocfs2_journal_dirty(handle, et_root_bh);
 
                *deleted = 1;
        } else
@@ -2962,10 +2910,7 @@ static int ocfs2_rotate_rightmost_leaf_left(handle_t *handle,
        }
 
        ocfs2_remove_empty_extent(el);
-
-       ret = ocfs2_journal_dirty(handle, bh);
-       if (ret)
-               mlog_errno(ret);
+       ocfs2_journal_dirty(handle, bh);
 
 out:
        return ret;
@@ -3506,15 +3451,9 @@ static int ocfs2_merge_rec_right(struct ocfs2_path *left_path,
 
        ocfs2_cleanup_merge(el, index);
 
-       ret = ocfs2_journal_dirty(handle, bh);
-       if (ret)
-               mlog_errno(ret);
-
+       ocfs2_journal_dirty(handle, bh);
        if (right_path) {
-               ret = ocfs2_journal_dirty(handle, path_leaf_bh(right_path));
-               if (ret)
-                       mlog_errno(ret);
-
+               ocfs2_journal_dirty(handle, path_leaf_bh(right_path));
                ocfs2_complete_edge_insert(handle, left_path, right_path,
                                           subtree_index);
        }
@@ -3683,14 +3622,9 @@ static int ocfs2_merge_rec_left(struct ocfs2_path *right_path,
 
        ocfs2_cleanup_merge(el, index);
 
-       ret = ocfs2_journal_dirty(handle, bh);
-       if (ret)
-               mlog_errno(ret);
-
+       ocfs2_journal_dirty(handle, bh);
        if (left_path) {
-               ret = ocfs2_journal_dirty(handle, path_leaf_bh(left_path));
-               if (ret)
-                       mlog_errno(ret);
+               ocfs2_journal_dirty(handle, path_leaf_bh(left_path));
 
                /*
                 * In the situation that the right_rec is empty and the extent
@@ -4016,10 +3950,7 @@ static void ocfs2_adjust_rightmost_records(handle_t *handle,
                le32_add_cpu(&rec->e_int_clusters,
                             -le32_to_cpu(rec->e_cpos));
 
-               ret = ocfs2_journal_dirty(handle, bh);
-               if (ret)
-                       mlog_errno(ret);
-
+               ocfs2_journal_dirty(handle, bh);
        }
 }
 
@@ -4203,17 +4134,13 @@ static int ocfs2_insert_path(handle_t *handle,
        struct buffer_head *leaf_bh = path_leaf_bh(right_path);
 
        if (left_path) {
-               int credits = handle->h_buffer_credits;
-
                /*
                 * There's a chance that left_path got passed back to
                 * us without being accounted for in the
                 * journal. Extend our transaction here to be sure we
                 * can change those blocks.
                 */
-               credits += left_path->p_tree_depth;
-
-               ret = ocfs2_extend_trans(handle, credits);
+               ret = ocfs2_extend_trans(handle, left_path->p_tree_depth);
                if (ret < 0) {
                        mlog_errno(ret);
                        goto out;
@@ -4251,17 +4178,13 @@ static int ocfs2_insert_path(handle_t *handle,
                 * dirty this for us.
                 */
                if (left_path)
-                       ret = ocfs2_journal_dirty(handle,
-                                                 path_leaf_bh(left_path));
-                       if (ret)
-                               mlog_errno(ret);
+                       ocfs2_journal_dirty(handle,
+                                           path_leaf_bh(left_path));
        } else
                ocfs2_insert_at_leaf(et, insert_rec, path_leaf_el(right_path),
                                     insert);
 
-       ret = ocfs2_journal_dirty(handle, leaf_bh);
-       if (ret)
-               mlog_errno(ret);
+       ocfs2_journal_dirty(handle, leaf_bh);
 
        if (left_path) {
                /*
@@ -4384,9 +4307,7 @@ out_update_clusters:
                ocfs2_et_update_clusters(et,
                                         le16_to_cpu(insert_rec->e_leaf_clusters));
 
-       ret = ocfs2_journal_dirty(handle, et->et_root_bh);
-       if (ret)
-               mlog_errno(ret);
+       ocfs2_journal_dirty(handle, et->et_root_bh);
 
 out:
        ocfs2_free_path(left_path);
@@ -4866,7 +4787,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
                goto leave;
        }
 
-       status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
+       status = __ocfs2_claim_clusters(handle, data_ac, 1,
                                        clusters_to_add, &bit_off, &num_bits);
        if (status < 0) {
                if (status != -ENOSPC)
@@ -4895,11 +4816,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
                goto leave;
        }
 
-       status = ocfs2_journal_dirty(handle, et->et_root_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto leave;
-       }
+       ocfs2_journal_dirty(handle, et->et_root_bh);
 
        clusters_to_add -= num_bits;
        *logical_offset += num_bits;
@@ -5309,7 +5226,7 @@ static int ocfs2_split_tree(handle_t *handle, struct ocfs2_extent_tree *et,
                            int index, u32 new_range,
                            struct ocfs2_alloc_context *meta_ac)
 {
-       int ret, depth, credits = handle->h_buffer_credits;
+       int ret, depth, credits;
        struct buffer_head *last_eb_bh = NULL;
        struct ocfs2_extent_block *eb;
        struct ocfs2_extent_list *rightmost_el, *el;
@@ -5340,8 +5257,8 @@ static int ocfs2_split_tree(handle_t *handle, struct ocfs2_extent_tree *et,
        } else
                rightmost_el = path_leaf_el(path);
 
-       credits += path->p_tree_depth +
-                  ocfs2_extend_meta_needed(et->et_root_el);
+       credits = path->p_tree_depth +
+                 ocfs2_extend_meta_needed(et->et_root_el);
        ret = ocfs2_extend_trans(handle, credits);
        if (ret) {
                mlog_errno(ret);
@@ -5671,19 +5588,97 @@ out:
        return ret;
 }
 
+/*
+ * ocfs2_reserve_blocks_for_rec_trunc() would look basically the
+ * same as ocfs2_lock_alloctors(), except for it accepts a blocks
+ * number to reserve some extra blocks, and it only handles meta
+ * data allocations.
+ *
+ * Currently, only ocfs2_remove_btree_range() uses it for truncating
+ * and punching holes.
+ */
+static int ocfs2_reserve_blocks_for_rec_trunc(struct inode *inode,
+                                             struct ocfs2_extent_tree *et,
+                                             u32 extents_to_split,
+                                             struct ocfs2_alloc_context **ac,
+                                             int extra_blocks)
+{
+       int ret = 0, num_free_extents;
+       unsigned int max_recs_needed = 2 * extents_to_split;
+       struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+       *ac = NULL;
+
+       num_free_extents = ocfs2_num_free_extents(osb, et);
+       if (num_free_extents < 0) {
+               ret = num_free_extents;
+               mlog_errno(ret);
+               goto out;
+       }
+
+       if (!num_free_extents ||
+           (ocfs2_sparse_alloc(osb) && num_free_extents < max_recs_needed))
+               extra_blocks += ocfs2_extend_meta_needed(et->et_root_el);
+
+       if (extra_blocks) {
+               ret = ocfs2_reserve_new_metadata_blocks(osb, extra_blocks, ac);
+               if (ret < 0) {
+                       if (ret != -ENOSPC)
+                               mlog_errno(ret);
+                       goto out;
+               }
+       }
+
+out:
+       if (ret) {
+               if (*ac) {
+                       ocfs2_free_alloc_context(*ac);
+                       *ac = NULL;
+               }
+       }
+
+       return ret;
+}
+
 int ocfs2_remove_btree_range(struct inode *inode,
                             struct ocfs2_extent_tree *et,
-                            u32 cpos, u32 phys_cpos, u32 len,
-                            struct ocfs2_cached_dealloc_ctxt *dealloc)
+                            u32 cpos, u32 phys_cpos, u32 len, int flags,
+                            struct ocfs2_cached_dealloc_ctxt *dealloc,
+                            u64 refcount_loc)
 {
-       int ret;
+       int ret, credits = 0, extra_blocks = 0;
        u64 phys_blkno = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos);
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        struct inode *tl_inode = osb->osb_tl_inode;
        handle_t *handle;
        struct ocfs2_alloc_context *meta_ac = NULL;
+       struct ocfs2_refcount_tree *ref_tree = NULL;
+
+       if ((flags & OCFS2_EXT_REFCOUNTED) && len) {
+               BUG_ON(!(OCFS2_I(inode)->ip_dyn_features &
+                        OCFS2_HAS_REFCOUNT_FL));
+
+               ret = ocfs2_lock_refcount_tree(osb, refcount_loc, 1,
+                                              &ref_tree, NULL);
+               if (ret) {
+                       mlog_errno(ret);
+                       goto out;
+               }
 
-       ret = ocfs2_lock_allocators(inode, et, 0, 1, NULL, &meta_ac);
+               ret = ocfs2_prepare_refcount_change_for_del(inode,
+                                                           refcount_loc,
+                                                           phys_blkno,
+                                                           len,
+                                                           &credits,
+                                                           &extra_blocks);
+               if (ret < 0) {
+                       mlog_errno(ret);
+                       goto out;
+               }
+       }
+
+       ret = ocfs2_reserve_blocks_for_rec_trunc(inode, et, 1, &meta_ac,
+                                                extra_blocks);
        if (ret) {
                mlog_errno(ret);
                return ret;
@@ -5699,7 +5694,8 @@ int ocfs2_remove_btree_range(struct inode *inode,
                }
        }
 
-       handle = ocfs2_start_trans(osb, ocfs2_remove_extent_credits(osb->sb));
+       handle = ocfs2_start_trans(osb,
+                       ocfs2_remove_extent_credits(osb->sb) + credits);
        if (IS_ERR(handle)) {
                ret = PTR_ERR(handle);
                mlog_errno(ret);
@@ -5724,15 +5720,22 @@ int ocfs2_remove_btree_range(struct inode *inode,
 
        ocfs2_et_update_clusters(et, -len);
 
-       ret = ocfs2_journal_dirty(handle, et->et_root_bh);
-       if (ret) {
-               mlog_errno(ret);
-               goto out_commit;
-       }
+       ocfs2_journal_dirty(handle, et->et_root_bh);
 
-       ret = ocfs2_truncate_log_append(osb, handle, phys_blkno, len);
-       if (ret)
-               mlog_errno(ret);
+       if (phys_blkno) {
+               if (flags & OCFS2_EXT_REFCOUNTED)
+                       ret = ocfs2_decrease_refcount(inode, handle,
+                                       ocfs2_blocks_to_clusters(osb->sb,
+                                                                phys_blkno),
+                                       len, meta_ac,
+                                       dealloc, 1);
+               else
+                       ret = ocfs2_truncate_log_append(osb, handle,
+                                                       phys_blkno, len);
+               if (ret)
+                       mlog_errno(ret);
+
+       }
 
 out_commit:
        ocfs2_commit_trans(osb, handle);
@@ -5742,6 +5745,9 @@ out:
        if (meta_ac)
                ocfs2_free_alloc_context(meta_ac);
 
+       if (ref_tree)
+               ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
+
        return ret;
 }
 
@@ -5850,11 +5856,7 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
        }
        tl->tl_recs[index].t_clusters = cpu_to_le32(num_clusters);
 
-       status = ocfs2_journal_dirty(handle, tl_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
+       ocfs2_journal_dirty(handle, tl_bh);
 
 bail:
        mlog_exit(status);
@@ -5893,11 +5895,7 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
 
                tl->tl_used = cpu_to_le16(i);
 
-               status = ocfs2_journal_dirty(handle, tl_bh);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
+               ocfs2_journal_dirty(handle, tl_bh);
 
                /* TODO: Perhaps we can calculate the bulk of the
                 * credits up front rather than extending like
@@ -6298,6 +6296,7 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
  */
 struct ocfs2_cached_block_free {
        struct ocfs2_cached_block_free          *free_next;
+       u64                                     free_bg;
        u64                                     free_blk;
        unsigned int                            free_bit;
 };
@@ -6344,8 +6343,11 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
        }
 
        while (head) {
-               bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
-                                                     head->free_bit);
+               if (head->free_bg)
+                       bg_blkno = head->free_bg;
+               else
+                       bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
+                                                             head->free_bit);
                mlog(0, "Free bit: (bit %u, blkno %llu)\n",
                     head->free_bit, (unsigned long long)head->free_blk);
 
@@ -6393,7 +6395,7 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
        int ret = 0;
        struct ocfs2_cached_block_free *item;
 
-       item = kmalloc(sizeof(*item), GFP_NOFS);
+       item = kzalloc(sizeof(*item), GFP_NOFS);
        if (item == NULL) {
                ret = -ENOMEM;
                mlog_errno(ret);
@@ -6533,8 +6535,8 @@ ocfs2_find_per_slot_free_list(int type,
 }
 
 int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
-                             int type, int slot, u64 blkno,
-                             unsigned int bit)
+                             int type, int slot, u64 suballoc,
+                             u64 blkno, unsigned int bit)
 {
        int ret;
        struct ocfs2_per_slot_free_list *fl;
@@ -6547,7 +6549,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
                goto out;
        }
 
-       item = kmalloc(sizeof(*item), GFP_NOFS);
+       item = kzalloc(sizeof(*item), GFP_NOFS);
        if (item == NULL) {
                ret = -ENOMEM;
                mlog_errno(ret);
@@ -6557,6 +6559,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
        mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n",
             type, slot, bit, (unsigned long long)blkno);
 
+       item->free_bg = suballoc;
        item->free_blk = blkno;
        item->free_bit = bit;
        item->free_next = fl->f_first;
@@ -6573,433 +6576,11 @@ static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt,
 {
        return ocfs2_cache_block_dealloc(ctxt, EXTENT_ALLOC_SYSTEM_INODE,
                                         le16_to_cpu(eb->h_suballoc_slot),
+                                        le64_to_cpu(eb->h_suballoc_loc),
                                         le64_to_cpu(eb->h_blkno),
                                         le16_to_cpu(eb->h_suballoc_bit));
 }
 
-/* This function will figure out whether the currently last extent
- * block will be deleted, and if it will, what the new last extent
- * block will be so we can update his h_next_leaf_blk field, as well
- * as the dinodes i_last_eb_blk */
-static int ocfs2_find_new_last_ext_blk(struct inode *inode,
-                                      unsigned int clusters_to_del,
-                                      struct ocfs2_path *path,
-                                      struct buffer_head **new_last_eb)
-{
-       int next_free, ret = 0;
-       u32 cpos;
-       struct ocfs2_extent_rec *rec;
-       struct ocfs2_extent_block *eb;
-       struct ocfs2_extent_list *el;
-       struct buffer_head *bh = NULL;
-
-       *new_last_eb = NULL;
-
-       /* we have no tree, so of course, no last_eb. */
-       if (!path->p_tree_depth)
-               goto out;
-
-       /* trunc to zero special case - this makes tree_depth = 0
-        * regardless of what it is.  */
-       if (OCFS2_I(inode)->ip_clusters == clusters_to_del)
-               goto out;
-
-       el = path_leaf_el(path);
-       BUG_ON(!el->l_next_free_rec);
-
-       /*
-        * Make sure that this extent list will actually be empty
-        * after we clear away the data. We can shortcut out if
-        * there's more than one non-empty extent in the
-        * list. Otherwise, a check of the remaining extent is
-        * necessary.
-        */
-       next_free = le16_to_cpu(el->l_next_free_rec);
-       rec = NULL;
-       if (ocfs2_is_empty_extent(&el->l_recs[0])) {
-               if (next_free > 2)
-                       goto out;
-
-               /* We may have a valid extent in index 1, check it. */
-               if (next_free == 2)
-                       rec = &el->l_recs[1];
-
-               /*
-                * Fall through - no more nonempty extents, so we want
-                * to delete this leaf.
-                */
-       } else {
-               if (next_free > 1)
-                       goto out;
-
-               rec = &el->l_recs[0];
-       }
-
-       if (rec) {
-               /*
-                * Check it we'll only be trimming off the end of this
-                * cluster.
-                */
-               if (le16_to_cpu(rec->e_leaf_clusters) > clusters_to_del)
-                       goto out;
-       }
-
-       ret = ocfs2_find_cpos_for_left_leaf(inode->i_sb, path, &cpos);
-       if (ret) {
-               mlog_errno(ret);
-               goto out;
-       }
-
-       ret = ocfs2_find_leaf(INODE_CACHE(inode), path_root_el(path), cpos, &bh);
-       if (ret) {
-               mlog_errno(ret);
-               goto out;
-       }
-
-       eb = (struct ocfs2_extent_block *) bh->b_data;
-       el = &eb->h_list;
-
-       /* ocfs2_find_leaf() gets the eb from ocfs2_read_extent_block().
-        * Any corruption is a code bug. */
-       BUG_ON(!OCFS2_IS_VALID_EXTENT_BLOCK(eb));
-
-       *new_last_eb = bh;
-       get_bh(*new_last_eb);
-       mlog(0, "returning block %llu, (cpos: %u)\n",
-            (unsigned long long)le64_to_cpu(eb->h_blkno), cpos);
-out:
-       brelse(bh);
-
-       return ret;
-}
-
-/*
- * Trim some clusters off the rightmost edge of a tree. Only called
- * during truncate.
- *
- * The caller needs to:
- *   - start journaling of each path component.
- *   - compute and fully set up any new last ext block
- */
-static int ocfs2_trim_tree(struct inode *inode, struct ocfs2_path *path,
-                          handle_t *handle, struct ocfs2_truncate_context *tc,
-                          u32 clusters_to_del, u64 *delete_start, u8 *flags)
-{
-       int ret, i, index = path->p_tree_depth;
-       u32 new_edge = 0;
-       u64 deleted_eb = 0;
-       struct buffer_head *bh;
-       struct ocfs2_extent_list *el;
-       struct ocfs2_extent_rec *rec;
-
-       *delete_start = 0;
-       *flags = 0;
-
-       while (index >= 0) {
-               bh = path->p_node[index].bh;
-               el = path->p_node[index].el;
-
-               mlog(0, "traveling tree (index = %d, block = %llu)\n",
-                    index,  (unsigned long long)bh->b_blocknr);
-
-               BUG_ON(le16_to_cpu(el->l_next_free_rec) == 0);
-
-               if (index !=
-                   (path->p_tree_depth - le16_to_cpu(el->l_tree_depth))) {
-                       ocfs2_error(inode->i_sb,
-                                   "Inode %lu has invalid ext. block %llu",
-                                   inode->i_ino,
-                                   (unsigned long long)bh->b_blocknr);
-                       ret = -EROFS;
-                       goto out;
-               }
-
-find_tail_record:
-               i = le16_to_cpu(el->l_next_free_rec) - 1;
-               rec = &el->l_recs[i];
-
-               mlog(0, "Extent list before: record %d: (%u, %u, %llu), "
-                    "next = %u\n", i, le32_to_cpu(rec->e_cpos),
-                    ocfs2_rec_clusters(el, rec),
-                    (unsigned long long)le64_to_cpu(rec->e_blkno),
-                    le16_to_cpu(el->l_next_free_rec));
-
-               BUG_ON(ocfs2_rec_clusters(el, rec) < clusters_to_del);
-
-               if (le16_to_cpu(el->l_tree_depth) == 0) {
-                       /*
-                        * If the leaf block contains a single empty
-                        * extent and no records, we can just remove
-                        * the block.
-                        */
-                       if (i == 0 && ocfs2_is_empty_extent(rec)) {
-                               memset(rec, 0,
-                                      sizeof(struct ocfs2_extent_rec));
-                               el->l_next_free_rec = cpu_to_le16(0);
-
-                               goto delete;
-                       }
-
-                       /*
-                        * Remove any empty extents by shifting things
-                        * left. That should make life much easier on
-                        * the code below. This condition is rare
-                        * enough that we shouldn't see a performance
-                        * hit.
-                        */
-                       if (ocfs2_is_empty_extent(&el->l_recs[0])) {
-                               le16_add_cpu(&el->l_next_free_rec, -1);
-
-                               for(i = 0;
-                                   i < le16_to_cpu(el->l_next_free_rec); i++)
-                                       el->l_recs[i] = el->l_recs[i + 1];
-
-                               memset(&el->l_recs[i], 0,
-                                      sizeof(struct ocfs2_extent_rec));
-
-                               /*
-                                * We've modified our extent list. The
-                                * simplest way to handle this change
-                                * is to being the search from the
-                                * start again.
-                                */
-                               goto find_tail_record;
-                       }
-
-                       le16_add_cpu(&rec->e_leaf_clusters, -clusters_to_del);
-
-                       /*
-                        * We'll use "new_edge" on our way back up the
-                        * tree to know what our rightmost cpos is.
-                        */
-                       new_edge = le16_to_cpu(rec->e_leaf_clusters);
-                       new_edge += le32_to_cpu(rec->e_cpos);
-
-                       /*
-                        * The caller will use this to delete data blocks.
-                        */
-                       *delete_start = le64_to_cpu(rec->e_blkno)
-                               + ocfs2_clusters_to_blocks(inode->i_sb,
-                                       le16_to_cpu(rec->e_leaf_clusters));
-                       *flags = rec->e_flags;
-
-                       /*
-                        * If it's now empty, remove this record.
-                        */
-                       if (le16_to_cpu(rec->e_leaf_clusters) == 0) {
-                               memset(rec, 0,
-                                      sizeof(struct ocfs2_extent_rec));
-                               le16_add_cpu(&el->l_next_free_rec, -1);
-                       }
-               } else {
-                       if (le64_to_cpu(rec->e_blkno) == deleted_eb) {
-                               memset(rec, 0,
-                                      sizeof(struct ocfs2_extent_rec));
-                               le16_add_cpu(&el->l_next_free_rec, -1);
-
-                               goto delete;
-                       }
-
-                       /* Can this actually happen? */
-                       if (le16_to_cpu(el->l_next_free_rec) == 0)
-                               goto delete;
-
-                       /*
-                        * We never actually deleted any clusters
-                        * because our leaf was empty. There's no
-                        * reason to adjust the rightmost edge then.
-                        */
-                       if (new_edge == 0)
-                               goto delete;
-
-                       rec->e_int_clusters = cpu_to_le32(new_edge);
-                       le32_add_cpu(&rec->e_int_clusters,
-                                    -le32_to_cpu(rec->e_cpos));
-
-                        /*
-                         * A deleted child record should have been
-                         * caught above.
-                         */
-                        BUG_ON(le32_to_cpu(rec->e_int_clusters) == 0);
-               }
-
-delete:
-               ret = ocfs2_journal_dirty(handle, bh);
-               if (ret) {
-                       mlog_errno(ret);
-                       goto out;
-               }
-
-               mlog(0, "extent list container %llu, after: record %d: "
-                    "(%u, %u, %llu), next = %u.\n",
-                    (unsigned long long)bh->b_blocknr, i,
-                    le32_to_cpu(rec->e_cpos), ocfs2_rec_clusters(el, rec),
-                    (unsigned long long)le64_to_cpu(rec->e_blkno),
-                    le16_to_cpu(el->l_next_free_rec));
-
-               /*
-                * We must be careful to only attempt delete of an
-                * extent block (and not the root inode block).
-                */
-               if (index > 0 && le16_to_cpu(el->l_next_free_rec) == 0) {
-                       struct ocfs2_extent_block *eb =
-                               (struct ocfs2_extent_block *)bh->b_data;
-
-                       /*
-                        * Save this for use when processing the
-                        * parent block.
-                        */
-                       deleted_eb = le64_to_cpu(eb->h_blkno);
-
-                       mlog(0, "deleting this extent block.\n");
-
-                       ocfs2_remove_from_cache(INODE_CACHE(inode), bh);
-
-                       BUG_ON(ocfs2_rec_clusters(el, &el->l_recs[0]));
-                       BUG_ON(le32_to_cpu(el->l_recs[0].e_cpos));
-                       BUG_ON(le64_to_cpu(el->l_recs[0].e_blkno));
-
-                       ret = ocfs2_cache_extent_block_free(&tc->tc_dealloc, eb);
-                       /* An error here is not fatal. */
-                       if (ret < 0)
-                               mlog_errno(ret);
-               } else {
-                       deleted_eb = 0;
-               }
-
-               index--;
-       }
-
-       ret = 0;
-out:
-       return ret;
-}
-
-static int ocfs2_do_truncate(struct ocfs2_super *osb,
-                            unsigned int clusters_to_del,
-                            struct inode *inode,
-                            struct buffer_head *fe_bh,
-                            handle_t *handle,
-                            struct ocfs2_truncate_context *tc,
-                            struct ocfs2_path *path,
-                            struct ocfs2_alloc_context *meta_ac)
-{
-       int status;
-       struct ocfs2_dinode *fe;
-       struct ocfs2_extent_block *last_eb = NULL;
-       struct ocfs2_extent_list *el;
-       struct buffer_head *last_eb_bh = NULL;
-       u64 delete_blk = 0;
-       u8 rec_flags;
-
-       fe = (struct ocfs2_dinode *) fe_bh->b_data;
-
-       status = ocfs2_find_new_last_ext_blk(inode, clusters_to_del,
-                                            path, &last_eb_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
-
-       /*
-        * Each component will be touched, so we might as well journal
-        * here to avoid having to handle errors later.
-        */
-       status = ocfs2_journal_access_path(INODE_CACHE(inode), handle, path);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
-
-       if (last_eb_bh) {
-               status = ocfs2_journal_access_eb(handle, INODE_CACHE(inode), last_eb_bh,
-                                                OCFS2_JOURNAL_ACCESS_WRITE);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-
-               last_eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
-       }
-
-       el = &(fe->id2.i_list);
-
-       /*
-        * Lower levels depend on this never happening, but it's best
-        * to check it up here before changing the tree.
-        */
-       if (el->l_tree_depth && el->l_recs[0].e_int_clusters == 0) {
-               ocfs2_error(inode->i_sb,
-                           "Inode %lu has an empty extent record, depth %u\n",
-                           inode->i_ino, le16_to_cpu(el->l_tree_depth));
-               status = -EROFS;
-               goto bail;
-       }
-
-       dquot_free_space_nodirty(inode,
-                       ocfs2_clusters_to_bytes(osb->sb, clusters_to_del));
-       spin_lock(&OCFS2_I(inode)->ip_lock);
-       OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) -
-                                     clusters_to_del;
-       spin_unlock(&OCFS2_I(inode)->ip_lock);
-       le32_add_cpu(&fe->i_clusters, -clusters_to_del);
-       inode->i_blocks = ocfs2_inode_sector_count(inode);
-
-       status = ocfs2_trim_tree(inode, path, handle, tc,
-                                clusters_to_del, &delete_blk, &rec_flags);
-       if (status) {
-               mlog_errno(status);
-               goto bail;
-       }
-
-       if (le32_to_cpu(fe->i_clusters) == 0) {
-               /* trunc to zero is a special case. */
-               el->l_tree_depth = 0;
-               fe->i_last_eb_blk = 0;
-       } else if (last_eb)
-               fe->i_last_eb_blk = last_eb->h_blkno;
-
-       status = ocfs2_journal_dirty(handle, fe_bh);
-       if (status < 0) {
-               mlog_errno(status);
-               goto bail;
-       }
-
-       if (last_eb) {
-               /* If there will be a new last extent block, then by
-                * definition, there cannot be any leaves to the right of
-                * him. */
-               last_eb->h_next_leaf_blk = 0;
-               status = ocfs2_journal_dirty(handle, last_eb_bh);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-       }
-
-       if (delete_blk) {
-               if (rec_flags & OCFS2_EXT_REFCOUNTED)
-                       status = ocfs2_decrease_refcount(inode, handle,
-                                       ocfs2_blocks_to_clusters(osb->sb,
-                                                                delete_blk),
-                                       clusters_to_del, meta_ac,
-                                       &tc->tc_dealloc, 1);
-               else
-                       status = ocfs2_truncate_log_append(osb, handle,
-                                                          delete_blk,
-                                                          clusters_to_del);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-       }
-       status = 0;
-bail:
-       brelse(last_eb_bh);
-       mlog_exit(status);
-       return status;
-}
-
 static int ocfs2_zero_func(handle_t *handle, struct buffer_head *bh)
 {
        set_buffer_uptodate(bh);
@@ -7307,7 +6888,9 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
                        goto out_commit;
                did_quota = 1;
 
-               ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off,
+               data_ac->ac_resv = &OCFS2_I(inode)->ip_la_data_resv;
+
+               ret = ocfs2_claim_clusters(handle, data_ac, 1, &bit_off,
                                           &num);
                if (ret) {
                        mlog_errno(ret);
@@ -7406,26 +6989,29 @@ out:
  */
 int ocfs2_commit_truncate(struct ocfs2_super *osb,
                          struct inode *inode,
-                         struct buffer_head *fe_bh,
-                         struct ocfs2_truncate_context *tc)
+                         struct buffer_head *di_bh)
 {
-       int status, i, credits, tl_sem = 0;
-       u32 clusters_to_del, new_highest_cpos, range;
+       int status = 0, i, flags = 0;
+       u32 new_highest_cpos, range, trunc_cpos, trunc_len, phys_cpos, coff;
        u64 blkno = 0;
        struct ocfs2_extent_list *el;
-       handle_t *handle = NULL;
-       struct inode *tl_inode = osb->osb_tl_inode;
+       struct ocfs2_extent_rec *rec;
        struct ocfs2_path *path = NULL;
-       struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data;
-       struct ocfs2_alloc_context *meta_ac = NULL;
-       struct ocfs2_refcount_tree *ref_tree = NULL;
+       struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
+       struct ocfs2_extent_list *root_el = &(di->id2.i_list);
+       u64 refcount_loc = le64_to_cpu(di->i_refcount_loc);
+       struct ocfs2_extent_tree et;
+       struct ocfs2_cached_dealloc_ctxt dealloc;
 
        mlog_entry_void();
 
+       ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
+       ocfs2_init_dealloc_ctxt(&dealloc);
+
        new_highest_cpos = ocfs2_clusters_for_bytes(osb->sb,
                                                     i_size_read(inode));
 
-       path = ocfs2_new_path(fe_bh, &di->id2.i_list,
+       path = ocfs2_new_path(di_bh, &di->id2.i_list,
                              ocfs2_journal_access_di);
        if (!path) {
                status = -ENOMEM;
@@ -7444,8 +7030,6 @@ start:
                goto bail;
        }
 
-       credits = 0;
-
        /*
         * Truncate always works against the rightmost tree branch.
         */
@@ -7480,101 +7064,62 @@ start:
        }
 
        i = le16_to_cpu(el->l_next_free_rec) - 1;
-       range = le32_to_cpu(el->l_recs[i].e_cpos) +
-               ocfs2_rec_clusters(el, &el->l_recs[i]);
-       if (i == 0 && ocfs2_is_empty_extent(&el->l_recs[i])) {
-               clusters_to_del = 0;
-       } else if (le32_to_cpu(el->l_recs[i].e_cpos) >= new_highest_cpos) {
-               clusters_to_del = ocfs2_rec_clusters(el, &el->l_recs[i]);
-               blkno = le64_to_cpu(el->l_recs[i].e_blkno);
+       rec = &el->l_recs[i];
+       flags = rec->e_flags;
+       range = le32_to_cpu(rec->e_cpos) + ocfs2_rec_clusters(el, rec);
+
+       if (i == 0 && ocfs2_is_empty_extent(rec)) {
+               /*
+                * Lower levels depend on this never happening, but it's best
+                * to check it up here before changing the tree.
+               */
+               if (root_el->l_tree_depth && rec->e_int_clusters == 0) {
+                       ocfs2_error(inode->i_sb, "Inode %lu has an empty "
+                                   "extent record, depth %u\n", inode->i_ino,
+                                   le16_to_cpu(root_el->l_tree_depth));
+                       status = -EROFS;
+                       goto bail;
+               }
+               trunc_cpos = le32_to_cpu(rec->e_cpos);
+               trunc_len = 0;
+               blkno = 0;
+       } else if (le32_to_cpu(rec->e_cpos) >= new_highest_cpos) {
+               /*
+                * Truncate entire record.
+                */
+               trunc_cpos = le32_to_cpu(rec->e_cpos);
+               trunc_len = ocfs2_rec_clusters(el, rec);
+               blkno = le64_to_cpu(rec->e_blkno);
        } else if (range > new_highest_cpos) {
-               clusters_to_del = (ocfs2_rec_clusters(el, &el->l_recs[i]) +
-                                  le32_to_cpu(el->l_recs[i].e_cpos)) -
-                                 new_highest_cpos;
-               blkno = le64_to_cpu(el->l_recs[i].e_blkno) +
-                       ocfs2_clusters_to_blocks(inode->i_sb,
-                               ocfs2_rec_clusters(el, &el->l_recs[i]) -
-                               clusters_to_del);
+               /*
+                * Partial truncate. it also should be
+                * the last truncate we're doing.
+                */
+               trunc_cpos = new_highest_cpos;
+               trunc_len = range - new_highest_cpos;
+               coff = new_highest_cpos - le32_to_cpu(rec->e_cpos);
+               blkno = le64_to_cpu(rec->e_blkno) +
+                               ocfs2_clusters_to_blocks(inode->i_sb, coff);
        } else {
+               /*
+                * Truncate completed, leave happily.
+                */
                status = 0;
                goto bail;
        }
 
-       mlog(0, "clusters_to_del = %u in this pass, tail blk=%llu\n",
-            clusters_to_del, (unsigned long long)path_leaf_bh(path)->b_blocknr);
-
-       if (el->l_recs[i].e_flags & OCFS2_EXT_REFCOUNTED && clusters_to_del) {
-               BUG_ON(!(OCFS2_I(inode)->ip_dyn_features &
-                        OCFS2_HAS_REFCOUNT_FL));
-
-               status = ocfs2_lock_refcount_tree(osb,
-                                               le64_to_cpu(di->i_refcount_loc),
-                                               1, &ref_tree, NULL);
-               if (status) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-
-               status = ocfs2_prepare_refcount_change_for_del(inode, fe_bh,
-                                                              blkno,
-                                                              clusters_to_del,
-                                                              &credits,
-                                                              &meta_ac);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-       }
-
-       mutex_lock(&tl_inode->i_mutex);
-       tl_sem = 1;
-       /* ocfs2_truncate_log_needs_flush guarantees us at least one
-        * record is free for use. If there isn't any, we flush to get
-        * an empty truncate log.  */
-       if (ocfs2_truncate_log_needs_flush(osb)) {
-               status = __ocfs2_flush_truncate_log(osb);
-               if (status < 0) {
-                       mlog_errno(status);
-                       goto bail;
-               }
-       }
+       phys_cpos = ocfs2_blocks_to_clusters(inode->i_sb, blkno);
 
-       credits += ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del,
-                                               (struct ocfs2_dinode *)fe_bh->b_data,
-                                               el);
-       handle = ocfs2_start_trans(osb, credits);
-       if (IS_ERR(handle)) {
-               status = PTR_ERR(handle);
-               handle = NULL;
-               mlog_errno(status);
-               goto bail;
-       }
-
-       status = ocfs2_do_truncate(osb, clusters_to_del, inode, fe_bh, handle,
-                                  tc, path, meta_ac);
+       status = ocfs2_remove_btree_range(inode, &et, trunc_cpos,
+                                         phys_cpos, trunc_len, flags, &dealloc,
+                                         refcount_loc);
        if (status < 0) {
                mlog_errno(status);
                goto bail;
        }
 
-       mutex_unlock(&tl_inode->i_mutex);
-       tl_sem = 0;
-
-       ocfs2_commit_trans(osb, handle);
-       handle = NULL;
-
        ocfs2_reinit_path(path, 1);
 
-       if (meta_ac) {
-               ocfs2_free_alloc_context(meta_ac);
-               meta_ac = NULL;
-       }
-
-       if (ref_tree) {
-               ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
-               ref_tree = NULL;
-       }
-
        /*
         * The check above will catch the case where we've truncated
         * away all allocation.
@@ -7585,25 +7130,10 @@ bail:
 
        ocfs2_schedule_truncate_log_flush(osb, 1);
 
-       if (tl_sem)
-               mutex_unlock(&tl_inode->i_mutex);
-
-       if (handle)
-               ocfs2_commit_trans(osb, handle);
-
-       if (meta_ac)
-               ocfs2_free_alloc_context(meta_ac);
-
-       if (ref_tree)
-               ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
-
-       ocfs2_run_deallocs(osb, &tc->tc_dealloc);
+       ocfs2_run_deallocs(osb, &dealloc);
 
        ocfs2_free_path(path);
 
-       /* This will drop the ext_alloc cluster lock for us */
-       ocfs2_free_truncate_context(tc);
-
        mlog_exit(status);
        return status;
 }