Message ID | 20240719150343.3992904-1-maharmstone@fb.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/2] btrfs-progs: add set_uuid param to btrfs_make_subvolume | expand |
On Fri, Jul 19, 2024 at 04:03:23PM +0100, Mark Harmstone wrote: > Adds a set_uuid parameter to btrfs_make_subvolume, which generates a > uuid for the new root and adds it to the uuid tree. > > Signed-off-by: Mark Harmstone <maharmstone@fb.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Thanks, Josef
在 2024/7/20 00:33, Mark Harmstone 写道: > Adds a set_uuid parameter to btrfs_make_subvolume, which generates a > uuid for the new root and adds it to the uuid tree. > > Signed-off-by: Mark Harmstone <maharmstone@fb.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Thanks, Qu > --- > common/root-tree-utils.c | 72 +++++++++++++++++++++++++++++++++++++++- > common/root-tree-utils.h | 5 ++- > convert/main.c | 5 +-- > mkfs/main.c | 59 ++------------------------------ > 4 files changed, 80 insertions(+), 61 deletions(-) > > diff --git a/common/root-tree-utils.c b/common/root-tree-utils.c > index 6a57c51a..f9343304 100644 > --- a/common/root-tree-utils.c > +++ b/common/root-tree-utils.c > @@ -15,6 +15,7 @@ > */ > > #include <time.h> > +#include <uuid/uuid.h> > #include "common/root-tree-utils.h" > #include "common/messages.h" > #include "kernel-shared/disk-io.h" > @@ -58,13 +59,70 @@ error: > return ret; > } > > +int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, > + u64 subvol_id_cpu) > +{ > + struct btrfs_fs_info *fs_info = trans->fs_info; > + struct btrfs_root *uuid_root = fs_info->uuid_root; > + int ret; > + struct btrfs_path *path = NULL; > + struct btrfs_key key; > + struct extent_buffer *eb; > + int slot; > + unsigned long offset; > + __le64 subvol_id_le; > + > + btrfs_uuid_to_key(uuid, type, &key); > + > + path = btrfs_alloc_path(); > + if (!path) { > + ret = -ENOMEM; > + goto out; > + } > + > + ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, sizeof(subvol_id_le)); > + if (ret < 0 && ret != -EEXIST) { > + warning( > + "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", > + key.objectid, key.offset, type, ret); > + goto out; > + } > + > + if (ret >= 0) { > + /* Add an item for the type for the first time. */ > + eb = path->nodes[0]; > + slot = path->slots[0]; > + offset = btrfs_item_ptr_offset(eb, slot); > + } else { > + /* > + * ret == -EEXIST case, an item with that type already exists. > + * Extend the item and store the new subvol_id at the end. > + */ > + btrfs_extend_item(path, sizeof(subvol_id_le)); > + eb = path->nodes[0]; > + slot = path->slots[0]; > + offset = btrfs_item_ptr_offset(eb, slot); > + offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); > + } > + > + ret = 0; > + subvol_id_le = cpu_to_le64(subvol_id_cpu); > + write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); > + btrfs_mark_buffer_dirty(eb); > + > +out: > + btrfs_free_path(path); > + return ret; > +} > + > /* > * Create a subvolume and initialize its content with the top inode. > * > * The created tree root would have its root_ref as 1. > * Thus for subvolumes caller needs to properly add ROOT_BACKREF items. > */ > -int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid) > +int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid, > + bool set_uuid) > { > struct btrfs_fs_info *fs_info = trans->fs_info; > struct btrfs_root *root; > @@ -96,6 +154,18 @@ int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid) > ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID); > if (ret < 0) > goto error; > + > + if (set_uuid) { > + uuid_generate(root->root_item.uuid); > + > + ret = btrfs_uuid_tree_add(trans, root->root_item.uuid, > + BTRFS_UUID_KEY_SUBVOL, objectid); > + if (ret < 0) { > + error("failed to add uuid entry"); > + goto error; > + } > + } > + > ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key, > &root->root_item); > if (ret < 0) > diff --git a/common/root-tree-utils.h b/common/root-tree-utils.h > index 0c4ece24..78731dd5 100644 > --- a/common/root-tree-utils.h > +++ b/common/root-tree-utils.h > @@ -21,10 +21,13 @@ > > int btrfs_make_root_dir(struct btrfs_trans_handle *trans, > struct btrfs_root *root, u64 objectid); > -int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid); > +int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid, > + bool set_uuid); > int btrfs_link_subvolume(struct btrfs_trans_handle *trans, > struct btrfs_root *parent_root, > u64 parent_dir, const char *name, > int namelen, struct btrfs_root *subvol); > +int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, > + u64 subvol_id_cpu); > > #endif > diff --git a/convert/main.c b/convert/main.c > index 078ef64e..c863ce91 100644 > --- a/convert/main.c > +++ b/convert/main.c > @@ -1022,13 +1022,14 @@ static int init_btrfs(struct btrfs_mkfs_config *cfg, struct btrfs_root *root, > BTRFS_FIRST_FREE_OBJECTID); > > /* subvol for fs image file */ > - ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID); > + ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID, false); > if (ret < 0) { > error("failed to create subvolume image root: %d", ret); > goto err; > } > /* subvol for data relocation tree */ > - ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID); > + ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID, > + false); > if (ret < 0) { > error("failed to create DATA_RELOC root: %d", ret); > goto err; > diff --git a/mkfs/main.c b/mkfs/main.c > index cf5cae45..0bdb414a 100644 > --- a/mkfs/main.c > +++ b/mkfs/main.c > @@ -735,62 +735,6 @@ static void update_chunk_allocation(struct btrfs_fs_info *fs_info, > } > } > > -static int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, > - u8 type, u64 subvol_id_cpu) > -{ > - struct btrfs_fs_info *fs_info = trans->fs_info; > - struct btrfs_root *uuid_root = fs_info->uuid_root; > - int ret; > - struct btrfs_path *path = NULL; > - struct btrfs_key key; > - struct extent_buffer *eb; > - int slot; > - unsigned long offset; > - __le64 subvol_id_le; > - > - btrfs_uuid_to_key(uuid, type, &key); > - > - path = btrfs_alloc_path(); > - if (!path) { > - ret = -ENOMEM; > - goto out; > - } > - > - ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, sizeof(subvol_id_le)); > - if (ret < 0 && ret != -EEXIST) { > - warning( > - "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", > - key.objectid, key.offset, type, ret); > - goto out; > - } > - > - if (ret >= 0) { > - /* Add an item for the type for the first time. */ > - eb = path->nodes[0]; > - slot = path->slots[0]; > - offset = btrfs_item_ptr_offset(eb, slot); > - } else { > - /* > - * ret == -EEXIST case, an item with that type already exists. > - * Extend the item and store the new subvol_id at the end. > - */ > - btrfs_extend_item(path, sizeof(subvol_id_le)); > - eb = path->nodes[0]; > - slot = path->slots[0]; > - offset = btrfs_item_ptr_offset(eb, slot); > - offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); > - } > - > - ret = 0; > - subvol_id_le = cpu_to_le64(subvol_id_cpu); > - write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); > - btrfs_mark_buffer_dirty(eb); > - > -out: > - btrfs_free_path(path); > - return ret; > -} > - > static int create_uuid_tree(struct btrfs_trans_handle *trans) > { > struct btrfs_fs_info *fs_info = trans->fs_info; > @@ -1871,7 +1815,8 @@ raid_groups: > goto out; > } > > - ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID); > + ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID, > + false); > if (ret) { > error("unable to create data reloc tree: %d", ret); > goto out;
diff --git a/common/root-tree-utils.c b/common/root-tree-utils.c index 6a57c51a..f9343304 100644 --- a/common/root-tree-utils.c +++ b/common/root-tree-utils.c @@ -15,6 +15,7 @@ */ #include <time.h> +#include <uuid/uuid.h> #include "common/root-tree-utils.h" #include "common/messages.h" #include "kernel-shared/disk-io.h" @@ -58,13 +59,70 @@ error: return ret; } +int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, + u64 subvol_id_cpu) +{ + struct btrfs_fs_info *fs_info = trans->fs_info; + struct btrfs_root *uuid_root = fs_info->uuid_root; + int ret; + struct btrfs_path *path = NULL; + struct btrfs_key key; + struct extent_buffer *eb; + int slot; + unsigned long offset; + __le64 subvol_id_le; + + btrfs_uuid_to_key(uuid, type, &key); + + path = btrfs_alloc_path(); + if (!path) { + ret = -ENOMEM; + goto out; + } + + ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, sizeof(subvol_id_le)); + if (ret < 0 && ret != -EEXIST) { + warning( + "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", + key.objectid, key.offset, type, ret); + goto out; + } + + if (ret >= 0) { + /* Add an item for the type for the first time. */ + eb = path->nodes[0]; + slot = path->slots[0]; + offset = btrfs_item_ptr_offset(eb, slot); + } else { + /* + * ret == -EEXIST case, an item with that type already exists. + * Extend the item and store the new subvol_id at the end. + */ + btrfs_extend_item(path, sizeof(subvol_id_le)); + eb = path->nodes[0]; + slot = path->slots[0]; + offset = btrfs_item_ptr_offset(eb, slot); + offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); + } + + ret = 0; + subvol_id_le = cpu_to_le64(subvol_id_cpu); + write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); + btrfs_mark_buffer_dirty(eb); + +out: + btrfs_free_path(path); + return ret; +} + /* * Create a subvolume and initialize its content with the top inode. * * The created tree root would have its root_ref as 1. * Thus for subvolumes caller needs to properly add ROOT_BACKREF items. */ -int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid) +int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid, + bool set_uuid) { struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_root *root; @@ -96,6 +154,18 @@ int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid) ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID); if (ret < 0) goto error; + + if (set_uuid) { + uuid_generate(root->root_item.uuid); + + ret = btrfs_uuid_tree_add(trans, root->root_item.uuid, + BTRFS_UUID_KEY_SUBVOL, objectid); + if (ret < 0) { + error("failed to add uuid entry"); + goto error; + } + } + ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key, &root->root_item); if (ret < 0) diff --git a/common/root-tree-utils.h b/common/root-tree-utils.h index 0c4ece24..78731dd5 100644 --- a/common/root-tree-utils.h +++ b/common/root-tree-utils.h @@ -21,10 +21,13 @@ int btrfs_make_root_dir(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 objectid); -int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid); +int btrfs_make_subvolume(struct btrfs_trans_handle *trans, u64 objectid, + bool set_uuid); int btrfs_link_subvolume(struct btrfs_trans_handle *trans, struct btrfs_root *parent_root, u64 parent_dir, const char *name, int namelen, struct btrfs_root *subvol); +int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, u8 type, + u64 subvol_id_cpu); #endif diff --git a/convert/main.c b/convert/main.c index 078ef64e..c863ce91 100644 --- a/convert/main.c +++ b/convert/main.c @@ -1022,13 +1022,14 @@ static int init_btrfs(struct btrfs_mkfs_config *cfg, struct btrfs_root *root, BTRFS_FIRST_FREE_OBJECTID); /* subvol for fs image file */ - ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID); + ret = btrfs_make_subvolume(trans, CONV_IMAGE_SUBVOL_OBJECTID, false); if (ret < 0) { error("failed to create subvolume image root: %d", ret); goto err; } /* subvol for data relocation tree */ - ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID); + ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID, + false); if (ret < 0) { error("failed to create DATA_RELOC root: %d", ret); goto err; diff --git a/mkfs/main.c b/mkfs/main.c index cf5cae45..0bdb414a 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -735,62 +735,6 @@ static void update_chunk_allocation(struct btrfs_fs_info *fs_info, } } -static int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, u8 *uuid, - u8 type, u64 subvol_id_cpu) -{ - struct btrfs_fs_info *fs_info = trans->fs_info; - struct btrfs_root *uuid_root = fs_info->uuid_root; - int ret; - struct btrfs_path *path = NULL; - struct btrfs_key key; - struct extent_buffer *eb; - int slot; - unsigned long offset; - __le64 subvol_id_le; - - btrfs_uuid_to_key(uuid, type, &key); - - path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } - - ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, sizeof(subvol_id_le)); - if (ret < 0 && ret != -EEXIST) { - warning( - "inserting uuid item failed (0x%016llx, 0x%016llx) type %u: %d", - key.objectid, key.offset, type, ret); - goto out; - } - - if (ret >= 0) { - /* Add an item for the type for the first time. */ - eb = path->nodes[0]; - slot = path->slots[0]; - offset = btrfs_item_ptr_offset(eb, slot); - } else { - /* - * ret == -EEXIST case, an item with that type already exists. - * Extend the item and store the new subvol_id at the end. - */ - btrfs_extend_item(path, sizeof(subvol_id_le)); - eb = path->nodes[0]; - slot = path->slots[0]; - offset = btrfs_item_ptr_offset(eb, slot); - offset += btrfs_item_size(eb, slot) - sizeof(subvol_id_le); - } - - ret = 0; - subvol_id_le = cpu_to_le64(subvol_id_cpu); - write_extent_buffer(eb, &subvol_id_le, offset, sizeof(subvol_id_le)); - btrfs_mark_buffer_dirty(eb); - -out: - btrfs_free_path(path); - return ret; -} - static int create_uuid_tree(struct btrfs_trans_handle *trans) { struct btrfs_fs_info *fs_info = trans->fs_info; @@ -1871,7 +1815,8 @@ raid_groups: goto out; } - ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID); + ret = btrfs_make_subvolume(trans, BTRFS_DATA_RELOC_TREE_OBJECTID, + false); if (ret) { error("unable to create data reloc tree: %d", ret); goto out;
Adds a set_uuid parameter to btrfs_make_subvolume, which generates a uuid for the new root and adds it to the uuid tree. Signed-off-by: Mark Harmstone <maharmstone@fb.com> --- common/root-tree-utils.c | 72 +++++++++++++++++++++++++++++++++++++++- common/root-tree-utils.h | 5 ++- convert/main.c | 5 +-- mkfs/main.c | 59 ++------------------------------ 4 files changed, 80 insertions(+), 61 deletions(-)