INIT_LIST_HEAD(&ref->add_list);
}
-void btrfs_init_tree_ref(struct btrfs_ref *generic_ref, int level, u64 root,
- u64 mod_root, bool skip_qgroup)
+void btrfs_init_tree_ref(struct btrfs_ref *generic_ref, int level, u64 mod_root,
+ bool skip_qgroup)
{
#ifdef CONFIG_BTRFS_FS_REF_VERIFY
/* If @real_root not set, use @root as fallback */
- generic_ref->real_root = mod_root ?: root;
+ generic_ref->real_root = mod_root ?: generic_ref->ref_root;
#endif
generic_ref->tree_ref.level = level;
- generic_ref->tree_ref.ref_root = root;
generic_ref->type = BTRFS_REF_METADATA;
- if (skip_qgroup || !(is_fstree(root) &&
+ if (skip_qgroup || !(is_fstree(generic_ref->ref_root) &&
(!mod_root || is_fstree(mod_root))))
generic_ref->skip_qgroup = true;
else
}
-void btrfs_init_data_ref(struct btrfs_ref *generic_ref, u64 ref_root, u64 ino,
- u64 offset, u64 mod_root, bool skip_qgroup)
+void btrfs_init_data_ref(struct btrfs_ref *generic_ref, u64 ino, u64 offset,
+ u64 mod_root, bool skip_qgroup)
{
#ifdef CONFIG_BTRFS_FS_REF_VERIFY
/* If @real_root not set, use @root as fallback */
- generic_ref->real_root = mod_root ?: ref_root;
+ generic_ref->real_root = mod_root ?: generic_ref->ref_root;
#endif
- generic_ref->data_ref.ref_root = ref_root;
generic_ref->data_ref.ino = ino;
generic_ref->data_ref.offset = offset;
generic_ref->type = BTRFS_REF_DATA;
- if (skip_qgroup || !(is_fstree(ref_root) &&
+ if (skip_qgroup || !(is_fstree(generic_ref->ref_root) &&
(!mod_root || is_fstree(mod_root))))
generic_ref->skip_qgroup = true;
else
u64 parent = generic_ref->parent;
u8 ref_type;
- is_system = (generic_ref->tree_ref.ref_root == BTRFS_CHUNK_TREE_OBJECTID);
+ is_system = (generic_ref->ref_root == BTRFS_CHUNK_TREE_OBJECTID);
ASSERT(generic_ref->type == BTRFS_REF_METADATA && generic_ref->action);
node = kmem_cache_alloc(btrfs_delayed_ref_node_cachep, GFP_NOFS);
ref_type = BTRFS_TREE_BLOCK_REF_KEY;
init_delayed_ref_common(fs_info, node, bytenr, num_bytes,
- generic_ref->tree_ref.ref_root, action,
- ref_type);
- ref->root = generic_ref->tree_ref.ref_root;
+ generic_ref->ref_root, action, ref_type);
+ ref->root = generic_ref->ref_root;
ref->parent = parent;
ref->level = level;
init_delayed_ref_head(head_ref, record, bytenr, num_bytes,
- generic_ref->tree_ref.ref_root, 0, action,
+ generic_ref->ref_root, 0, action,
false, is_system, generic_ref->owning_root);
head_ref->extent_op = extent_op;
u64 bytenr = generic_ref->bytenr;
u64 num_bytes = generic_ref->len;
u64 parent = generic_ref->parent;
- u64 ref_root = generic_ref->data_ref.ref_root;
+ u64 ref_root = generic_ref->ref_root;
u64 owner = generic_ref->data_ref.ino;
u64 offset = generic_ref->data_ref.offset;
u8 ref_type;
struct btrfs_data_ref {
/* For EXTENT_DATA_REF */
- /* Root which owns this data reference. */
- u64 ref_root;
-
/* Inode which refers to this data extent */
u64 ino;
*/
int level;
- /*
- * Root which owns this tree block reference.
- *
- * For TREE_BLOCK_REF (skinny metadata, either inline or keyed)
- */
- u64 ref_root;
-
/* For non-skinny metadata, no special member needed */
};
u64 len;
u64 owning_root;
+ /*
+ * The root that owns the reference for this reference, this will be set
+ * or ->parent will be set, depending on what type of reference this is.
+ */
+ u64 ref_root;
+
/* Bytenr of the parent tree block */
u64 parent;
union {
return btrfs_calc_metadata_size(fs_info, num_csum_items);
}
-void btrfs_init_tree_ref(struct btrfs_ref *generic_ref, int level, u64 root,
+void btrfs_init_tree_ref(struct btrfs_ref *generic_ref, int level, u64 mod_root,
+ bool skip_qgroup);
+void btrfs_init_data_ref(struct btrfs_ref *generic_ref, u64 ino, u64 offset,
u64 mod_root, bool skip_qgroup);
-void btrfs_init_data_ref(struct btrfs_ref *generic_ref, u64 ref_root, u64 ino,
- u64 offset, u64 mod_root, bool skip_qgroup);
static inline struct btrfs_delayed_extent_op *
btrfs_alloc_delayed_extent_op(void)
ASSERT(generic_ref->type != BTRFS_REF_NOT_SET &&
generic_ref->action);
BUG_ON(generic_ref->type == BTRFS_REF_METADATA &&
- generic_ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID);
+ generic_ref->ref_root == BTRFS_TREE_LOG_OBJECTID);
if (generic_ref->type == BTRFS_REF_METADATA)
ret = btrfs_add_delayed_tree_ref(trans, generic_ref, NULL);
struct btrfs_ref ref = {
.action = action,
.parent = parent,
+ .ref_root = ref_root,
};
if (level == 0) {
ref.owning_root = ref_root;
key.offset -= btrfs_file_extent_offset(buf, fi);
- btrfs_init_data_ref(&ref, ref_root, key.objectid,
- key.offset, root->root_key.objectid,
- for_reloc);
+ btrfs_init_data_ref(&ref, key.objectid, key.offset,
+ root->root_key.objectid, for_reloc);
if (inc)
ret = btrfs_inc_extent_ref(trans, &ref);
else
ref.bytenr = btrfs_node_blockptr(buf, i);
ref.len = fs_info->nodesize;
- btrfs_init_tree_ref(&ref, level - 1, ref_root,
+ btrfs_init_tree_ref(&ref, level - 1,
root->root_key.objectid, for_reloc);
if (inc)
ret = btrfs_inc_extent_ref(trans, &ref);
.len = buf->len,
.parent = parent,
.owning_root = btrfs_header_owner(buf),
+ .ref_root = root_id,
};
/*
*/
ASSERT(btrfs_header_bytenr(buf) != 0);
- btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf),
- root_id, 0, false);
+ btrfs_init_tree_ref(&generic_ref, btrfs_header_level(buf), 0, false);
btrfs_ref_tree_mod(fs_info, &generic_ref);
ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, NULL);
BUG_ON(ret); /* -ENOMEM */
* tree log blocks never actually go into the extent allocation
* tree, just update pinning info and exit early.
*/
- if ((ref->type == BTRFS_REF_METADATA &&
- ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID) ||
- (ref->type == BTRFS_REF_DATA &&
- ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)) {
+ if (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) {
ret = btrfs_add_delayed_data_ref(trans, ref, 0);
}
- if (!((ref->type == BTRFS_REF_METADATA &&
- ref->tree_ref.ref_root == BTRFS_TREE_LOG_OBJECTID) ||
- (ref->type == BTRFS_REF_DATA &&
- ref->data_ref.ref_root == BTRFS_TREE_LOG_OBJECTID)))
+ if (ref->ref_root != BTRFS_TREE_LOG_OBJECTID)
btrfs_ref_tree_mod(fs_info, ref);
return ret;
.bytenr = ins->objectid,
.len = ins->offset,
.owning_root = root->root_key.objectid,
+ .ref_root = root->root_key.objectid,
};
- u64 root_objectid = root->root_key.objectid;
- ASSERT(root_objectid != BTRFS_TREE_LOG_OBJECTID);
+ ASSERT(generic_ref.ref_root != BTRFS_TREE_LOG_OBJECTID);
if (btrfs_is_data_reloc_root(root) && is_fstree(root->relocation_src_root))
generic_ref.owning_root = root->relocation_src_root;
- btrfs_init_data_ref(&generic_ref, root_objectid, owner,
- offset, 0, false);
+ btrfs_init_data_ref(&generic_ref, owner, offset, 0, false);
btrfs_ref_tree_mod(root->fs_info, &generic_ref);
return btrfs_add_delayed_data_ref(trans, &generic_ref, ram_bytes);
.len = ins.offset,
.parent = parent,
.owning_root = owning_root,
+ .ref_root = root_objectid,
};
extent_op = btrfs_alloc_delayed_extent_op();
if (!extent_op) {
extent_op->update_flags = true;
extent_op->level = level;
- btrfs_init_tree_ref(&generic_ref, level, root_objectid,
+ btrfs_init_tree_ref(&generic_ref, level,
root->root_key.objectid, false);
btrfs_ref_tree_mod(fs_info, &generic_ref);
ret = btrfs_add_delayed_tree_ref(trans, &generic_ref, extent_op);
.bytenr = bytenr,
.len = fs_info->nodesize,
.owning_root = owner_root,
+ .ref_root = root->root_key.objectid,
};
if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
ref.parent = path->nodes[level]->start;
wc->drop_level = level;
find_next_key(path, level, &wc->drop_progress);
- btrfs_init_tree_ref(&ref, level - 1, root->root_key.objectid,
- 0, false);
+ btrfs_init_tree_ref(&ref, level - 1, 0, false);
ret = btrfs_free_extent(trans, &ref);
if (ret)
goto out_unlock;
.len = num_bytes,
.parent = 0,
.owning_root = root->root_key.objectid,
+ .ref_root = root->root_key.objectid,
};
- btrfs_init_data_ref(&ref,
- root->root_key.objectid,
- new_key.objectid,
- args->start - extent_offset,
- 0, false);
+ btrfs_init_data_ref(&ref, new_key.objectid,
+ args->start - extent_offset,
+ 0, false);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
.len = num_bytes,
.parent = 0,
.owning_root = root->root_key.objectid,
+ .ref_root = root->root_key.objectid,
};
- btrfs_init_data_ref(&ref,
- root->root_key.objectid,
- key.objectid,
- key.offset - extent_offset, 0,
- false);
+ btrfs_init_data_ref(&ref, key.objectid,
+ key.offset - extent_offset,
+ 0, false);
ret = btrfs_free_extent(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
ref.len = num_bytes;
ref.parent = 0;
ref.owning_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, root->root_key.objectid, ino,
- orig_offset, 0, false);
+ ref.ref_root = root->root_key.objectid;
+ btrfs_init_data_ref(&ref, ino, orig_offset, 0, false);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
ref.len = num_bytes;
ref.parent = 0;
ref.owning_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, root->root_key.objectid, ino, orig_offset,
- 0, false);
+ ref.ref_root = root->root_key.objectid;
+ btrfs_init_data_ref(&ref, ino, orig_offset, 0, false);
if (extent_mergeable(leaf, path->slots[0] + 1,
ino, bytenr, orig_offset,
&other_start, &other_end)) {
.bytenr = extent_info->disk_offset,
.len = extent_info->disk_len,
.owning_root = root->root_key.objectid,
+ .ref_root = root->root_key.objectid,
};
u64 ref_offset;
ref_offset = extent_info->file_offset - extent_info->data_offset;
- btrfs_init_data_ref(&ref, root->root_key.objectid,
- btrfs_ino(inode), ref_offset, 0, false);
+ btrfs_init_data_ref(&ref, btrfs_ino(inode), ref_offset, 0, false);
ret = btrfs_inc_extent_ref(trans, &ref);
}
.bytenr = extent_start,
.len = extent_num_bytes,
.owning_root = root->root_key.objectid,
+ .ref_root = btrfs_header_owner(leaf),
};
bytes_deleted += extent_num_bytes;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- control->ino, extent_offset,
- root->root_key.objectid, false);
+ btrfs_init_data_ref(&ref, control->ino, extent_offset,
+ root->root_key.objectid, false);
ret = btrfs_free_extent(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
if (generic_ref->type == BTRFS_REF_METADATA) {
if (!parent)
- ref_root = generic_ref->tree_ref.ref_root;
+ ref_root = generic_ref->ref_root;
owner = generic_ref->tree_ref.level;
} else if (!parent) {
- ref_root = generic_ref->data_ref.ref_root;
+ ref_root = generic_ref->ref_root;
owner = generic_ref->data_ref.ino;
offset = generic_ref->data_ref.offset;
}
ref.len = num_bytes;
ref.parent = parent;
ref.owning_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- key.objectid, key.offset,
+ ref.ref_root = btrfs_header_owner(leaf);
+ btrfs_init_data_ref(&ref, key.objectid, key.offset,
root->root_key.objectid, false);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret) {
ref.len = num_bytes;
ref.parent = parent;
ref.owning_root = root->root_key.objectid;
- btrfs_init_data_ref(&ref, btrfs_header_owner(leaf),
- key.objectid, key.offset,
+ ref.ref_root = btrfs_header_owner(leaf);
+ btrfs_init_data_ref(&ref, key.objectid, key.offset,
root->root_key.objectid, false);
ret = btrfs_free_extent(trans, &ref);
if (ret) {
ref.len = blocksize;
ref.parent = path->nodes[level]->start;
ref.owning_root = src->root_key.objectid;
- btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid,
- 0, true);
+ ref.ref_root = src->root_key.objectid;
+ btrfs_init_tree_ref(&ref, level - 1, 0, true);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
ref.len = blocksize;
ref.parent = 0;
ref.owning_root = dest->root_key.objectid;
- btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid, 0,
- true);
+ ref.ref_root = dest->root_key.objectid;
+ btrfs_init_tree_ref(&ref, level - 1, 0, true);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
ref.len = blocksize;
ref.parent = path->nodes[level]->start;
ref.owning_root = 0;
- btrfs_init_tree_ref(&ref, level - 1, src->root_key.objectid,
- 0, true);
+ ref.ref_root = src->root_key.objectid;
+ btrfs_init_tree_ref(&ref, level - 1, 0, true);
ret = btrfs_free_extent(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
ref.len = blocksize;
ref.parent = 0;
ref.owning_root = 0;
- btrfs_init_tree_ref(&ref, level - 1, dest->root_key.objectid,
- 0, true);
+ ref.ref_root = dest->root_key.objectid;
+ btrfs_init_tree_ref(&ref, level - 1, 0, true);
ret = btrfs_free_extent(trans, &ref);
if (ret) {
btrfs_abort_transaction(trans, ret);
.len = blocksize,
.parent = upper->eb->start,
.owning_root = btrfs_header_owner(upper->eb),
+ .ref_root = btrfs_header_owner(upper->eb),
};
btrfs_set_node_blockptr(upper->eb, slot,
btrfs_mark_buffer_dirty(trans, upper->eb);
btrfs_init_tree_ref(&ref, node->level,
- btrfs_header_owner(upper->eb),
root->root_key.objectid, false);
ret = btrfs_inc_extent_ref(trans, &ref);
if (!ret)
.bytenr = ins.objectid,
.len = ins.offset,
.owning_root = root->root_key.objectid,
+ .ref_root = root->root_key.objectid,
};
- btrfs_init_data_ref(&ref,
- root->root_key.objectid,
- key->objectid, offset, 0, false);
+ btrfs_init_data_ref(&ref, key->objectid, offset,
+ 0, false);
ret = btrfs_inc_extent_ref(trans, &ref);
if (ret)
goto out;