btrfs: qgroup: simple quota auto hierarchy for nested subvolumes
[linux-2.6-microblaze.git] / fs / btrfs / extent-tree.c
index 3e58c8d..865c74d 100644 (file)
 #include "file-item.h"
 #include "orphan.h"
 #include "tree-checker.h"
+#include "raid-stripe-tree.h"
 
 #undef SCRAMBLE_DELAYED_REFS
 
 
 static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
+                              struct btrfs_delayed_ref_head *href,
                               struct btrfs_delayed_ref_node *node, u64 parent,
                               u64 root_objectid, u64 owner_objectid,
                               u64 owner_offset,
@@ -344,9 +346,15 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
                                     struct btrfs_extent_inline_ref *iref,
                                     enum btrfs_inline_ref_type is_data)
 {
+       struct btrfs_fs_info *fs_info = eb->fs_info;
        int type = btrfs_extent_inline_ref_type(eb, iref);
        u64 offset = btrfs_extent_inline_ref_offset(eb, iref);
 
+       if (type == BTRFS_EXTENT_OWNER_REF_KEY) {
+               ASSERT(btrfs_fs_incompat(fs_info, SIMPLE_QUOTA));
+               return type;
+       }
+
        if (type == BTRFS_TREE_BLOCK_REF_KEY ||
            type == BTRFS_SHARED_BLOCK_REF_KEY ||
            type == BTRFS_SHARED_DATA_REF_KEY ||
@@ -355,26 +363,25 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
                        if (type == BTRFS_TREE_BLOCK_REF_KEY)
                                return type;
                        if (type == BTRFS_SHARED_BLOCK_REF_KEY) {
-                               ASSERT(eb->fs_info);
+                               ASSERT(fs_info);
                                /*
                                 * Every shared one has parent tree block,
                                 * which must be aligned to sector size.
                                 */
-                               if (offset &&
-                                   IS_ALIGNED(offset, eb->fs_info->sectorsize))
+                               if (offset && IS_ALIGNED(offset, fs_info->sectorsize))
                                        return type;
                        }
                } else if (is_data == BTRFS_REF_TYPE_DATA) {
                        if (type == BTRFS_EXTENT_DATA_REF_KEY)
                                return type;
                        if (type == BTRFS_SHARED_DATA_REF_KEY) {
-                               ASSERT(eb->fs_info);
+                               ASSERT(fs_info);
                                /*
                                 * Every shared one has parent tree block,
                                 * which must be aligned to sector size.
                                 */
                                if (offset &&
-                                   IS_ALIGNED(offset, eb->fs_info->sectorsize))
+                                   IS_ALIGNED(offset, fs_info->sectorsize))
                                        return type;
                        }
                } else {
@@ -385,7 +392,7 @@ int btrfs_get_extent_inline_ref_type(const struct extent_buffer *eb,
 
        WARN_ON(1);
        btrfs_print_leaf(eb);
-       btrfs_err(eb->fs_info,
+       btrfs_err(fs_info,
                  "eb %llu iref 0x%lx invalid extent inline ref type %d",
                  eb->start, (unsigned long)iref, type);
 
@@ -886,6 +893,11 @@ again:
        while (ptr < end) {
                iref = (struct btrfs_extent_inline_ref *)ptr;
                type = btrfs_get_extent_inline_ref_type(leaf, iref, needed);
+               if (type == BTRFS_EXTENT_OWNER_REF_KEY) {
+                       ASSERT(btrfs_fs_incompat(fs_info, SIMPLE_QUOTA));
+                       ptr += btrfs_extent_inline_ref_size(type);
+                       continue;
+               }
                if (type == BTRFS_REF_TYPE_INVALID) {
                        ret = -EUCLEAN;
                        goto out;
@@ -1423,7 +1435,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
        ASSERT(generic_ref->type != BTRFS_REF_NOT_SET &&
               generic_ref->action);
        BUG_ON(generic_ref->type == BTRFS_REF_METADATA &&
-              generic_ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID);
+              generic_ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID);
 
        if (generic_ref->type == BTRFS_REF_METADATA)
                ret = btrfs_add_delayed_tree_ref(trans, generic_ref, NULL);
@@ -1530,6 +1542,7 @@ out:
 }
 
 static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
+                               struct btrfs_delayed_ref_head *href,
                                struct btrfs_delayed_ref_node *node,
                                struct btrfs_delayed_extent_op *extent_op,
                                bool insert_reserved)
@@ -1547,6 +1560,13 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
 
        if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
                struct btrfs_key key;
+               struct btrfs_squota_delta delta = {
+                       .root = href->owning_root,
+                       .num_bytes = node->num_bytes,
+                       .rsv_bytes = href->reserved_bytes,
+                       .is_data = true,
+                       .is_inc = true,
+               };
 
                if (extent_op)
                        flags |= extent_op->flags_to_set;
@@ -1559,12 +1579,17 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
                                                 flags, ref->objectid,
                                                 ref->offset, &key,
                                                 node->ref_mod);
+               if (!ret)
+                       ret = btrfs_record_squota_delta(trans->fs_info, &delta);
+               else
+                       btrfs_qgroup_free_refroot(trans->fs_info, delta.root,
+                                                 delta.rsv_bytes, BTRFS_QGROUP_RSV_DATA);
        } else if (node->action == BTRFS_ADD_DELAYED_REF) {
                ret = __btrfs_inc_extent_ref(trans, node, parent, ref->root,
                                             ref->objectid, ref->offset,
                                             extent_op);
        } else if (node->action == BTRFS_DROP_DELAYED_REF) {
-               ret = __btrfs_free_extent(trans, node, parent,
+               ret = __btrfs_free_extent(trans, href, node, parent,
                                          ref->root, ref->objectid,
                                          ref->offset, extent_op);
        } else {
@@ -1681,11 +1706,13 @@ out:
 }
 
 static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
+                               struct btrfs_delayed_ref_head *href,
                                struct btrfs_delayed_ref_node *node,
                                struct btrfs_delayed_extent_op *extent_op,
                                bool insert_reserved)
 {
        int ret = 0;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_tree_ref *ref;
        u64 parent = 0;
        u64 ref_root = 0;
@@ -1705,13 +1732,23 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
                return -EUCLEAN;
        }
        if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
+               struct btrfs_squota_delta delta = {
+                       .root = href->owning_root,
+                       .num_bytes = fs_info->nodesize,
+                       .rsv_bytes = 0,
+                       .is_data = false,
+                       .is_inc = true,
+               };
+
                BUG_ON(!extent_op || !extent_op->update_flags);
                ret = alloc_reserved_tree_block(trans, node, extent_op);
+               if (!ret)
+                       btrfs_record_squota_delta(fs_info, &delta);
        } else if (node->action == BTRFS_ADD_DELAYED_REF) {
                ret = __btrfs_inc_extent_ref(trans, node, parent, ref_root,
                                             ref->level, 0, extent_op);
        } else if (node->action == BTRFS_DROP_DELAYED_REF) {
-               ret = __btrfs_free_extent(trans, node, parent, ref_root,
+               ret = __btrfs_free_extent(trans, href, node, parent, ref_root,
                                          ref->level, 0, extent_op);
        } else {
                BUG();
@@ -1721,6 +1758,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
 
 /* helper function to actually process a single delayed ref entry */
 static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
+                              struct btrfs_delayed_ref_head *href,
                               struct btrfs_delayed_ref_node *node,
                               struct btrfs_delayed_extent_op *extent_op,
                               bool insert_reserved)
@@ -1735,12 +1773,14 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
 
        if (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
            node->type == BTRFS_SHARED_BLOCK_REF_KEY)
-               ret = run_delayed_tree_ref(trans, node, extent_op,
+               ret = run_delayed_tree_ref(trans, href, node, extent_op,
                                           insert_reserved);
        else if (node->type == BTRFS_EXTENT_DATA_REF_KEY ||
                 node->type == BTRFS_SHARED_DATA_REF_KEY)
-               ret = run_delayed_data_ref(trans, node, extent_op,
+               ret = run_delayed_data_ref(trans, href, node, extent_op,
                                           insert_reserved);
+       else if (node->type == BTRFS_EXTENT_OWNER_REF_KEY)
+               ret = 0;
        else
                BUG();
        if (ret && insert_reserved)
@@ -1839,6 +1879,10 @@ u64 btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
 
                return btrfs_calc_delayed_ref_csum_bytes(fs_info, nr_csums);
        }
+       if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE &&
+           head->must_insert_reserved && head->is_data)
+               btrfs_qgroup_free_refroot(fs_info, head->owning_root,
+                                         head->reserved_bytes, BTRFS_QGROUP_RSV_DATA);
 
        return 0;
 }
@@ -1987,10 +2031,11 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
                locked_ref->extent_op = NULL;
                spin_unlock(&locked_ref->lock);
 
-               ret = run_one_delayed_ref(trans, ref, extent_op,
+               ret = run_one_delayed_ref(trans, locked_ref, 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);
@@ -2312,6 +2357,7 @@ static noinline int check_committed_ref(struct btrfs_root *root,
        struct btrfs_extent_item *ei;
        struct btrfs_key key;
        u32 item_size;
+       u32 expected_size;
        int type;
        int ret;
 
@@ -2338,10 +2384,22 @@ static noinline int check_committed_ref(struct btrfs_root *root,
        ret = 1;
        item_size = btrfs_item_size(leaf, path->slots[0]);
        ei = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_extent_item);
+       expected_size = sizeof(*ei) + btrfs_extent_inline_ref_size(BTRFS_EXTENT_DATA_REF_KEY);
+
+       /* No inline refs; we need to bail before checking for owner ref. */
+       if (item_size == sizeof(*ei))
+               goto out;
+
+       /* Check for an owner ref; skip over it to the real inline refs. */
+       iref = (struct btrfs_extent_inline_ref *)(ei + 1);
+       type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_DATA);
+       if (btrfs_fs_incompat(fs_info, SIMPLE_QUOTA) && type == BTRFS_EXTENT_OWNER_REF_KEY) {
+               expected_size += btrfs_extent_inline_ref_size(BTRFS_EXTENT_OWNER_REF_KEY);
+               iref = (struct btrfs_extent_inline_ref *)(iref + 1);
+       }
 
        /* If extent item has more than 1 inline ref then it's shared */
-       if (item_size != sizeof(*ei) +
-           btrfs_extent_inline_ref_size(BTRFS_EXTENT_DATA_REF_KEY))
+       if (item_size != expected_size)
                goto out;
 
        /*
@@ -2353,8 +2411,6 @@ static noinline int check_committed_ref(struct btrfs_root *root,
             btrfs_root_last_snapshot(&root->root_item)))
                goto out;
 
-       iref = (struct btrfs_extent_inline_ref *)(ei + 1);
-
        /* If this extent has SHARED_DATA_REF then it's shared */
        type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_DATA);
        if (type != BTRFS_EXTENT_DATA_REF_KEY)
@@ -2451,7 +2507,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
                        num_bytes = btrfs_file_extent_disk_num_bytes(buf, fi);
                        key.offset -= btrfs_file_extent_offset(buf, fi);
                        btrfs_init_generic_ref(&generic_ref, action, bytenr,
-                                              num_bytes, parent);
+                                              num_bytes, parent, ref_root);
                        btrfs_init_data_ref(&generic_ref, ref_root, key.objectid,
                                            key.offset, root->root_key.objectid,
                                            for_reloc);
@@ -2464,8 +2520,9 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
                } else {
                        bytenr = btrfs_node_blockptr(buf, i);
                        num_bytes = fs_info->nodesize;
+                       /* We don't know the owning_root, use 0. */
                        btrfs_init_generic_ref(&generic_ref, action, bytenr,
-                                              num_bytes, parent);
+                                              num_bytes, parent, 0);
                        btrfs_init_tree_ref(&generic_ref, level - 1, ref_root,
                                            root->root_key.objectid, for_reloc);
                        if (inc)
@@ -2842,12 +2899,61 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
        return 0;
 }
 
+/*
+ * Parse an extent item's inline extents looking for a simple quotas owner ref.
+ *
+ * @fs_info:   the btrfs_fs_info for this mount
+ * @leaf:      a leaf in the extent tree containing the extent item
+ * @slot:      the slot in the leaf where the extent item is found
+ *
+ * Returns the objectid of the root that originally allocated the extent item
+ * if the inline owner ref is expected and present, otherwise 0.
+ *
+ * If an extent item has an owner ref item, it will be the first inline ref
+ * item. Therefore the logic is to check whether there are any inline ref
+ * items, then check the type of the first one.
+ */
+u64 btrfs_get_extent_owner_root(struct btrfs_fs_info *fs_info,
+                               struct extent_buffer *leaf, int slot)
+{
+       struct btrfs_extent_item *ei;
+       struct btrfs_extent_inline_ref *iref;
+       struct btrfs_extent_owner_ref *oref;
+       unsigned long ptr;
+       unsigned long end;
+       int type;
+
+       if (!btrfs_fs_incompat(fs_info, SIMPLE_QUOTA))
+               return 0;
+
+       ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
+       ptr = (unsigned long)(ei + 1);
+       end = (unsigned long)ei + btrfs_item_size(leaf, slot);
+
+       /* No inline ref items of any kind, can't check type. */
+       if (ptr == end)
+               return 0;
+
+       iref = (struct btrfs_extent_inline_ref *)ptr;
+       type = btrfs_get_extent_inline_ref_type(leaf, iref, BTRFS_REF_TYPE_ANY);
+
+       /* We found an owner ref, get the root out of it. */
+       if (type == BTRFS_EXTENT_OWNER_REF_KEY) {
+               oref = (struct btrfs_extent_owner_ref *)(&iref->offset);
+               return btrfs_extent_owner_ref_root_id(leaf, oref);
+       }
+
+       /* We have inline refs, but not an owner ref. */
+       return 0;
+}
+
 static int do_free_extent_accounting(struct btrfs_trans_handle *trans,
-                                    u64 bytenr, u64 num_bytes, bool is_data)
+                                    u64 bytenr, struct btrfs_squota_delta *delta)
 {
        int ret;
+       u64 num_bytes = delta->num_bytes;
 
-       if (is_data) {
+       if (delta->is_data) {
                struct btrfs_root *csum_root;
 
                csum_root = btrfs_csum_root(trans->fs_info, bytenr);
@@ -2856,6 +2962,18 @@ static int do_free_extent_accounting(struct btrfs_trans_handle *trans,
                        btrfs_abort_transaction(trans, ret);
                        return ret;
                }
+
+               ret = btrfs_delete_raid_extent(trans, bytenr, num_bytes);
+               if (ret) {
+                       btrfs_abort_transaction(trans, ret);
+                       return ret;
+               }
+       }
+
+       ret = btrfs_record_squota_delta(trans->fs_info, delta);
+       if (ret) {
+               btrfs_abort_transaction(trans, ret);
+               return ret;
        }
 
        ret = add_to_free_space_tree(trans, bytenr, num_bytes);
@@ -2938,6 +3056,7 @@ static int do_free_extent_accounting(struct btrfs_trans_handle *trans,
  * And that (13631488 EXTENT_DATA_REF <HASH>) gets removed.
  */
 static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
+                              struct btrfs_delayed_ref_head *href,
                               struct btrfs_delayed_ref_node *node, u64 parent,
                               u64 root_objectid, u64 owner_objectid,
                               u64 owner_offset,
@@ -2961,6 +3080,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
        u64 bytenr = node->bytenr;
        u64 num_bytes = node->num_bytes;
        bool skinny_metadata = btrfs_fs_incompat(info, SKINNY_METADATA);
+       u64 delayed_ref_root = href->owning_root;
 
        extent_root = btrfs_extent_root(info, bytenr);
        ASSERT(extent_root);
@@ -3161,6 +3281,14 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                        }
                }
        } else {
+               struct btrfs_squota_delta delta = {
+                       .root = delayed_ref_root,
+                       .num_bytes = num_bytes,
+                       .rsv_bytes = 0,
+                       .is_data = is_data,
+                       .is_inc = false,
+               };
+
                /* In this branch refs == 1 */
                if (found_extent) {
                        if (is_data && refs_to_drop !=
@@ -3199,6 +3327,16 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                num_to_del = 2;
                        }
                }
+               /*
+                * We can't infer the data owner from the delayed ref, so we need
+                * to try to get it from the owning ref item.
+                *
+                * If it is not present, then that extent was not written under
+                * simple quotas mode, so we don't need to account for its deletion.
+                */
+               if (is_data)
+                       delta.root = btrfs_get_extent_owner_root(trans->fs_info,
+                                                                leaf, extent_slot);
 
                ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
                                      num_to_del);
@@ -3208,7 +3346,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                }
                btrfs_release_path(path);
 
-               ret = do_free_extent_accounting(trans, bytenr, num_bytes, is_data);
+               ret = do_free_extent_accounting(trans, bytenr, &delta);
        }
        btrfs_release_path(path);
 
@@ -3282,7 +3420,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
        int ret;
 
        btrfs_init_generic_ref(&generic_ref, BTRFS_DROP_DELAYED_REF,
-                              buf->start, buf->len, parent);
+                              buf->start, buf->len, parent, btrfs_header_owner(buf));
        btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
                            root_id, 0, false);
 
@@ -3369,9 +3507,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
         * tree, just update pinning info and exit early.
         */
        if ((ref->type == BTRFS_REF_METADATA &&
-            ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID) ||
+            ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID) ||
            (ref->type == BTRFS_REF_DATA &&
-            ref->data_ref.owning_root == BTRFS_TREE_LOG_OBJECTID)) {
+            ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)) {
                btrfs_pin_extent(trans, ref->bytenr, ref->len, 1);
                ret = 0;
        } else if (ref->type == BTRFS_REF_METADATA) {
@@ -3381,9 +3519,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_ref *ref)
        }
 
        if (!((ref->type == BTRFS_REF_METADATA &&
-              ref->tree_ref.owning_root == BTRFS_TREE_LOG_OBJECTID) ||
+              ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID) ||
              (ref->type == BTRFS_REF_DATA &&
-              ref->data_ref.owning_root == BTRFS_TREE_LOG_OBJECTID)))
+              ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)))
                btrfs_ref_tree_mod(fs_info, ref);
 
        return ret;
@@ -4609,18 +4747,23 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
        struct btrfs_root *extent_root;
        int ret;
        struct btrfs_extent_item *extent_item;
+       struct btrfs_extent_owner_ref *oref;
        struct btrfs_extent_inline_ref *iref;
        struct btrfs_path *path;
        struct extent_buffer *leaf;
        int type;
        u32 size;
+       const bool simple_quota = (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE);
 
        if (parent > 0)
                type = BTRFS_SHARED_DATA_REF_KEY;
        else
                type = BTRFS_EXTENT_DATA_REF_KEY;
 
-       size = sizeof(*extent_item) + btrfs_extent_inline_ref_size(type);
+       size = sizeof(*extent_item);
+       if (simple_quota)
+               size += btrfs_extent_inline_ref_size(BTRFS_EXTENT_OWNER_REF_KEY);
+       size += btrfs_extent_inline_ref_size(type);
 
        path = btrfs_alloc_path();
        if (!path)
@@ -4642,7 +4785,14 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
                               flags | BTRFS_EXTENT_FLAG_DATA);
 
        iref = (struct btrfs_extent_inline_ref *)(extent_item + 1);
+       if (simple_quota) {
+               btrfs_set_extent_inline_ref_type(leaf, iref, BTRFS_EXTENT_OWNER_REF_KEY);
+               oref = (struct btrfs_extent_owner_ref *)(&iref->offset);
+               btrfs_set_extent_owner_ref_root_id(leaf, oref, root_objectid);
+               iref = (struct btrfs_extent_inline_ref *)(oref + 1);
+       }
        btrfs_set_extent_inline_ref_type(leaf, iref, type);
+
        if (parent > 0) {
                struct btrfs_shared_data_ref *ref;
                ref = (struct btrfs_shared_data_ref *)(iref + 1);
@@ -4744,12 +4894,14 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
                                     struct btrfs_key *ins)
 {
        struct btrfs_ref generic_ref = { 0 };
+       u64 root_objectid = root->root_key.objectid;
+       u64 owning_root = root_objectid;
 
-       BUG_ON(root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);
+       BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
 
        btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_EXTENT,
-                              ins->objectid, ins->offset, 0);
-       btrfs_init_data_ref(&generic_ref, root->root_key.objectid, owner,
+                              ins->objectid, ins->offset, 0, owning_root);
+       btrfs_init_data_ref(&generic_ref, root_objectid, owner,
                            offset, 0, false);
        btrfs_ref_tree_mod(root->fs_info, &generic_ref);
 
@@ -4769,6 +4921,13 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
        int ret;
        struct btrfs_block_group *block_group;
        struct btrfs_space_info *space_info;
+       struct btrfs_squota_delta delta = {
+               .root = root_objectid,
+               .num_bytes = ins->offset,
+               .rsv_bytes = 0,
+               .is_data = true,
+               .is_inc = true,
+       };
 
        /*
         * Mixed block groups will exclude before processing the log so we only
@@ -4797,6 +4956,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                                         offset, ins, 1);
        if (ret)
                btrfs_pin_extent(trans, ins->objectid, ins->offset, 1);
+       ret = btrfs_record_squota_delta(fs_info, &delta);
        btrfs_put_block_group(block_group);
        return ret;
 }
@@ -4975,7 +5135,8 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
                extent_op->level = level;
 
                btrfs_init_generic_ref(&generic_ref, BTRFS_ADD_DELAYED_EXTENT,
-                                      ins.objectid, ins.offset, parent);
+                                      ins.objectid, ins.offset, parent,
+                                      btrfs_header_owner(buf));
                btrfs_init_tree_ref(&generic_ref, level, root_objectid,
                                    root->root_key.objectid, false);
                btrfs_ref_tree_mod(fs_info, &generic_ref);
@@ -5396,7 +5557,8 @@ skip:
                find_next_key(path, level, &wc->drop_progress);
 
                btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
-                                      fs_info->nodesize, parent);
+                                      fs_info->nodesize, parent,
+                                      btrfs_header_owner(next));
                btrfs_init_tree_ref(&ref, level - 1, root->root_key.objectid,
                                    0, false);
                ret = btrfs_free_extent(trans, &ref);