]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - fs/btrfs/extent-tree.c
btrfs: remove stale comment from btrfs_free_extent()
[thirdparty/linux.git] / fs / btrfs / extent-tree.c
index fc313fce5bbdc7d9e5e2a7994b7e3ba0ab12105a..89e3799d39e0bc0947fe279e566e46a8b4024ae7 100644 (file)
@@ -49,7 +49,7 @@
 static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                               struct btrfs_delayed_ref_node *node, u64 parent,
                               u64 root_objectid, u64 owner_objectid,
-                              u64 owner_offset, int refs_to_drop,
+                              u64 owner_offset,
                               struct btrfs_delayed_extent_op *extra_op);
 static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op,
                                    struct extent_buffer *leaf,
@@ -399,11 +399,11 @@ u64 hash_extent_data_ref(u64 root_objectid, u64 owner, u64 offset)
        __le64 lenum;
 
        lenum = cpu_to_le64(root_objectid);
-       high_crc = btrfs_crc32c(high_crc, &lenum, sizeof(lenum));
+       high_crc = crc32c(high_crc, &lenum, sizeof(lenum));
        lenum = cpu_to_le64(owner);
-       low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum));
+       low_crc = crc32c(low_crc, &lenum, sizeof(lenum));
        lenum = cpu_to_le64(offset);
-       low_crc = btrfs_crc32c(low_crc, &lenum, sizeof(lenum));
+       low_crc = crc32c(low_crc, &lenum, sizeof(lenum));
 
        return ((u64)high_crc << 31) ^ (u64)low_crc;
 }
@@ -575,7 +575,7 @@ static noinline int insert_extent_data_ref(struct btrfs_trans_handle *trans,
                        btrfs_set_extent_data_ref_count(leaf, ref, num_refs);
                }
        }
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
        ret = 0;
 fail:
        btrfs_release_path(path);
@@ -623,7 +623,7 @@ static noinline int remove_extent_data_ref(struct btrfs_trans_handle *trans,
                        btrfs_set_extent_data_ref_count(leaf, ref1, num_refs);
                else if (key.type == BTRFS_SHARED_DATA_REF_KEY)
                        btrfs_set_shared_data_ref_count(leaf, ref2, num_refs);
-               btrfs_mark_buffer_dirty(leaf);
+               btrfs_mark_buffer_dirty(trans, leaf);
        }
        return ret;
 }
@@ -789,7 +789,6 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
        int type;
        int want;
        int ret;
-       int err = 0;
        bool skinny_metadata = btrfs_fs_incompat(fs_info, SKINNY_METADATA);
        int needed;
 
@@ -816,10 +815,8 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
 
 again:
        ret = btrfs_search_slot(trans, root, &key, path, extra_size, 1);
-       if (ret < 0) {
-               err = ret;
+       if (ret < 0)
                goto out;
-       }
 
        /*
         * We may be a newly converted file system which still has the old fat
@@ -846,7 +843,7 @@ again:
        }
 
        if (ret && !insert) {
-               err = -ENOENT;
+               ret = -ENOENT;
                goto out;
        } else if (WARN_ON(ret)) {
                btrfs_print_leaf(path->nodes[0]);
@@ -854,18 +851,18 @@ again:
 "extent item not found for insert, bytenr %llu num_bytes %llu parent %llu root_objectid %llu owner %llu offset %llu",
                          bytenr, num_bytes, parent, root_objectid, owner,
                          offset);
-               err = -EIO;
+               ret = -EUCLEAN;
                goto out;
        }
 
        leaf = path->nodes[0];
        item_size = btrfs_item_size(leaf, path->slots[0]);
        if (unlikely(item_size < sizeof(*ei))) {
-               err = -EUCLEAN;
+               ret = -EUCLEAN;
                btrfs_err(fs_info,
                          "unexpected extent item size, has %llu expect >= %zu",
                          item_size, sizeof(*ei));
-               btrfs_abort_transaction(trans, err);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
@@ -885,22 +882,12 @@ again:
        else
                needed = BTRFS_REF_TYPE_BLOCK;
 
-       err = -ENOENT;
-       while (1) {
-               if (ptr >= end) {
-                       if (ptr > end) {
-                               err = -EUCLEAN;
-                               btrfs_print_leaf(path->nodes[0]);
-                               btrfs_crit(fs_info,
-"overrun extent record at slot %d while looking for inline extent for root %llu owner %llu offset %llu parent %llu",
-                                       path->slots[0], root_objectid, owner, offset, parent);
-                       }
-                       break;
-               }
+       ret = -ENOENT;
+       while (ptr < end) {
                iref = (struct btrfs_extent_inline_ref *)ptr;
                type = btrfs_get_extent_inline_ref_type(leaf, iref, needed);
                if (type == BTRFS_REF_TYPE_INVALID) {
-                       err = -EUCLEAN;
+                       ret = -EUCLEAN;
                        goto out;
                }
 
@@ -916,7 +903,7 @@ again:
                        dref = (struct btrfs_extent_data_ref *)(&iref->offset);
                        if (match_extent_data_ref(leaf, dref, root_objectid,
                                                  owner, offset)) {
-                               err = 0;
+                               ret = 0;
                                break;
                        }
                        if (hash_extent_data_ref_item(leaf, dref) <
@@ -927,14 +914,14 @@ again:
                        ref_offset = btrfs_extent_inline_ref_offset(leaf, iref);
                        if (parent > 0) {
                                if (parent == ref_offset) {
-                                       err = 0;
+                                       ret = 0;
                                        break;
                                }
                                if (ref_offset < parent)
                                        break;
                        } else {
                                if (root_objectid == ref_offset) {
-                                       err = 0;
+                                       ret = 0;
                                        break;
                                }
                                if (ref_offset < root_objectid)
@@ -943,10 +930,20 @@ again:
                }
                ptr += btrfs_extent_inline_ref_size(type);
        }
-       if (err == -ENOENT && insert) {
+
+       if (unlikely(ptr > end)) {
+               ret = -EUCLEAN;
+               btrfs_print_leaf(path->nodes[0]);
+               btrfs_crit(fs_info,
+"overrun extent record at slot %d while looking for inline extent for root %llu owner %llu offset %llu parent %llu",
+                          path->slots[0], root_objectid, owner, offset, parent);
+               goto out;
+       }
+
+       if (ret == -ENOENT && insert) {
                if (item_size + extra_size >=
                    BTRFS_MAX_EXTENT_ITEM_SIZE(root)) {
-                       err = -EAGAIN;
+                       ret = -EAGAIN;
                        goto out;
                }
                /*
@@ -958,7 +955,7 @@ again:
                if (find_next_key(path, 0, &key) == 0 &&
                    key.objectid == bytenr &&
                    key.type < BTRFS_BLOCK_GROUP_ITEM_KEY) {
-                       err = -EAGAIN;
+                       ret = -EAGAIN;
                        goto out;
                }
        }
@@ -969,14 +966,14 @@ out:
                path->search_for_extension = 0;
                btrfs_unlock_up_safe(path, 1);
        }
-       return err;
+       return ret;
 }
 
 /*
  * helper to add new inline back ref
  */
 static noinline_for_stack
-void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
+void setup_inline_extent_backref(struct btrfs_trans_handle *trans,
                                 struct btrfs_path *path,
                                 struct btrfs_extent_inline_ref *iref,
                                 u64 parent, u64 root_objectid,
@@ -999,7 +996,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
        type = extent_ref_type(parent, owner);
        size = btrfs_extent_inline_ref_size(type);
 
-       btrfs_extend_item(path, size);
+       btrfs_extend_item(trans, path, size);
 
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
        refs = btrfs_extent_refs(leaf, ei);
@@ -1033,7 +1030,7 @@ void setup_inline_extent_backref(struct btrfs_fs_info *fs_info,
        } else {
                btrfs_set_extent_inline_ref_offset(leaf, iref, root_objectid);
        }
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
 }
 
 static int lookup_extent_backref(struct btrfs_trans_handle *trans,
@@ -1066,7 +1063,9 @@ static int lookup_extent_backref(struct btrfs_trans_handle *trans,
 /*
  * helper to update/remove inline back ref
  */
-static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *path,
+static noinline_for_stack int update_inline_extent_backref(
+                                 struct btrfs_trans_handle *trans,
+                                 struct btrfs_path *path,
                                  struct btrfs_extent_inline_ref *iref,
                                  int refs_to_mod,
                                  struct btrfs_delayed_extent_op *extent_op)
@@ -1174,9 +1173,9 @@ static noinline_for_stack int update_inline_extent_backref(struct btrfs_path *pa
                        memmove_extent_buffer(leaf, ptr, ptr + size,
                                              end - ptr - size);
                item_size -= size;
-               btrfs_truncate_item(path, item_size, 1);
+               btrfs_truncate_item(trans, path, item_size, 1);
        }
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
        return 0;
 }
 
@@ -1206,9 +1205,10 @@ int insert_inline_extent_backref(struct btrfs_trans_handle *trans,
                                   bytenr, num_bytes, root_objectid, path->slots[0]);
                        return -EUCLEAN;
                }
-               ret = update_inline_extent_backref(path, iref, refs_to_add, extent_op);
+               ret = update_inline_extent_backref(trans, path, iref,
+                                                  refs_to_add, extent_op);
        } else if (ret == -ENOENT) {
-               setup_inline_extent_backref(trans->fs_info, path, iref, parent,
+               setup_inline_extent_backref(trans, path, iref, parent,
                                            root_objectid, owner, offset,
                                            refs_to_add, extent_op);
                ret = 0;
@@ -1226,7 +1226,8 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
 
        BUG_ON(!is_data && refs_to_drop != 1);
        if (iref)
-               ret = update_inline_extent_backref(path, iref, -refs_to_drop, NULL);
+               ret = update_inline_extent_backref(trans, path, iref,
+                                                  -refs_to_drop, NULL);
        else if (is_data)
                ret = remove_extent_data_ref(trans, root, path, refs_to_drop);
        else
@@ -1435,7 +1436,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 }
 
 /*
- * __btrfs_inc_extent_ref - insert backreference for a given extent
+ * Insert backreference for a given extent.
  *
  * The counterpart is in __btrfs_free_extent(), with examples and more details
  * how it works.
@@ -1465,8 +1466,6 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
  *                 always passed as 0. For data extents it is the fileoffset
  *                 this extent belongs to.
  *
- * @refs_to_add     Number of references to add
- *
  * @extent_op       Pointer to a structure, holding information necessary when
  *                  updating a tree block's flags
  *
@@ -1474,7 +1473,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                                  struct btrfs_delayed_ref_node *node,
                                  u64 parent, u64 root_objectid,
-                                 u64 owner, u64 offset, int refs_to_add,
+                                 u64 owner, u64 offset,
                                  struct btrfs_delayed_extent_op *extent_op)
 {
        struct btrfs_path *path;
@@ -1484,6 +1483,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
        u64 bytenr = node->bytenr;
        u64 num_bytes = node->num_bytes;
        u64 refs;
+       int refs_to_add = node->ref_mod;
        int ret;
 
        path = btrfs_alloc_path();
@@ -1510,7 +1510,7 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
        if (extent_op)
                __run_delayed_extent_op(extent_op, leaf, item);
 
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
        btrfs_release_path(path);
 
        /* now insert the actual backref */
@@ -1536,38 +1536,37 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
 {
        int ret = 0;
        struct btrfs_delayed_data_ref *ref;
-       struct btrfs_key ins;
        u64 parent = 0;
-       u64 ref_root = 0;
        u64 flags = 0;
 
-       ins.objectid = node->bytenr;
-       ins.offset = node->num_bytes;
-       ins.type = BTRFS_EXTENT_ITEM_KEY;
-
        ref = btrfs_delayed_node_to_data_ref(node);
        trace_run_delayed_data_ref(trans->fs_info, node, ref, node->action);
 
        if (node->type == BTRFS_SHARED_DATA_REF_KEY)
                parent = ref->parent;
-       ref_root = ref->root;
 
        if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
+               struct btrfs_key key;
+
                if (extent_op)
                        flags |= extent_op->flags_to_set;
-               ret = alloc_reserved_file_extent(trans, parent, ref_root,
+
+               key.objectid = node->bytenr;
+               key.type = BTRFS_EXTENT_ITEM_KEY;
+               key.offset = node->num_bytes;
+
+               ret = alloc_reserved_file_extent(trans, parent, ref->root,
                                                 flags, ref->objectid,
-                                                ref->offset, &ins,
+                                                ref->offset, &key,
                                                 node->ref_mod);
        } else if (node->action == BTRFS_ADD_DELAYED_REF) {
-               ret = __btrfs_inc_extent_ref(trans, node, parent, ref_root,
+               ret = __btrfs_inc_extent_ref(trans, node, parent, ref->root,
                                             ref->objectid, ref->offset,
-                                            node->ref_mod, extent_op);
+                                            extent_op);
        } else if (node->action == BTRFS_DROP_DELAYED_REF) {
                ret = __btrfs_free_extent(trans, node, parent,
-                                         ref_root, ref->objectid,
-                                         ref->offset, node->ref_mod,
-                                         extent_op);
+                                         ref->root, ref->objectid,
+                                         ref->offset, extent_op);
        } else {
                BUG();
        }
@@ -1604,7 +1603,6 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
        struct extent_buffer *leaf;
        u32 item_size;
        int ret;
-       int err = 0;
        int metadata = 1;
 
        if (TRANS_ABORTED(trans))
@@ -1631,10 +1629,8 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
 again:
        ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
        if (ret < 0) {
-               err = ret;
                goto out;
-       }
-       if (ret > 0) {
+       } else if (ret > 0) {
                if (metadata) {
                        if (path->slots[0] > 0) {
                                path->slots[0]--;
@@ -1655,7 +1651,7 @@ again:
                                goto again;
                        }
                } else {
-                       err = -EUCLEAN;
+                       ret = -EUCLEAN;
                        btrfs_err(fs_info,
                  "missing extent item for extent %llu num_bytes %llu level %d",
                                  head->bytenr, head->num_bytes, extent_op->level);
@@ -1667,21 +1663,21 @@ again:
        item_size = btrfs_item_size(leaf, path->slots[0]);
 
        if (unlikely(item_size < sizeof(*ei))) {
-               err = -EUCLEAN;
+               ret = -EUCLEAN;
                btrfs_err(fs_info,
                          "unexpected extent item size, has %u expect >= %zu",
                          item_size, sizeof(*ei));
-               btrfs_abort_transaction(trans, err);
+               btrfs_abort_transaction(trans, ret);
                goto out;
        }
 
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
        __run_delayed_extent_op(extent_op, leaf, ei);
 
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
 out:
        btrfs_free_path(path);
-       return err;
+       return ret;
 }
 
 static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
@@ -1713,10 +1709,10 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
                ret = alloc_reserved_tree_block(trans, node, extent_op);
        } else if (node->action == BTRFS_ADD_DELAYED_REF) {
                ret = __btrfs_inc_extent_ref(trans, node, parent, ref_root,
-                                            ref->level, 0, 1, extent_op);
+                                            ref->level, 0, extent_op);
        } else if (node->action == BTRFS_DROP_DELAYED_REF) {
                ret = __btrfs_free_extent(trans, node, parent, ref_root,
-                                         ref->level, 0, 1, extent_op);
+                                         ref->level, 0, extent_op);
        } else {
                BUG();
        }
@@ -1823,28 +1819,33 @@ static int run_and_cleanup_extent_op(struct btrfs_trans_handle *trans,
        return ret ? ret : 1;
 }
 
-void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
+u64 btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
                                  struct btrfs_delayed_ref_root *delayed_refs,
                                  struct btrfs_delayed_ref_head *head)
 {
-       int nr_items = 1;       /* Dropping this ref head update. */
-
        /*
         * We had csum deletions accounted for in our delayed refs rsv, we need
         * to drop the csum leaves for this update from our delayed_refs_rsv.
         */
        if (head->total_ref_mod < 0 && head->is_data) {
+               int nr_csums;
+
                spin_lock(&delayed_refs->lock);
                delayed_refs->pending_csums -= head->num_bytes;
                spin_unlock(&delayed_refs->lock);
-               nr_items += btrfs_csum_bytes_to_leaves(fs_info, head->num_bytes);
+               nr_csums = btrfs_csum_bytes_to_leaves(fs_info, head->num_bytes);
+
+               btrfs_delayed_refs_rsv_release(fs_info, 0, nr_csums);
+
+               return btrfs_calc_delayed_ref_csum_bytes(fs_info, nr_csums);
        }
 
-       btrfs_delayed_refs_rsv_release(fs_info, nr_items);
+       return 0;
 }
 
 static int cleanup_ref_head(struct btrfs_trans_handle *trans,
-                           struct btrfs_delayed_ref_head *head)
+                           struct btrfs_delayed_ref_head *head,
+                           u64 *bytes_released)
 {
 
        struct btrfs_fs_info *fs_info = trans->fs_info;
@@ -1889,7 +1890,7 @@ static int cleanup_ref_head(struct btrfs_trans_handle *trans,
                }
        }
 
-       btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head);
+       *bytes_released += btrfs_cleanup_ref_head_accounting(fs_info, delayed_refs, head);
 
        trace_run_delayed_ref_head(fs_info, head, 0);
        btrfs_delayed_ref_unlock(head);
@@ -1931,7 +1932,8 @@ static struct btrfs_delayed_ref_head *btrfs_obtain_ref_head(
 }
 
 static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
-                                          struct btrfs_delayed_ref_head *locked_ref)
+                                          struct btrfs_delayed_ref_head *locked_ref,
+                                          u64 *bytes_released)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_ref_root *delayed_refs;
@@ -1987,7 +1989,8 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
 
                ret = run_one_delayed_ref(trans, ref, extent_op,
                                          must_insert_reserved);
-
+               btrfs_delayed_refs_rsv_release(fs_info, 1, 0);
+               *bytes_released += btrfs_calc_delayed_ref_bytes(fs_info, 1);
                btrfs_free_delayed_extent_op(extent_op);
                if (ret) {
                        unselect_delayed_ref_head(delayed_refs, locked_ref);
@@ -2010,15 +2013,22 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
  * Returns -ENOMEM or -EIO on failure and will abort the transaction.
  */
 static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
-                                            unsigned long nr)
+                                            u64 min_bytes)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_ref_root *delayed_refs;
        struct btrfs_delayed_ref_head *locked_ref = NULL;
        int ret;
        unsigned long count = 0;
+       unsigned long max_count = 0;
+       u64 bytes_processed = 0;
 
        delayed_refs = &trans->transaction->delayed_refs;
+       if (min_bytes == 0) {
+               max_count = delayed_refs->num_heads_ready;
+               min_bytes = U64_MAX;
+       }
+
        do {
                if (!locked_ref) {
                        locked_ref = btrfs_obtain_ref_head(trans);
@@ -2046,7 +2056,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                spin_lock(&locked_ref->lock);
                btrfs_merge_delayed_refs(fs_info, delayed_refs, locked_ref);
 
-               ret = btrfs_run_delayed_refs_for_head(trans, locked_ref);
+               ret = btrfs_run_delayed_refs_for_head(trans, locked_ref, &bytes_processed);
                if (ret < 0 && ret != -EAGAIN) {
                        /*
                         * Error, btrfs_run_delayed_refs_for_head already
@@ -2058,7 +2068,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                         * Success, perform the usual cleanup of a processed
                         * head
                         */
-                       ret = cleanup_ref_head(trans, locked_ref);
+                       ret = cleanup_ref_head(trans, locked_ref, &bytes_processed);
                        if (ret > 0 ) {
                                /* We dropped our lock, we need to loop. */
                                ret = 0;
@@ -2075,7 +2085,9 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
 
                locked_ref = NULL;
                cond_resched();
-       } while ((nr != -1 && count < nr) || locked_ref);
+       } while ((min_bytes != U64_MAX && bytes_processed < min_bytes) ||
+                (max_count > 0 && count < max_count) ||
+                locked_ref);
 
        return 0;
 }
@@ -2124,24 +2136,25 @@ static u64 find_middle(struct rb_root *root)
 #endif
 
 /*
- * this starts processing the delayed reference count updates and
- * extent insertions we have queued up so far.  count can be
- * 0, which means to process everything in the tree at the start
- * of the run (but not newly added entries), or it can be some target
- * number you'd like to process.
+ * Start processing the delayed reference count updates and extent insertions
+ * we have queued up so far.
+ *
+ * @trans:     Transaction handle.
+ * @min_bytes: How many bytes of delayed references to process. After this
+ *             many bytes we stop processing delayed references if there are
+ *             any more. If 0 it means to run all existing delayed references,
+ *             but not new ones added after running all existing ones.
+ *             Use (u64)-1 (U64_MAX) to run all existing delayed references
+ *             plus any new ones that are added.
  *
  * Returns 0 on success or if called with an aborted transaction
  * Returns <0 on error and aborts the transaction
  */
-int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
-                          unsigned long count)
+int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, u64 min_bytes)
 {
        struct btrfs_fs_info *fs_info = trans->fs_info;
-       struct rb_node *node;
        struct btrfs_delayed_ref_root *delayed_refs;
-       struct btrfs_delayed_ref_head *head;
        int ret;
-       int run_all = count == (unsigned long)-1;
 
        /* We'll clean this up in btrfs_cleanup_transaction */
        if (TRANS_ABORTED(trans))
@@ -2151,42 +2164,30 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
                return 0;
 
        delayed_refs = &trans->transaction->delayed_refs;
-       if (count == 0)
-               count = delayed_refs->num_heads_ready;
-
 again:
 #ifdef SCRAMBLE_DELAYED_REFS
        delayed_refs->run_delayed_start = find_middle(&delayed_refs->root);
 #endif
-       ret = __btrfs_run_delayed_refs(trans, count);
+       ret = __btrfs_run_delayed_refs(trans, min_bytes);
        if (ret < 0) {
                btrfs_abort_transaction(trans, ret);
                return ret;
        }
 
-       if (run_all) {
+       if (min_bytes == U64_MAX) {
                btrfs_create_pending_block_groups(trans);
 
                spin_lock(&delayed_refs->lock);
-               node = rb_first_cached(&delayed_refs->href_root);
-               if (!node) {
+               if (RB_EMPTY_ROOT(&delayed_refs->href_root.rb_root)) {
                        spin_unlock(&delayed_refs->lock);
-                       goto out;
+                       return 0;
                }
-               head = rb_entry(node, struct btrfs_delayed_ref_head,
-                               href_node);
-               refcount_inc(&head->refs);
                spin_unlock(&delayed_refs->lock);
 
-               /* Mutex was contended, block until it's released and retry. */
-               mutex_lock(&head->mutex);
-               mutex_unlock(&head->mutex);
-
-               btrfs_put_delayed_ref_head(head);
                cond_resched();
                goto again;
        }
-out:
+
        return 0;
 }
 
@@ -2569,12 +2570,12 @@ int btrfs_pin_extent(struct btrfs_trans_handle *trans,
  * this function must be called within transaction
  */
 int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
-                                   u64 bytenr, u64 num_bytes)
+                                   const struct extent_buffer *eb)
 {
        struct btrfs_block_group *cache;
        int ret;
 
-       cache = btrfs_lookup_block_group(trans->fs_info, bytenr);
+       cache = btrfs_lookup_block_group(trans->fs_info, eb->start);
        if (!cache)
                return -EINVAL;
 
@@ -2586,10 +2587,10 @@ int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,
        if (ret)
                goto out;
 
-       pin_down_extent(trans, cache, bytenr, num_bytes, 0);
+       pin_down_extent(trans, cache, eb->start, eb->len, 0);
 
        /* remove us from the free space cache (if we're there at all) */
-       ret = btrfs_remove_free_space(cache, bytenr, num_bytes);
+       ret = btrfs_remove_free_space(cache, eb->start, eb->len);
 out:
        btrfs_put_block_group(cache);
        return ret;
@@ -2942,7 +2943,7 @@ static int do_free_extent_accounting(struct btrfs_trans_handle *trans,
 static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                               struct btrfs_delayed_ref_node *node, u64 parent,
                               u64 root_objectid, u64 owner_objectid,
-                              u64 owner_offset, int refs_to_drop,
+                              u64 owner_offset,
                               struct btrfs_delayed_extent_op *extent_op)
 {
        struct btrfs_fs_info *info = trans->fs_info;
@@ -2957,6 +2958,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
        int extent_slot = 0;
        int found_extent = 0;
        int num_to_del = 1;
+       int refs_to_drop = node->ref_mod;
        u32 item_size;
        u64 refs;
        u64 bytenr = node->bytenr;
@@ -3151,7 +3153,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                        }
                } else {
                        btrfs_set_extent_refs(leaf, ei, refs);
-                       btrfs_mark_buffer_dirty(leaf);
+                       btrfs_mark_buffer_dirty(trans, leaf);
                }
                if (found_extent) {
                        ret = remove_extent_backref(trans, extent_root, path,
@@ -3373,7 +3375,6 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
             ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID) ||
            (ref->type == BTRFS_REF_DATA &&
             ref->data_ref.owning_root == BTRFS_TREE_LOG_OBJECTID)) {
-               /* unlocks the pinned mutex */
                btrfs_pin_extent(trans, ref->bytenr, ref->len, 1);
                ret = 0;
        } else if (ref->type == BTRFS_REF_METADATA) {
@@ -4442,8 +4443,8 @@ loop:
 }
 
 /*
- * btrfs_reserve_extent - entry point to the extent allocator. Tries to find a
- *                       hole that is at least as big as @num_bytes.
+ * Entry point to the extent allocator. Tries to find a hole that is at least
+ * as big as @num_bytes.
  *
  * @root           -   The root that will contain this extent
  *
@@ -4562,20 +4563,20 @@ int btrfs_free_reserved_extent(struct btrfs_fs_info *fs_info,
        return 0;
 }
 
-int btrfs_pin_reserved_extent(struct btrfs_trans_handle *trans, u64 start,
-                             u64 len)
+int btrfs_pin_reserved_extent(struct btrfs_trans_handle *trans,
+                             const struct extent_buffer *eb)
 {
        struct btrfs_block_group *cache;
        int ret = 0;
 
-       cache = btrfs_lookup_block_group(trans->fs_info, start);
+       cache = btrfs_lookup_block_group(trans->fs_info, eb->start);
        if (!cache) {
                btrfs_err(trans->fs_info, "unable to find block group for %llu",
-                         start);
+                         eb->start);
                return -ENOSPC;
        }
 
-       ret = pin_down_extent(trans, cache, start, len, 1);
+       ret = pin_down_extent(trans, cache, eb->start, eb->len, 1);
        btrfs_put_block_group(cache);
        return ret;
 }
@@ -4659,7 +4660,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
                btrfs_set_extent_data_ref_count(leaf, ref, ref_mod);
        }
 
-       btrfs_mark_buffer_dirty(path->nodes[0]);
+       btrfs_mark_buffer_dirty(trans, path->nodes[0]);
        btrfs_free_path(path);
 
        return alloc_reserved_extent(trans, ins->objectid, ins->offset);
@@ -4734,7 +4735,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
                btrfs_set_extent_inline_ref_offset(leaf, iref, ref->root);
        }
 
-       btrfs_mark_buffer_dirty(leaf);
+       btrfs_mark_buffer_dirty(trans, leaf);
        btrfs_free_path(path);
 
        return alloc_reserved_extent(trans, node->bytenr, fs_info->nodesize);
@@ -4803,6 +4804,28 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        return ret;
 }
 
+#ifdef CONFIG_BTRFS_DEBUG
+/*
+ * Extra safety check in case the extent tree is corrupted and extent allocator
+ * chooses to use a tree block which is already used and locked.
+ */
+static bool check_eb_lock_owner(const struct extent_buffer *eb)
+{
+       if (eb->lock_owner == current->pid) {
+               btrfs_err_rl(eb->fs_info,
+"tree block %llu owner %llu already locked by pid=%d, extent tree corruption detected",
+                            eb->start, btrfs_header_owner(eb), current->pid);
+               return true;
+       }
+       return false;
+}
+#else
+static bool check_eb_lock_owner(struct extent_buffer *eb)
+{
+       return false;
+}
+#endif
+
 static struct extent_buffer *
 btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
                      u64 bytenr, int level, u64 owner,
@@ -4816,15 +4839,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
        if (IS_ERR(buf))
                return buf;
 
-       /*
-        * Extra safety check in case the extent tree is corrupted and extent
-        * allocator chooses to use a tree block which is already used and
-        * locked.
-        */
-       if (buf->lock_owner == current->pid) {
-               btrfs_err_rl(fs_info,
-"tree block %llu owner %llu already locked by pid=%d, extent tree corruption detected",
-                       buf->start, btrfs_header_owner(buf), current->pid);
+       if (check_eb_lock_owner(buf)) {
                free_extent_buffer(buf);
                return ERR_PTR(-EUCLEAN);
        }