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 ||
                        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 {
 
        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);
 
        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;
                 node->type == BTRFS_SHARED_DATA_REF_KEY)
                ret = run_delayed_data_ref(trans, node, extent_op,
                                           insert_reserved);
+       else if (node->type == BTRFS_EXTENT_OWNER_REF_KEY)
+               ret = 0;
        else
                BUG();
        if (ret && insert_reserved)
        struct btrfs_extent_item *ei;
        struct btrfs_key key;
        u32 item_size;
+       u32 expected_size;
        int type;
        int ret;
 
        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;
 
        /*
             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)
        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)
                               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);
 
               btrfs_extent_data_ref_count(eb, ref));
 }
 
+static void print_extent_owner_ref(const struct extent_buffer *eb,
+                                  const struct btrfs_extent_owner_ref *ref)
+{
+       ASSERT(btrfs_fs_incompat(eb->fs_info, SIMPLE_QUOTA));
+       pr_cont("extent data owner root %llu\n", btrfs_extent_owner_ref_root_id(eb, ref));
+}
+
 static void print_extent_item(const struct extent_buffer *eb, int slot, int type)
 {
        struct btrfs_extent_item *ei;
        struct btrfs_extent_inline_ref *iref;
        struct btrfs_extent_data_ref *dref;
        struct btrfs_shared_data_ref *sref;
+       struct btrfs_extent_owner_ref *oref;
        struct btrfs_disk_key key;
        unsigned long end;
        unsigned long ptr;
                        "\t\t\t(parent %llu not aligned to sectorsize %u)\n",
                                     offset, eb->fs_info->sectorsize);
                        break;
+               case BTRFS_EXTENT_OWNER_REF_KEY:
+                       oref = (struct btrfs_extent_owner_ref *)(&iref->offset);
+                       print_extent_owner_ref(eb, oref);
+                       break;
                default:
                        pr_cont("(extent %llu has INVALID ref type %d)\n",
                                  eb->start, type);