* [PATCH 00/15] btrfs-progs: initial snapshot_id support
@ 2022-03-07 22:17 Josef Bacik
2022-03-07 22:17 ` [PATCH 01/15] btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data Josef Bacik
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Hello,
This is the less complicated portion of the snapshot_id support. These patches
add the on-disk definitions to the btrfs_header and btrfs_root_item to keep
track of the snapshot_id. This series does not include the extent tree changes
that will be needed as well, as those will require a lot of changes as well.
The complicated part of this is we're growing the btrfs_header size, so we've
had to adjust all of the accessors to take into account the new math. This
passes xfstests with the btrfs-progs related patches. Currently nothing
actually messes with the snapshot_id, as this will be handled later when I
re-instate snapshot support for extent tree v2. Thanks,
Josef
Josef Bacik (15):
btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data
btrfs-progs: use item/node helpers instead of offsetof in ctree.c
btrfs-progs: image: use the appropriate offset helpers
btrfs-progs: mkfs: add a helper for temp buffer clearing
btrfs-progs: move the buffer init code to btrfs_alloc_free_block
btrfs-progs: fix item check to use the size helpers
btrfs-progs: add snapshot_id to the btrfs_header
btrfs-progs: make __BTRFS_LEAF_DATA_SIZE handle extent tree v2
btrfs-progs: adjust the leaf/node math for header_v2
btrfs-progs: setup the extent tree v2 header properly
btrfs-progs: add new roots to the dirty root list
btrfs-progs: delete the btrfs_create_root helper
btrfs-progs: add a snapshot_id to the btrfs_root_item
btrfs-progs: inherit the root snapshot id in the buffer
btrfs-progs: add new COW rules for extent tree v2
check/main.c | 14 ---
convert/main.c | 2 +-
image/main.c | 5 +-
kernel-shared/ctree.c | 166 +++-----------------------
kernel-shared/ctree.h | 199 +++++++++++++++++++-------------
kernel-shared/disk-io.c | 38 +++---
kernel-shared/extent-tree.c | 18 +++
kernel-shared/free-space-tree.c | 1 -
mkfs/common.c | 36 +++---
mkfs/main.c | 21 ++--
10 files changed, 207 insertions(+), 293 deletions(-)
--
2.26.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/15] btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 02/15] btrfs-progs: use item/node helpers instead of offsetof in ctree.c Josef Bacik
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
btrfs_leaf_data returns offsetof(struct btrfs_leaf, items), which is
equivalent to btrfs_item_nr_offset(leaf, 0). Change the helper to
simply call btrfs_item_nr_offset().
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 72c87485..f3343840 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2387,7 +2387,7 @@ BTRFS_SETGET_STACK_FUNCS(super_nr_global_roots, struct btrfs_super_block,
static inline unsigned long btrfs_leaf_data(struct extent_buffer *l)
{
- return offsetof(struct btrfs_leaf, items);
+ return btrfs_item_nr_offset(l, 0);
}
/* struct btrfs_file_extent_item */
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/15] btrfs-progs: use item/node helpers instead of offsetof in ctree.c
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
2022-03-07 22:17 ` [PATCH 01/15] btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 03/15] btrfs-progs: image: use the appropriate offset helpers Josef Bacik
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
In btrfs_bin_search we use offsetof(struct btrfs_*, items/ptrs) to tell
where to start searching for our keys. Instead use the appropriate
offset helpers to get this information.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 758a3882..8846836b 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -858,13 +858,13 @@ int btrfs_bin_search(struct extent_buffer *eb, const struct btrfs_key *key,
{
if (btrfs_header_level(eb) == 0)
return generic_bin_search(eb,
- offsetof(struct btrfs_leaf, items),
+ btrfs_item_nr_offset(eb, 0),
sizeof(struct btrfs_item),
key, btrfs_header_nritems(eb),
slot);
else
return generic_bin_search(eb,
- offsetof(struct btrfs_node, ptrs),
+ btrfs_node_key_ptr_offset(eb, 0),
sizeof(struct btrfs_key_ptr),
key, btrfs_header_nritems(eb),
slot);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/15] btrfs-progs: image: use the appropriate offset helpers
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
2022-03-07 22:17 ` [PATCH 01/15] btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data Josef Bacik
2022-03-07 22:17 ` [PATCH 02/15] btrfs-progs: use item/node helpers instead of offsetof in ctree.c Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 04/15] btrfs-progs: mkfs: add a helper for temp buffer clearing Josef Bacik
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We are using the size of the ondisk structures to figure out where we
need to zero out the buffers we're copying. Fix this by using the
appropriate helpers instead so that it's extent tree v2 compatible.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
image/main.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/image/main.c b/image/main.c
index c6af0cc2..600fc360 100644
--- a/image/main.c
+++ b/image/main.c
@@ -355,7 +355,7 @@ static void copy_buffer(struct metadump_struct *md, u8 *dst,
nritems = btrfs_header_nritems(src);
if (nritems == 0) {
- size = sizeof(struct btrfs_header);
+ size = btrfs_leaf_data(src);
memset(dst + size, 0, src->len - size);
} else if (level == 0) {
size = btrfs_leaf_data(src) +
@@ -364,8 +364,7 @@ static void copy_buffer(struct metadump_struct *md, u8 *dst,
memset(dst + btrfs_item_nr_offset(src, nritems), 0, size);
zero_items(md, dst, src);
} else {
- size = offsetof(struct btrfs_node, ptrs) +
- sizeof(struct btrfs_key_ptr) * nritems;
+ size = btrfs_node_key_ptr_offset(src, nritems);
memset(dst + size, 0, src->len - size);
}
csum_block(dst, src->len);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/15] btrfs-progs: mkfs: add a helper for temp buffer clearing
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (2 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 03/15] btrfs-progs: image: use the appropriate offset helpers Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 05/15] btrfs-progs: move the buffer init code to btrfs_alloc_free_block Josef Bacik
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We clear the temporary buffer every time we write a new block, and we
have this memset() code duplicated everywhere. Change this to a helper
and use the appropriate helper to figure out where the items start.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
mkfs/common.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/mkfs/common.c b/mkfs/common.c
index 2e13da17..652484f6 100644
--- a/mkfs/common.c
+++ b/mkfs/common.c
@@ -42,14 +42,22 @@ static u64 reference_root_table[] = {
[MKFS_BLOCK_GROUP_TREE] = BTRFS_BLOCK_GROUP_TREE_OBJECTID,
};
+static inline void clear_buffer_items(struct extent_buffer *buf,
+ struct btrfs_mkfs_config *cfg)
+{
+ unsigned long offset = btrfs_item_nr_offset(buf, 0);
+
+ memset_extent_buffer(buf, 0, offset, cfg->nodesize - offset);
+}
+
static int btrfs_write_empty_tree(int fd, struct btrfs_mkfs_config *cfg,
struct extent_buffer *buf, u64 objectid,
u64 block)
{
int ret;
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+
+ clear_buffer_items(buf, cfg);
btrfs_set_header_bytenr(buf, block);
btrfs_set_header_owner(buf, objectid);
btrfs_set_header_nritems(buf, 0);
@@ -76,8 +84,7 @@ static int btrfs_create_tree_root(int fd, struct btrfs_mkfs_config *cfg,
int i;
u8 uuid[BTRFS_UUID_SIZE];
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
memset(&root_item, 0, sizeof(root_item));
memset(&disk_key, 0, sizeof(disk_key));
@@ -153,8 +160,7 @@ static int create_free_space_tree(int fd, struct btrfs_mkfs_config *cfg,
int nritems = 0;
int ret;
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
itemoff -= sizeof(*info);
btrfs_set_disk_key_objectid(&disk_key, group_start);
@@ -215,8 +221,7 @@ static int create_block_group_tree(int fd, struct btrfs_mkfs_config *cfg,
{
int ret;
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
write_block_group_item(buf, 0, bg_offset, bg_size, bg_used, 0,
cfg->leaf_data_size -
sizeof(struct btrfs_block_group_item));
@@ -250,8 +255,7 @@ static int fill_extent_tree(int fd, struct btrfs_mkfs_config *cfg,
first_free &= ~((u64)cfg->sectorsize - 1);
/* create the items for the extent tree */
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
itemoff = cfg->leaf_data_size;
for (i = 0; i < blocks_nr; i++) {
blk = blocks[i];
@@ -486,8 +490,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
}
/* create the chunk tree */
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
nritems = 0;
item_size = sizeof(*dev_item);
itemoff = cfg->leaf_data_size - item_size;
@@ -575,8 +578,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
}
/* create the device tree */
- memset(buf->data + sizeof(struct btrfs_header), 0,
- cfg->nodesize - sizeof(struct btrfs_header));
+ clear_buffer_items(buf, cfg);
nritems = 0;
itemoff = cfg->leaf_data_size - sizeof(struct btrfs_dev_extent);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/15] btrfs-progs: move the buffer init code to btrfs_alloc_free_block
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (3 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 04/15] btrfs-progs: mkfs: add a helper for temp buffer clearing Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 06/15] btrfs-progs: fix item check to use the size helpers Josef Bacik
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We are copying this init code everywhere we call btrfs_alloc_free_block,
fix this by putting it inside the helper itself.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
check/main.c | 14 ----------
kernel-shared/ctree.c | 51 -------------------------------------
kernel-shared/disk-io.c | 10 --------
kernel-shared/extent-tree.c | 11 ++++++++
4 files changed, 11 insertions(+), 75 deletions(-)
diff --git a/check/main.c b/check/main.c
index c5ffd652..869acf67 100644
--- a/check/main.c
+++ b/check/main.c
@@ -9246,20 +9246,6 @@ static struct extent_buffer *btrfs_fsck_clear_root(
return c;
}
- memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header));
- btrfs_set_header_level(c, 0);
- btrfs_set_header_bytenr(c, c->start);
- btrfs_set_header_generation(c, trans->transid);
- btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(c, key->objectid);
-
- write_extent_buffer(c, gfs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
-
- write_extent_buffer(c, gfs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(c),
- BTRFS_UUID_SIZE);
-
btrfs_mark_buffer_dirty(c);
/*
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 8846836b..6a578a41 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -237,18 +237,6 @@ int btrfs_create_root(struct btrfs_trans_handle *trans,
}
new_root->node = node;
- memset_extent_buffer(node, 0, 0, sizeof(struct btrfs_header));
- btrfs_set_header_bytenr(node, node->start);
- btrfs_set_header_generation(node, trans->transid);
- btrfs_set_header_backref_rev(node, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(node, objectid);
- write_extent_buffer(node, fs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
- write_extent_buffer(node, fs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(node),
- BTRFS_UUID_SIZE);
- btrfs_set_header_nritems(node, 0);
- btrfs_set_header_level(node, 0);
ret = btrfs_inc_ref(trans, new_root, node, 0);
if (ret < 0)
goto free;
@@ -1751,23 +1739,9 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans,
if (IS_ERR(c))
return PTR_ERR(c);
- memset_extent_buffer(c, 0, 0, sizeof(struct btrfs_header));
btrfs_set_header_nritems(c, 1);
- btrfs_set_header_level(c, level);
- btrfs_set_header_bytenr(c, c->start);
- btrfs_set_header_generation(c, trans->transid);
- btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(c, root->root_key.objectid);
-
root_add_used(root, root->fs_info->nodesize);
- write_extent_buffer(c, root->fs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
-
- write_extent_buffer(c, root->fs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(c),
- BTRFS_UUID_SIZE);
-
btrfs_set_node_key(c, &lower_key, 0);
btrfs_set_node_blockptr(c, 0, lower->start);
lower_gen = btrfs_header_generation(lower);
@@ -1876,18 +1850,6 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
if (IS_ERR(split))
return PTR_ERR(split);
- memset_extent_buffer(split, 0, 0, sizeof(struct btrfs_header));
- btrfs_set_header_level(split, btrfs_header_level(c));
- btrfs_set_header_bytenr(split, split->start);
- btrfs_set_header_generation(split, trans->transid);
- btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(split, root->root_key.objectid);
- write_extent_buffer(split, root->fs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
- write_extent_buffer(split, root->fs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(split),
- BTRFS_UUID_SIZE);
-
root_add_used(root, root->fs_info->nodesize);
copy_extent_buffer(split, c,
@@ -2445,19 +2407,6 @@ again:
return PTR_ERR(right);
}
- memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
- btrfs_set_header_bytenr(right, right->start);
- btrfs_set_header_generation(right, trans->transid);
- btrfs_set_header_backref_rev(right, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(right, root->root_key.objectid);
- btrfs_set_header_level(right, 0);
- write_extent_buffer(right, root->fs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
-
- write_extent_buffer(right, root->fs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(right),
- BTRFS_UUID_SIZE);
-
root_add_used(root, root->fs_info->nodesize);
if (split == 0) {
diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index 35422d8c..e5ad2c82 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -2458,17 +2458,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
goto fail;
}
- memset_extent_buffer(leaf, 0, 0, sizeof(struct btrfs_header));
- btrfs_set_header_bytenr(leaf, leaf->start);
- btrfs_set_header_generation(leaf, trans->transid);
- btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV);
- btrfs_set_header_owner(leaf, root->root_key.objectid);
root->node = leaf;
- write_extent_buffer(leaf, fs_info->fs_devices->metadata_uuid,
- btrfs_header_fsid(), BTRFS_FSID_SIZE);
- write_extent_buffer(leaf, fs_info->chunk_tree_uuid,
- btrfs_header_chunk_tree_uuid(leaf),
- BTRFS_UUID_SIZE);
btrfs_mark_buffer_dirty(leaf);
extent_buffer_get(root->node);
diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c
index 933e8209..0361ec97 100644
--- a/kernel-shared/extent-tree.c
+++ b/kernel-shared/extent-tree.c
@@ -2588,6 +2588,17 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
}
btrfs_set_buffer_uptodate(buf);
trans->blocks_used++;
+ memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header));
+ btrfs_set_header_level(buf, level);
+ btrfs_set_header_bytenr(buf, buf->start);
+ btrfs_set_header_generation(buf, trans->transid);
+ btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV);
+ btrfs_set_header_owner(buf, root_objectid);
+ write_extent_buffer(buf, root->fs_info->fs_devices->metadata_uuid,
+ btrfs_header_fsid(), BTRFS_FSID_SIZE);
+ write_extent_buffer(buf, root->fs_info->chunk_tree_uuid,
+ btrfs_header_chunk_tree_uuid(buf),
+ BTRFS_UUID_SIZE);
return buf;
}
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/15] btrfs-progs: fix item check to use the size helpers
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (4 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 05/15] btrfs-progs: move the buffer init code to btrfs_alloc_free_block Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 07/15] btrfs-progs: add snapshot_id to the btrfs_header Josef Bacik
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Right now we're duplicating the math to figure out the maximum number of
items a leaf/node can hold for the sanity checks. Instead convert this
to use the appropriate helpers to that it does the correct thing with
extent tree v2.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/disk-io.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index e5ad2c82..bd316b46 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -45,14 +45,13 @@
#define BTRFS_BAD_NRITEMS (-4)
/* Calculate max possible nritems for a leaf/node */
-static u32 max_nritems(u8 level, u32 nodesize)
+static u32 max_nritems(struct btrfs_fs_info *fs_info, u8 level)
{
if (level == 0)
- return ((nodesize - sizeof(struct btrfs_header)) /
- sizeof(struct btrfs_item));
- return ((nodesize - sizeof(struct btrfs_header)) /
- sizeof(struct btrfs_key_ptr));
+ return BTRFS_LEAF_DATA_SIZE(fs_info) /
+ sizeof(struct btrfs_item);
+ return BTRFS_NODEPTRS_PER_BLOCK(fs_info);
}
static int check_tree_block(struct btrfs_fs_info *fs_info,
@@ -60,7 +59,6 @@ static int check_tree_block(struct btrfs_fs_info *fs_info,
{
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
- u32 nodesize = fs_info->nodesize;
bool fsid_match = false;
int ret = BTRFS_BAD_FSID;
@@ -68,8 +66,8 @@ static int check_tree_block(struct btrfs_fs_info *fs_info,
return BTRFS_BAD_BYTENR;
if (btrfs_header_level(buf) >= BTRFS_MAX_LEVEL)
return BTRFS_BAD_LEVEL;
- if (btrfs_header_nritems(buf) > max_nritems(btrfs_header_level(buf),
- nodesize))
+ if (btrfs_header_nritems(buf) > max_nritems(fs_info,
+ btrfs_header_level(buf)))
return BTRFS_BAD_NRITEMS;
/* Only leaf can be empty */
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/15] btrfs-progs: add snapshot_id to the btrfs_header
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (5 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 06/15] btrfs-progs: fix item check to use the size helpers Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 08/15] btrfs-progs: make __BTRFS_LEAF_DATA_SIZE handle extent tree v2 Josef Bacik
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Add a new btrfs_header_v2 which has the original header and an
additional snapshot_id field for tracking the snapshot the block was
created in.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.h | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index f3343840..7d4fd491 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -328,6 +328,7 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
#define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0)
#define BTRFS_HEADER_FLAG_RELOC (1ULL << 1)
+#define BTRFS_HEADER_FLAG_V2 (1ULL << 2)
#define BTRFS_SUPER_FLAG_SEEDING (1ULL << 32)
#define BTRFS_SUPER_FLAG_METADUMP (1ULL << 33)
#define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34)
@@ -361,6 +362,11 @@ struct btrfs_header {
u8 level;
} __attribute__ ((__packed__));
+struct btrfs_header_v2 {
+ struct btrfs_header header_v1;
+ __le64 snapshot_id;
+} __attribute__ ((__packed__));
+
static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize)
{
return nodesize - sizeof(struct btrfs_header);
@@ -1569,13 +1575,13 @@ static inline u32 BTRFS_MAX_XATTR_SIZE(const struct btrfs_fs_info *info)
#define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \
static inline u##bits btrfs_##name(const struct extent_buffer *eb) \
{ \
- const struct btrfs_header *h = (struct btrfs_header *)eb->data; \
+ const type *h = (type *)eb->data; \
return le##bits##_to_cpu(h->member); \
} \
static inline void btrfs_set_##name(struct extent_buffer *eb, \
u##bits val) \
{ \
- struct btrfs_header *h = (struct btrfs_header *)eb->data; \
+ type *h = (type *)eb->data; \
h->member = cpu_to_le##bits(val); \
}
@@ -2142,12 +2148,16 @@ BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64);
BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32);
BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64);
BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8);
+BTRFS_SETGET_HEADER_FUNCS(header_snapshot_id, struct btrfs_header_v2,
+ snapshot_id, 64);
BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64);
BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, nritems,
32);
BTRFS_SETGET_STACK_FUNCS(stack_header_owner, struct btrfs_header, owner, 64);
BTRFS_SETGET_STACK_FUNCS(stack_header_generation, struct btrfs_header,
generation, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_snapshot_id, struct btrfs_header_v2,
+ snapshot_id, 64);
static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag)
{
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/15] btrfs-progs: make __BTRFS_LEAF_DATA_SIZE handle extent tree v2
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (6 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 07/15] btrfs-progs: add snapshot_id to the btrfs_header Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 09/15] btrfs-progs: adjust the leaf/node math for header_v2 Josef Bacik
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Now that we have a larger header we need __BTRFS_LEAF_DATA_SIZE to take
this into account if we have extent tree v2 set. Add a bool to this
helper and adjust all of the callers.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
convert/main.c | 2 +-
kernel-shared/ctree.h | 4 +++-
kernel-shared/disk-io.c | 9 +++++++--
mkfs/main.c | 8 +++++---
4 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/convert/main.c b/convert/main.c
index b72d1e51..52afd7ed 100644
--- a/convert/main.c
+++ b/convert/main.c
@@ -1228,7 +1228,7 @@ static int do_convert(const char *devname, u32 convert_flags, u32 nodesize,
mkfs_cfg.sectorsize = blocksize;
mkfs_cfg.stripesize = blocksize;
mkfs_cfg.features = features;
- mkfs_cfg.leaf_data_size = __BTRFS_LEAF_DATA_SIZE(nodesize);
+ mkfs_cfg.leaf_data_size = __BTRFS_LEAF_DATA_SIZE(nodesize, false);
printf("Create initial btrfs filesystem\n");
ret = make_convert_btrfs(fd, &mkfs_cfg, &cctx);
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 7d4fd491..0ee5357a 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -367,8 +367,10 @@ struct btrfs_header_v2 {
__le64 snapshot_id;
} __attribute__ ((__packed__));
-static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize)
+static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize, bool v2)
{
+ if (v2)
+ return nodesize - sizeof(struct btrfs_header_v2);
return nodesize - sizeof(struct btrfs_header);
}
diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index bd316b46..3d99e7dd 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -1642,15 +1642,20 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, struct open_ctree_flags *oc
fs_info->stripesize = btrfs_super_stripesize(disk_super);
fs_info->csum_type = btrfs_super_csum_type(disk_super);
fs_info->csum_size = btrfs_super_csum_size(disk_super);
- fs_info->leaf_data_size = __BTRFS_LEAF_DATA_SIZE(fs_info->nodesize);
ret = btrfs_check_fs_compatibility(fs_info->super_copy, flags);
if (ret)
goto out_devices;
- if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+ fs_info->leaf_data_size =
+ __BTRFS_LEAF_DATA_SIZE(fs_info->nodesize, true);
fs_info->nr_global_roots =
btrfs_super_nr_global_roots(fs_info->super_copy);
+ } else {
+ fs_info->leaf_data_size =
+ __BTRFS_LEAF_DATA_SIZE(fs_info->nodesize, false);
+ }
/*
* fs_info->zone_size (and zoned) are not known before reading the
diff --git a/mkfs/main.c b/mkfs/main.c
index 17b3efc1..995b0223 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1025,6 +1025,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
enum btrfs_csum_type csum_type = BTRFS_CSUM_TYPE_CRC32;
u64 system_group_size;
int nr_global_roots = sysconf(_SC_NPROCESSORS_ONLN);
+ bool extent_tree_v2 = false;
crc32c_optimization_init();
btrfs_config_init();
@@ -1195,6 +1196,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
print_usage(1);
zoned = !!(features & BTRFS_FEATURE_INCOMPAT_ZONED);
+ extent_tree_v2 = !!(features & BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2);
if (source_dir_set && dev_cnt > 1) {
error("the option -r is limited to a single device");
@@ -1305,7 +1307,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
}
/* Extent tree v2 comes with a set of mandatory features. */
- if (features & BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) {
+ if (extent_tree_v2) {
features |= BTRFS_FEATURE_INCOMPAT_NO_HOLES;
runtime_features |= BTRFS_RUNTIME_FEATURE_FREE_SPACE_TREE;
@@ -1499,7 +1501,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
mkfs_cfg.features = features;
mkfs_cfg.runtime_features = runtime_features;
mkfs_cfg.csum_type = csum_type;
- mkfs_cfg.leaf_data_size = __BTRFS_LEAF_DATA_SIZE(nodesize);
+ mkfs_cfg.leaf_data_size = __BTRFS_LEAF_DATA_SIZE(nodesize, extent_tree_v2);
if (zoned)
mkfs_cfg.zone_size = zone_size(file);
else
@@ -1541,7 +1543,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv)
goto error;
}
- if (features & BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2) {
+ if (extent_tree_v2) {
ret = create_global_roots(trans, nr_global_roots);
if (ret) {
error("failed to create global roots: %d", ret);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/15] btrfs-progs: adjust the leaf/node math for header_v2
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (7 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 08/15] btrfs-progs: make __BTRFS_LEAF_DATA_SIZE handle extent tree v2 Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 10/15] btrfs-progs: setup the extent tree v2 header properly Josef Bacik
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
With extent tree v2 we have a slightly larger header in all metadata
blocks, so adjust the leaf and node related math to take into account
the new header.
I had to move the header SETGET funcs hence the churn.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.h | 174 +++++++++++++++++++++++-------------------
1 file changed, 96 insertions(+), 78 deletions(-)
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 0ee5357a..26a1db9a 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -590,6 +590,11 @@ struct btrfs_leaf {
struct btrfs_item items[];
} __attribute__ ((__packed__));
+struct btrfs_leaf_v2 {
+ struct btrfs_header_v2 header;
+ struct btrfs_item items[];
+} __attribute__ ((__packed__));
+
/*
* all non-leaf blocks are nodes, they hold only keys and pointers to
* other blocks
@@ -605,6 +610,11 @@ struct btrfs_node {
struct btrfs_key_ptr ptrs[];
} __attribute__ ((__packed__));
+struct btrfs_node_v2 {
+ struct btrfs_header_v2 header;
+ struct btrfs_key_ptr ptrs[];
+} __attribute__ ((__packed__));
+
/*
* btrfs_paths remember the path taken from the root down to the leaf.
* level 0 is always the leaf, and nodes[1...BTRFS_MAX_LEVEL] will point
@@ -1613,6 +1623,80 @@ static inline void btrfs_set_##name(type *s, u##bits val) \
s->member = cpu_to_le##bits(val); \
}
+/* struct btrfs_header */
+BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64);
+BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,
+ generation, 64);
+BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64);
+BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32);
+BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64);
+BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8);
+BTRFS_SETGET_HEADER_FUNCS(header_snapshot_id, struct btrfs_header_v2,
+ snapshot_id, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, nritems,
+ 32);
+BTRFS_SETGET_STACK_FUNCS(stack_header_owner, struct btrfs_header, owner, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_generation, struct btrfs_header,
+ generation, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_header_snapshot_id, struct btrfs_header_v2,
+ snapshot_id, 64);
+
+static inline int btrfs_header_flag(const struct extent_buffer *eb, u64 flag)
+{
+ return (btrfs_header_flags(eb) & flag) == flag;
+}
+
+static inline int btrfs_set_header_flag(struct extent_buffer *eb, u64 flag)
+{
+ u64 flags = btrfs_header_flags(eb);
+ btrfs_set_header_flags(eb, flags | flag);
+ return (flags & flag) == flag;
+}
+
+static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag)
+{
+ u64 flags = btrfs_header_flags(eb);
+ btrfs_set_header_flags(eb, flags & ~flag);
+ return (flags & flag) == flag;
+}
+
+static inline int btrfs_header_backref_rev(struct extent_buffer *eb)
+{
+ u64 flags = btrfs_header_flags(eb);
+ return flags >> BTRFS_BACKREF_REV_SHIFT;
+}
+
+static inline void btrfs_set_header_backref_rev(struct extent_buffer *eb,
+ int rev)
+{
+ u64 flags = btrfs_header_flags(eb);
+ flags &= ~BTRFS_BACKREF_REV_MASK;
+ flags |= (u64)rev << BTRFS_BACKREF_REV_SHIFT;
+ btrfs_set_header_flags(eb, flags);
+}
+
+static inline unsigned long btrfs_header_fsid(void)
+{
+ return offsetof(struct btrfs_header, fsid);
+}
+
+static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *eb)
+{
+ return offsetof(struct btrfs_header, chunk_tree_uuid);
+}
+
+static inline u8 *btrfs_header_csum(struct extent_buffer *eb)
+{
+ unsigned long ptr = offsetof(struct btrfs_header, csum);
+ return (u8 *)ptr;
+}
+
+static inline int btrfs_is_leaf(struct extent_buffer *eb)
+{
+ return (btrfs_header_level(eb) == 0);
+}
+
BTRFS_SETGET_FUNCS(device_type, struct btrfs_dev_item, type, 64);
BTRFS_SETGET_FUNCS(device_total_bytes, struct btrfs_dev_item, total_bytes, 64);
BTRFS_SETGET_FUNCS(device_bytes_used, struct btrfs_dev_item, bytes_used, 64);
@@ -1942,8 +2026,12 @@ BTRFS_SETGET_FUNCS(key_generation, struct btrfs_key_ptr, generation, 64);
static inline unsigned long btrfs_node_key_ptr_offset(const struct extent_buffer *eb, int nr)
{
- return offsetof(struct btrfs_node, ptrs) +
- sizeof(struct btrfs_key_ptr) * nr;
+ unsigned long offset;
+ if (btrfs_header_flag(eb, BTRFS_HEADER_FLAG_V2))
+ offset = offsetof(struct btrfs_node_v2, ptrs);
+ else
+ offset = offsetof(struct btrfs_node, ptrs);
+ return offset + sizeof(struct btrfs_key_ptr) * nr;
}
static inline struct btrfs_key_ptr *btrfs_node_key_ptr(const struct extent_buffer *eb, int nr)
@@ -1993,8 +2081,12 @@ BTRFS_SETGET_FUNCS(raw_item_size, struct btrfs_item, size, 32);
static inline unsigned long btrfs_item_nr_offset(const struct extent_buffer *eb, int nr)
{
- return offsetof(struct btrfs_leaf, items) +
- sizeof(struct btrfs_item) * nr;
+ unsigned long offset;
+ if (btrfs_header_flag(eb, BTRFS_HEADER_FLAG_V2))
+ offset = offsetof(struct btrfs_leaf_v2, items);
+ else
+ offset = offsetof(struct btrfs_leaf, items);
+ return offset + sizeof(struct btrfs_item) * nr;
}
static inline struct btrfs_item *btrfs_item_nr(const struct extent_buffer *eb, int nr)
@@ -2142,80 +2234,6 @@ static inline void btrfs_dir_item_key_to_cpu(struct extent_buffer *eb,
btrfs_disk_key_to_cpu(key, &disk_key);
}
-/* struct btrfs_header */
-BTRFS_SETGET_HEADER_FUNCS(header_bytenr, struct btrfs_header, bytenr, 64);
-BTRFS_SETGET_HEADER_FUNCS(header_generation, struct btrfs_header,
- generation, 64);
-BTRFS_SETGET_HEADER_FUNCS(header_owner, struct btrfs_header, owner, 64);
-BTRFS_SETGET_HEADER_FUNCS(header_nritems, struct btrfs_header, nritems, 32);
-BTRFS_SETGET_HEADER_FUNCS(header_flags, struct btrfs_header, flags, 64);
-BTRFS_SETGET_HEADER_FUNCS(header_level, struct btrfs_header, level, 8);
-BTRFS_SETGET_HEADER_FUNCS(header_snapshot_id, struct btrfs_header_v2,
- snapshot_id, 64);
-BTRFS_SETGET_STACK_FUNCS(stack_header_bytenr, struct btrfs_header, bytenr, 64);
-BTRFS_SETGET_STACK_FUNCS(stack_header_nritems, struct btrfs_header, nritems,
- 32);
-BTRFS_SETGET_STACK_FUNCS(stack_header_owner, struct btrfs_header, owner, 64);
-BTRFS_SETGET_STACK_FUNCS(stack_header_generation, struct btrfs_header,
- generation, 64);
-BTRFS_SETGET_STACK_FUNCS(stack_header_snapshot_id, struct btrfs_header_v2,
- snapshot_id, 64);
-
-static inline int btrfs_header_flag(struct extent_buffer *eb, u64 flag)
-{
- return (btrfs_header_flags(eb) & flag) == flag;
-}
-
-static inline int btrfs_set_header_flag(struct extent_buffer *eb, u64 flag)
-{
- u64 flags = btrfs_header_flags(eb);
- btrfs_set_header_flags(eb, flags | flag);
- return (flags & flag) == flag;
-}
-
-static inline int btrfs_clear_header_flag(struct extent_buffer *eb, u64 flag)
-{
- u64 flags = btrfs_header_flags(eb);
- btrfs_set_header_flags(eb, flags & ~flag);
- return (flags & flag) == flag;
-}
-
-static inline int btrfs_header_backref_rev(struct extent_buffer *eb)
-{
- u64 flags = btrfs_header_flags(eb);
- return flags >> BTRFS_BACKREF_REV_SHIFT;
-}
-
-static inline void btrfs_set_header_backref_rev(struct extent_buffer *eb,
- int rev)
-{
- u64 flags = btrfs_header_flags(eb);
- flags &= ~BTRFS_BACKREF_REV_MASK;
- flags |= (u64)rev << BTRFS_BACKREF_REV_SHIFT;
- btrfs_set_header_flags(eb, flags);
-}
-
-static inline unsigned long btrfs_header_fsid(void)
-{
- return offsetof(struct btrfs_header, fsid);
-}
-
-static inline unsigned long btrfs_header_chunk_tree_uuid(struct extent_buffer *eb)
-{
- return offsetof(struct btrfs_header, chunk_tree_uuid);
-}
-
-static inline u8 *btrfs_header_csum(struct extent_buffer *eb)
-{
- unsigned long ptr = offsetof(struct btrfs_header, csum);
- return (u8 *)ptr;
-}
-
-static inline int btrfs_is_leaf(struct extent_buffer *eb)
-{
- return (btrfs_header_level(eb) == 0);
-}
-
/* struct btrfs_root_item */
BTRFS_SETGET_FUNCS(disk_root_generation, struct btrfs_root_item,
generation, 64);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/15] btrfs-progs: setup the extent tree v2 header properly
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (8 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 09/15] btrfs-progs: adjust the leaf/node math for header_v2 Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 11/15] btrfs-progs: add new roots to the dirty root list Josef Bacik
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Now that all the helpers handle the larger header properly, set the
correct flag and snapshot_id for blocks if we have extent tree v2
enabled.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/extent-tree.c | 8 +++++++-
mkfs/common.c | 6 ++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c
index 0361ec97..8f8617b3 100644
--- a/kernel-shared/extent-tree.c
+++ b/kernel-shared/extent-tree.c
@@ -2588,7 +2588,13 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
}
btrfs_set_buffer_uptodate(buf);
trans->blocks_used++;
- memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header));
+ if (btrfs_fs_incompat(root->fs_info, EXTENT_TREE_V2)) {
+ memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header_v2));
+ btrfs_set_header_snapshot_id(buf, 0);
+ btrfs_set_header_flag(buf, BTRFS_HEADER_FLAG_V2);
+ } else {
+ memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header));
+ }
btrfs_set_header_level(buf, level);
btrfs_set_header_bytenr(buf, buf->start);
btrfs_set_header_generation(buf, trans->transid);
diff --git a/mkfs/common.c b/mkfs/common.c
index 652484f6..8c1c3073 100644
--- a/mkfs/common.c
+++ b/mkfs/common.c
@@ -460,6 +460,12 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
/* create the tree of root objects */
memset(buf->data, 0, cfg->nodesize);
buf->len = cfg->nodesize;
+
+ if (extent_tree_v2) {
+ btrfs_set_header_snapshot_id(buf, 0);
+ btrfs_set_header_flag(buf, BTRFS_HEADER_FLAG_V2);
+ }
+
btrfs_set_header_bytenr(buf, cfg->blocks[MKFS_ROOT_TREE]);
btrfs_set_header_generation(buf, 1);
btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV);
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/15] btrfs-progs: add new roots to the dirty root list
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (9 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 10/15] btrfs-progs: setup the extent tree v2 header properly Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 12/15] btrfs-progs: delete the btrfs_create_root helper Josef Bacik
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
We have a few places that create new roots and then add the root to the
dirty list. Since any root we create we need to make sure ends up on
the tree_root we can simply add this step to btrfs_create_tree().
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/disk-io.c | 2 ++
kernel-shared/free-space-tree.c | 1 -
mkfs/main.c | 1 -
3 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index 3d99e7dd..078ab0fb 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -2485,6 +2485,8 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
if (ret)
goto fail;
+ add_root_to_dirty_list(root);
+
return root;
fail:
diff --git a/kernel-shared/free-space-tree.c b/kernel-shared/free-space-tree.c
index 03eb0ed2..ec2f7915 100644
--- a/kernel-shared/free-space-tree.c
+++ b/kernel-shared/free-space-tree.c
@@ -1494,7 +1494,6 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
ret = btrfs_global_root_insert(fs_info, free_space_root);
if (ret)
goto abort;
- add_root_to_dirty_list(free_space_root);
do {
block_group = btrfs_lookup_first_block_group(fs_info, start);
diff --git a/mkfs/main.c b/mkfs/main.c
index 995b0223..7bdbe64d 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -798,7 +798,6 @@ static int create_uuid_tree(struct btrfs_trans_handle *trans)
goto out;
}
- add_root_to_dirty_list(root);
fs_info->uuid_root = root;
ret = btrfs_uuid_tree_add(trans, fs_info->fs_root->root_item.uuid,
BTRFS_UUID_KEY_SUBVOL,
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/15] btrfs-progs: delete the btrfs_create_root helper
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (10 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 11/15] btrfs-progs: add new roots to the dirty root list Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 13/15] btrfs-progs: add a snapshot_id to the btrfs_root_item Josef Bacik
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
The only user of this is mkfs to make the quota root, everybody else
uses btrfs_create_tree(). Fix mkfs to use the btrfs_create_tree()
helper and delete btrfs_create_root().
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.c | 98 -------------------------------------------
kernel-shared/ctree.h | 2 -
mkfs/main.c | 12 ++++--
3 files changed, 9 insertions(+), 103 deletions(-)
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index 6a578a41..c6ce82b0 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -198,104 +198,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
return 0;
}
-/*
- * Create a new tree root, with root objectid set to @objectid.
- *
- * NOTE: Doesn't support tree with non-zero offset, like data reloc tree.
- */
-int btrfs_create_root(struct btrfs_trans_handle *trans,
- struct btrfs_fs_info *fs_info, u64 objectid)
-{
- struct extent_buffer *node;
- struct btrfs_root *new_root;
- struct btrfs_disk_key disk_key;
- struct btrfs_key location;
- struct btrfs_root_item root_item = { 0 };
- int ret;
-
- new_root = malloc(sizeof(*new_root));
- if (!new_root)
- return -ENOMEM;
-
- btrfs_setup_root(new_root, fs_info, objectid);
- if (!is_fstree(objectid))
- new_root->track_dirty = 1;
- add_root_to_dirty_list(new_root);
-
- new_root->objectid = objectid;
- new_root->root_key.objectid = objectid;
- new_root->root_key.type = BTRFS_ROOT_ITEM_KEY;
- new_root->root_key.offset = 0;
-
- node = btrfs_alloc_free_block(trans, new_root, fs_info->nodesize,
- objectid, &disk_key, 0, 0, 0);
- if (IS_ERR(node)) {
- ret = PTR_ERR(node);
- error("failed to create root node for tree %llu: %d (%m)",
- objectid, ret);
- return ret;
- }
- new_root->node = node;
-
- ret = btrfs_inc_ref(trans, new_root, node, 0);
- if (ret < 0)
- goto free;
-
- /*
- * Special tree roots may need to modify pointers in @fs_info
- * Only quota is supported yet.
- */
- switch (objectid) {
- case BTRFS_QUOTA_TREE_OBJECTID:
- if (fs_info->quota_root) {
- error("quota root already exists");
- ret = -EEXIST;
- goto free;
- }
- fs_info->quota_root = new_root;
- fs_info->quota_enabled = 1;
- break;
- /*
- * Essential trees can't be created by this function, yet.
- * As we expect such skeleton exists, or a lot of functions like
- * btrfs_alloc_free_block() doesn't work at all
- */
- case BTRFS_ROOT_TREE_OBJECTID:
- case BTRFS_EXTENT_TREE_OBJECTID:
- case BTRFS_CHUNK_TREE_OBJECTID:
- case BTRFS_FS_TREE_OBJECTID:
- ret = -EEXIST;
- goto free;
- default:
- /* Subvolume trees don't need special handling */
- if (is_fstree(objectid))
- break;
- /* Other special trees are not supported yet */
- ret = -ENOTTY;
- goto free;
- }
- btrfs_mark_buffer_dirty(node);
- btrfs_set_root_bytenr(&root_item, btrfs_header_bytenr(node));
- btrfs_set_root_level(&root_item, 0);
- btrfs_set_root_generation(&root_item, trans->transid);
- btrfs_set_root_dirid(&root_item, 0);
- btrfs_set_root_refs(&root_item, 1);
- btrfs_set_root_used(&root_item, fs_info->nodesize);
- location.objectid = objectid;
- location.type = BTRFS_ROOT_ITEM_KEY;
- location.offset = 0;
-
- ret = btrfs_insert_root(trans, fs_info->tree_root, &location, &root_item);
- if (ret < 0)
- goto free;
- return ret;
-
-free:
- free_extent_buffer(node);
- free(new_root);
- return ret;
-}
-
/*
* check if the tree block can be shared by multiple trees
*/
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 26a1db9a..8c4f6ed6 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -2758,8 +2758,6 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_buffer *buf,
struct extent_buffer **cow_ret, u64 new_root_objectid);
-int btrfs_create_root(struct btrfs_trans_handle *trans,
- struct btrfs_fs_info *fs_info, u64 objectid);
int btrfs_extend_item(struct btrfs_root *root, struct btrfs_path *path,
u32 data_size);
int btrfs_truncate_item(struct btrfs_path *path, u32 new_size, int from_end);
diff --git a/mkfs/main.c b/mkfs/main.c
index 7bdbe64d..a2e6500e 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -918,12 +918,18 @@ static int setup_quota_root(struct btrfs_fs_info *fs_info)
error("failed to start transaction: %d (%m)", ret);
return ret;
}
- ret = btrfs_create_root(trans, fs_info, BTRFS_QUOTA_TREE_OBJECTID);
- if (ret < 0) {
+
+ key.objectid = BTRFS_QUOTA_TREE_OBJECTID;
+ key.type = BTRFS_ROOT_ITEM_KEY;
+ key.offset = 0;
+
+ quota_root = btrfs_create_tree(trans, fs_info, &key);
+ if (IS_ERR(quota_root)) {
+ ret = PTR_ERR(quota_root);
error("failed to create quota root: %d (%m)", ret);
goto fail;
}
- quota_root = fs_info->quota_root;
+ fs_info->quota_root = quota_root;
key.objectid = 0;
key.type = BTRFS_QGROUP_STATUS_KEY;
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 13/15] btrfs-progs: add a snapshot_id to the btrfs_root_item
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (11 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 12/15] btrfs-progs: delete the btrfs_create_root helper Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 14/15] btrfs-progs: inherit the root snapshot id in the buffer Josef Bacik
2022-03-07 22:17 ` [PATCH 15/15] btrfs-progs: add new COW rules for extent tree v2 Josef Bacik
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
This is going to be used to keep track of when a snapshot of this root
was taken last. Any time we are snapshotted we will increase this value
and set the new extent buffers to this snapshot_id.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.h | 11 ++++++++++-
kernel-shared/disk-io.c | 3 +++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 8c4f6ed6..f5b32264 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -859,7 +859,14 @@ struct btrfs_root_item {
* this root.
*/
__le64 global_tree_id;
- __le64 reserved[7]; /* for future */
+
+ /*
+ * Indicates the current snapshot id, every time we are snapshotted this
+ * is increased.
+ */
+ __le64 snapshot_id;
+
+ __le64 reserved[6]; /* for future */
} __attribute__ ((__packed__));
/*
@@ -2262,6 +2269,8 @@ BTRFS_SETGET_STACK_FUNCS(root_stransid, struct btrfs_root_item,
stransid, 64);
BTRFS_SETGET_STACK_FUNCS(root_rtransid, struct btrfs_root_item,
rtransid, 64);
+BTRFS_SETGET_STACK_FUNCS(root_snapshot_id, struct btrfs_root_item,
+ snapshot_id, 64);
static inline struct btrfs_timespec* btrfs_root_ctime(
struct btrfs_root_item *root_item)
diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c
index 078ab0fb..58831550 100644
--- a/kernel-shared/disk-io.c
+++ b/kernel-shared/disk-io.c
@@ -2480,6 +2480,9 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
memset(root->root_item.uuid, 0, BTRFS_UUID_SIZE);
root->root_item.drop_level = 0;
+ /* This is safe to do on both versions since we used a reserved area. */
+ btrfs_set_root_snapshot_id(&root->root_item, 0);
+
ret = btrfs_insert_root(trans, tree_root, &root->root_key,
&root->root_item);
if (ret)
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 14/15] btrfs-progs: inherit the root snapshot id in the buffer
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (12 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 13/15] btrfs-progs: add a snapshot_id to the btrfs_root_item Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
2022-03-07 22:17 ` [PATCH 15/15] btrfs-progs: add new COW rules for extent tree v2 Josef Bacik
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
Every extent buffer a root points to will inherit the current snapshot
id of the root. This will allow us to easily tie which extent buffers
are shared with which roots.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/extent-tree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel-shared/extent-tree.c b/kernel-shared/extent-tree.c
index 8f8617b3..e836c809 100644
--- a/kernel-shared/extent-tree.c
+++ b/kernel-shared/extent-tree.c
@@ -2590,7 +2590,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
trans->blocks_used++;
if (btrfs_fs_incompat(root->fs_info, EXTENT_TREE_V2)) {
memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header_v2));
- btrfs_set_header_snapshot_id(buf, 0);
+ btrfs_set_header_snapshot_id(buf,
+ btrfs_root_snapshot_id(&root->root_item));
btrfs_set_header_flag(buf, BTRFS_HEADER_FLAG_V2);
} else {
memset_extent_buffer(buf, 0, 0, sizeof(struct btrfs_header));
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 15/15] btrfs-progs: add new COW rules for extent tree v2
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
` (13 preceding siblings ...)
2022-03-07 22:17 ` [PATCH 14/15] btrfs-progs: inherit the root snapshot id in the buffer Josef Bacik
@ 2022-03-07 22:17 ` Josef Bacik
14 siblings, 0 replies; 16+ messages in thread
From: Josef Bacik @ 2022-03-07 22:17 UTC (permalink / raw)
To: linux-btrfs, kernel-team
All of the previous COW rules will apply, but with extent tree v2 we add
a new COW rule where we must COW if the snapshot id of the buffer is
less than the current snapshot id of the root. If the root's snapshot
id has been increased we know that the block is now shared by a new root
and we must cow this block.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
kernel-shared/ctree.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/kernel-shared/ctree.c b/kernel-shared/ctree.c
index c6ce82b0..215c33ce 100644
--- a/kernel-shared/ctree.c
+++ b/kernel-shared/ctree.c
@@ -390,6 +390,16 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans,
return 0;
}
+static inline bool should_cow_block_v2(struct btrfs_root *root,
+ struct extent_buffer *buf)
+{
+ if (btrfs_header_flag(buf, BTRFS_HEADER_FLAG_V2) &&
+ (btrfs_root_snapshot_id(&root->root_item) >
+ btrfs_header_snapshot_id(buf)))
+ return true;
+ return false;
+}
+
static inline int should_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_buffer *buf)
@@ -397,7 +407,8 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
if (btrfs_header_generation(buf) == trans->transid &&
!btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
!(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
- btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
+ btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
+ !should_cow_block_v2(root, buf))
return 0;
return 1;
}
--
2.26.3
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2022-03-07 22:18 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-07 22:17 [PATCH 00/15] btrfs-progs: initial snapshot_id support Josef Bacik
2022-03-07 22:17 ` [PATCH 01/15] btrfs-progs: use btrfs_item_nr_offset() in btrfs_leaf_data Josef Bacik
2022-03-07 22:17 ` [PATCH 02/15] btrfs-progs: use item/node helpers instead of offsetof in ctree.c Josef Bacik
2022-03-07 22:17 ` [PATCH 03/15] btrfs-progs: image: use the appropriate offset helpers Josef Bacik
2022-03-07 22:17 ` [PATCH 04/15] btrfs-progs: mkfs: add a helper for temp buffer clearing Josef Bacik
2022-03-07 22:17 ` [PATCH 05/15] btrfs-progs: move the buffer init code to btrfs_alloc_free_block Josef Bacik
2022-03-07 22:17 ` [PATCH 06/15] btrfs-progs: fix item check to use the size helpers Josef Bacik
2022-03-07 22:17 ` [PATCH 07/15] btrfs-progs: add snapshot_id to the btrfs_header Josef Bacik
2022-03-07 22:17 ` [PATCH 08/15] btrfs-progs: make __BTRFS_LEAF_DATA_SIZE handle extent tree v2 Josef Bacik
2022-03-07 22:17 ` [PATCH 09/15] btrfs-progs: adjust the leaf/node math for header_v2 Josef Bacik
2022-03-07 22:17 ` [PATCH 10/15] btrfs-progs: setup the extent tree v2 header properly Josef Bacik
2022-03-07 22:17 ` [PATCH 11/15] btrfs-progs: add new roots to the dirty root list Josef Bacik
2022-03-07 22:17 ` [PATCH 12/15] btrfs-progs: delete the btrfs_create_root helper Josef Bacik
2022-03-07 22:17 ` [PATCH 13/15] btrfs-progs: add a snapshot_id to the btrfs_root_item Josef Bacik
2022-03-07 22:17 ` [PATCH 14/15] btrfs-progs: inherit the root snapshot id in the buffer Josef Bacik
2022-03-07 22:17 ` [PATCH 15/15] btrfs-progs: add new COW rules for extent tree v2 Josef Bacik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox