From bbad3810abe8832ff865fa80a1397792ae06744ab92e33bd6380bf278a09955c Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 17 Jan 2019 14:35:40 +0000 Subject: [PATCH] Accepting request 666631 from home:nikbor:branches:filesystems - Implement fate#325871 * Added 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch * Added 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch * Added 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch * Added 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch * Added 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch OBS-URL: https://build.opensuse.org/request/show/666631 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=307 --- ...-Add-support-for-metadata_uuid-field.patch | 641 ++++++++++++++++++ ...stune-Add-support-for-changing-the-u.patch | 340 ++++++++++ ...ve-fsid-metdata_uuid-fields-from-fs_.patch | 252 +++++++ ...-progs-Remove-btrfs_fs_info-new_fsid.patch | 205 ++++++ ...ctly-pass-root-to-change_devices_uui.patch | 41 ++ btrfsprogs.changes | 10 + btrfsprogs.spec | 10 + 7 files changed, 1499 insertions(+) create mode 100644 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch create mode 100644 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch create mode 100644 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch create mode 100644 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch create mode 100644 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch diff --git a/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch b/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch new file mode 100644 index 0000000..9227210 --- /dev/null +++ b/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch @@ -0,0 +1,641 @@ +From c4aadd9af2d153a03cda59977ed9a7d5700d9eae Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Thu, 11 Oct 2018 18:03:59 +0300 +Subject: [PATCH 1/6] btrfs-progs: Add support for metadata_uuid field + +Add support for a new metadata_uuid field. This is just a preparatory +commit which switches all users of the fsid field for metdata comparison +purposes to utilize the new field. This more or less mirrors the +kernel patch, additionally: + + * Update 'btrfs inspect-internal dump-super' to account for the new + field. This involes introducing the 'metadata_uuid' line to the + output and updating the logic for comparing the fs uuid to the + dev_item uuid. + +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +--- + btrfstune.c | 3 ++ + check/main.c | 2 +- + chunk-recover.c | 16 +++++++++-- + cmds-filesystem.c | 2 ++ + cmds-inspect-dump-super.c | 22 ++++++++++++-- + convert/common.c | 2 ++ + ctree.c | 14 ++++----- + ctree.h | 8 ++++-- + disk-io.c | 60 ++++++++++++++++++++++++++++++++------- + free-space-tree.c | 3 +- + image/main.c | 25 ++++++++++------ + volumes.c | 34 +++++++++++++++++----- + volumes.h | 1 + + 13 files changed, 148 insertions(+), 44 deletions(-) + +diff --git a/btrfstune.c b/btrfstune.c +index 1e378ba1c2d7..ad70772b6962 100644 +--- a/btrfstune.c ++++ b/btrfstune.c +@@ -248,6 +248,9 @@ static int change_fsid_prepare(struct btrfs_fs_info *fs_info) + if (ret < 0) + return ret; + ++ /* Also need to change the metadatauuid of the fs info */ ++ memcpy(fs_info->metadata_uuid, fs_info->new_fsid, BTRFS_FSID_SIZE); ++ + /* also restore new chunk_tree_id into tree_root for restore */ + write_extent_buffer(tree_root->node, fs_info->new_chunk_tree_uuid, + btrfs_header_chunk_tree_uuid(tree_root->node), +diff --git a/check/main.c b/check/main.c +index db18827b2843..915be1b5afd2 100644 +--- a/check/main.c ++++ b/check/main.c +@@ -8424,7 +8424,7 @@ static int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans, + btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(c, root->root_key.objectid); + +- write_extent_buffer(c, root->fs_info->fsid, ++ write_extent_buffer(c, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + write_extent_buffer(c, root->fs_info->chunk_tree_uuid, +diff --git a/chunk-recover.c b/chunk-recover.c +index 1d30db51d8ed..31325bfc54e0 100644 +--- a/chunk-recover.c ++++ b/chunk-recover.c +@@ -759,7 +759,7 @@ static int scan_one_device(void *dev_scan_struct) + rc->nodesize) + break; + +- if (memcmp_extent_buffer(buf, rc->fs_devices->fsid, ++ if (memcmp_extent_buffer(buf, rc->fs_devices->metadata_uuid, + btrfs_header_fsid(), + BTRFS_FSID_SIZE)) { + bytenr += rc->sectorsize; +@@ -1155,7 +1155,7 @@ static int __rebuild_chunk_root(struct btrfs_trans_handle *trans, + btrfs_set_header_level(cow, 0); + btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(cow, BTRFS_CHUNK_TREE_OBJECTID); +- write_extent_buffer(cow, root->fs_info->fsid, ++ write_extent_buffer(cow, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + write_extent_buffer(cow, root->fs_info->chunk_tree_uuid, +@@ -1192,7 +1192,8 @@ static int __rebuild_device_items(struct btrfs_trans_handle *trans, + btrfs_set_stack_device_io_width(dev_item, dev->io_width); + btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); + memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); +- memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); ++ memcpy(dev_item->fsid, dev->fs_devices->metadata_uuid, ++ BTRFS_FSID_SIZE); + + ret = btrfs_insert_item(trans, root, &key, + dev_item, sizeof(*dev_item)); +@@ -1432,6 +1433,7 @@ open_ctree_with_broken_chunk(struct recover_control *rc) + struct btrfs_fs_info *fs_info; + struct btrfs_super_block *disk_super; + struct extent_buffer *eb; ++ u64 features; + int ret; + + fs_info = btrfs_new_fs_info(1, BTRFS_SUPER_INFO_OFFSET); +@@ -1464,6 +1466,14 @@ open_ctree_with_broken_chunk(struct recover_control *rc) + if (ret) + goto out_devices; + ++ features = btrfs_super_incompat_flags(disk_super); ++ ++ if (features & BTRFS_FEATURE_INCOMPAT_METADATA_UUID) ++ memcpy(fs_info->metadata_uuid, disk_super->metadata_uuid, ++ BTRFS_FSID_SIZE); ++ else ++ memcpy(fs_info->metadata_uuid, fs_info->fsid, BTRFS_FSID_SIZE); ++ + btrfs_setup_root(fs_info->chunk_root, fs_info, + BTRFS_CHUNK_TREE_OBJECTID); + +diff --git a/cmds-filesystem.c b/cmds-filesystem.c +index d1af21eeca6b..b8beec13f0e5 100644 +--- a/cmds-filesystem.c ++++ b/cmds-filesystem.c +@@ -173,6 +173,7 @@ static int match_search_item_kernel(u8 *fsid, char *mnt, char *label, + return 0; + } + ++/* Search for user visible uuid 'search' in registered filesystems */ + static int uuid_search(struct btrfs_fs_devices *fs_devices, const char *search) + { + char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; +@@ -498,6 +499,7 @@ static int copy_fs_devices(struct btrfs_fs_devices *dst, + int ret = 0; + + memcpy(dst->fsid, src->fsid, BTRFS_FSID_SIZE); ++ memcpy(dst->metadata_uuid, src->metadata_uuid, BTRFS_FSID_SIZE); + INIT_LIST_HEAD(&dst->devices); + dst->seed = NULL; + +diff --git a/cmds-inspect-dump-super.c b/cmds-inspect-dump-super.c +index e965267c5d96..97e9624db8d7 100644 +--- a/cmds-inspect-dump-super.c ++++ b/cmds-inspect-dump-super.c +@@ -228,7 +228,8 @@ static struct readable_flag_entry incompat_flags_array[] = { + DEF_INCOMPAT_FLAG_ENTRY(EXTENDED_IREF), + DEF_INCOMPAT_FLAG_ENTRY(RAID56), + DEF_INCOMPAT_FLAG_ENTRY(SKINNY_METADATA), +- DEF_INCOMPAT_FLAG_ENTRY(NO_HOLES) ++ DEF_INCOMPAT_FLAG_ENTRY(NO_HOLES), ++ DEF_INCOMPAT_FLAG_ENTRY(METADATA_UUID) + }; + static const int incompat_flags_num = sizeof(incompat_flags_array) / + sizeof(struct readable_flag_entry); +@@ -319,6 +320,10 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) + u8 *p; + u32 csum_size; + u16 csum_type; ++ bool metadata_uuid_present = (btrfs_super_incompat_flags(sb) & ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID); ++ int cmp_res = 0; ++ + + csum_type = btrfs_super_csum_type(sb); + csum_size = BTRFS_CSUM_SIZE; +@@ -365,6 +370,12 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) + + uuid_unparse(sb->fsid, buf); + printf("fsid\t\t\t%s\n", buf); ++ if (metadata_uuid_present) { ++ uuid_unparse(sb->metadata_uuid, buf); ++ printf("metadata_uuid\t\t%s\n", buf); ++ } else { ++ printf("metadata_uuid\t\t%s\n", buf); ++ } + + printf("label\t\t\t"); + s = sb->label; +@@ -424,9 +435,14 @@ static void dump_superblock(struct btrfs_super_block *sb, int full) + printf("dev_item.uuid\t\t%s\n", buf); + + uuid_unparse(sb->dev_item.fsid, buf); ++ if (metadata_uuid_present) { ++ cmp_res = !memcmp(sb->dev_item.fsid, sb->metadata_uuid, ++ BTRFS_FSID_SIZE); ++ } else { ++ cmp_res = !memcmp(sb->dev_item.fsid, sb->fsid, BTRFS_FSID_SIZE); ++ } + printf("dev_item.fsid\t\t%s %s\n", buf, +- !memcmp(sb->dev_item.fsid, sb->fsid, BTRFS_FSID_SIZE) ? +- "[match]" : "[DON'T MATCH]"); ++ cmp_res ? "[match]" : "[DON'T MATCH]"); + + printf("dev_item.type\t\t%llu\n", (unsigned long long) + btrfs_stack_device_type(&sb->dev_item)); +diff --git a/convert/common.c b/convert/common.c +index a9b240431928..04b5901900c0 100644 +--- a/convert/common.c ++++ b/convert/common.c +@@ -107,9 +107,11 @@ static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg, + ret = -EINVAL; + goto out; + } ++ uuid_copy(super->metadata_uuid, super->fsid); + } else { + uuid_generate(super->fsid); + uuid_unparse(super->fsid, cfg->fs_uuid); ++ uuid_copy(super->metadata_uuid, super->fsid); + } + uuid_generate(chunk_uuid); + uuid_unparse(chunk_uuid, cfg->chunk_uuid); +diff --git a/ctree.c b/ctree.c +index 295cd5ed46b6..548d6e2c1f62 100644 +--- a/ctree.c ++++ b/ctree.c +@@ -134,7 +134,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, + else + btrfs_set_header_owner(cow, new_root_objectid); + +- write_extent_buffer(cow, root->fs_info->fsid, ++ write_extent_buffer(cow, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + WARN_ON(btrfs_header_generation(buf) > trans->transid); +@@ -308,7 +308,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans, + else + btrfs_set_header_owner(cow, root->root_key.objectid); + +- write_extent_buffer(cow, root->fs_info->fsid, ++ write_extent_buffer(cow, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + WARN_ON(!(buf->flags & EXTENT_BAD_TRANSID) && +@@ -1532,7 +1532,7 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, + btrfs_node_key(lower, &lower_key, 0); + + c = btrfs_alloc_free_block(trans, root, root->fs_info->nodesize, +- root->root_key.objectid, &lower_key, ++ root->root_key.objectid, &lower_key, + level, root->node->start, 0); + + if (IS_ERR(c)) +@@ -1548,7 +1548,7 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, + + root_add_used(root, root->fs_info->nodesize); + +- write_extent_buffer(c, root->fs_info->fsid, ++ write_extent_buffer(c, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + write_extent_buffer(c, root->fs_info->chunk_tree_uuid, +@@ -1669,7 +1669,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root + 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->fsid, ++ write_extent_buffer(split, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + write_extent_buffer(split, root->fs_info->chunk_tree_uuid, + btrfs_header_chunk_tree_uuid(split), +@@ -2231,7 +2231,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, + } + } + } +- ++ + if (split == 0) + btrfs_cpu_key_to_disk(&disk_key, ins_key); + else +@@ -2251,7 +2251,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, + 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->fsid, ++ write_extent_buffer(right, root->fs_info->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + write_extent_buffer(right, root->fs_info->chunk_tree_uuid, +diff --git a/ctree.h b/ctree.h +index f9c49d6041c1..45ef02e7fb45 100644 +--- a/ctree.h ++++ b/ctree.h +@@ -454,8 +454,9 @@ struct btrfs_super_block { + __le64 cache_generation; + __le64 uuid_tree_generation; + ++ u8 metadata_uuid[BTRFS_FSID_SIZE]; + /* future expansion */ +- __le64 reserved[30]; ++ __le64 reserved[28]; + u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE]; + struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS]; + } __attribute__ ((__packed__)); +@@ -489,6 +490,7 @@ struct btrfs_super_block { + #define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7) + #define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8) + #define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9) ++#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID (1ULL << 10) + + #define BTRFS_FEATURE_COMPAT_SUPP 0ULL + +@@ -511,7 +513,8 @@ struct btrfs_super_block { + BTRFS_FEATURE_INCOMPAT_RAID56 | \ + BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \ + BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \ +- BTRFS_FEATURE_INCOMPAT_NO_HOLES) ++ BTRFS_FEATURE_INCOMPAT_NO_HOLES | \ ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID) + + /* + * A leaf is full of items. offset and size tell us where to find +@@ -1090,6 +1093,7 @@ struct btrfs_device; + struct btrfs_fs_devices; + struct btrfs_fs_info { + u8 fsid[BTRFS_FSID_SIZE]; ++ u8 metadata_uuid[BTRFS_FSID_SIZE]; + u8 *new_fsid; + u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; + u8 *new_chunk_tree_uuid; +diff --git a/disk-io.c b/disk-io.c +index 5fafa144c0d3..1e5fac89b127 100644 +--- a/disk-io.c ++++ b/disk-io.c +@@ -55,8 +55,9 @@ static int check_tree_block(struct btrfs_fs_info *fs_info, + struct extent_buffer *buf) + { + +- struct btrfs_fs_devices *fs_devices; ++ struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; + u32 nodesize = fs_info->nodesize; ++ bool fsid_match = false; + int ret = BTRFS_BAD_FSID; + + if (buf->start != btrfs_header_bytenr(buf)) +@@ -72,12 +73,26 @@ static int check_tree_block(struct btrfs_fs_info *fs_info, + btrfs_header_level(buf) != 0) + return BTRFS_BAD_NRITEMS; + +- fs_devices = fs_info->fs_devices; + while (fs_devices) { +- if (fs_info->ignore_fsid_mismatch || +- !memcmp_extent_buffer(buf, fs_devices->fsid, +- btrfs_header_fsid(), +- BTRFS_FSID_SIZE)) { ++ /* ++ * Checking the incompat flag is only valid for the current ++ * fs. For seed devices it's forbidden to have their uuid ++ * changed so reading ->fsid in this case is fine ++ */ ++ if (fs_devices == fs_info->fs_devices && ++ btrfs_fs_incompat(fs_info, METADATA_UUID)) ++ fsid_match = !memcmp_extent_buffer(buf, ++ fs_devices->metadata_uuid, ++ btrfs_header_fsid(), ++ BTRFS_FSID_SIZE); ++ else ++ fsid_match = !memcmp_extent_buffer(buf, ++ fs_devices->fsid, ++ btrfs_header_fsid(), ++ BTRFS_FSID_SIZE); ++ ++ ++ if (fs_info->ignore_fsid_mismatch || fsid_match) { + ret = 0; + break; + } +@@ -103,7 +118,7 @@ static void print_tree_block_error(struct btrfs_fs_info *fs_info, + read_extent_buffer(eb, buf, btrfs_header_fsid(), + BTRFS_UUID_SIZE); + uuid_unparse(buf, found_uuid); +- uuid_unparse(fs_info->fsid, fs_uuid); ++ uuid_unparse(fs_info->metadata_uuid, fs_uuid); + fprintf(stderr, "fsid mismatch, want=%s, have=%s\n", + fs_uuid, found_uuid); + break; +@@ -1170,6 +1185,12 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, + } + + memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE); ++ if (btrfs_fs_incompat(fs_info, METADATA_UUID)) { ++ memcpy(fs_info->metadata_uuid, disk_super->metadata_uuid, ++ BTRFS_FSID_SIZE); ++ } else { ++ memcpy(fs_info->metadata_uuid, fs_info->fsid, BTRFS_FSID_SIZE); ++ } + fs_info->sectorsize = btrfs_super_sectorsize(disk_super); + fs_info->nodesize = btrfs_super_nodesize(disk_super); + fs_info->stripesize = btrfs_super_stripesize(disk_super); +@@ -1290,6 +1311,7 @@ static int check_super(struct btrfs_super_block *sb, unsigned sbflags) + u32 crc; + u16 csum_type; + int csum_size; ++ u8 *metadata_uuid; + + if (btrfs_super_magic(sb) != BTRFS_MAGIC) { + if (btrfs_super_magic(sb) == BTRFS_MAGIC_TEMPORARY) { +@@ -1378,11 +1400,16 @@ static int check_super(struct btrfs_super_block *sb, unsigned sbflags) + goto error_out; + } + +- if (memcmp(sb->fsid, sb->dev_item.fsid, BTRFS_UUID_SIZE) != 0) { ++ if (btrfs_super_incompat_flags(sb) & BTRFS_FEATURE_INCOMPAT_METADATA_UUID) ++ metadata_uuid = sb->metadata_uuid; ++ else ++ metadata_uuid = sb->fsid; ++ ++ if (memcmp(metadata_uuid, sb->dev_item.fsid, BTRFS_FSID_SIZE) != 0) { + char fsid[BTRFS_UUID_UNPARSED_SIZE]; + char dev_fsid[BTRFS_UUID_UNPARSED_SIZE]; + +- uuid_unparse(sb->fsid, fsid); ++ uuid_unparse(sb->metadata_uuid, fsid); + uuid_unparse(sb->dev_item.fsid, dev_fsid); + if (sbflags & SBREAD_IGNORE_FSID_MISMATCH) { + warning("ignored: dev_item fsid mismatch: %s != %s", +@@ -1454,6 +1481,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, + unsigned sbflags) + { + u8 fsid[BTRFS_FSID_SIZE]; ++ u8 metadata_uuid[BTRFS_FSID_SIZE]; + int fsid_is_initialized = 0; + char tmp[BTRFS_SUPER_INFO_SIZE]; + struct btrfs_super_block *buf = (struct btrfs_super_block *)tmp; +@@ -1461,6 +1489,7 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, + int ret; + int max_super = sbflags & SBREAD_RECOVER ? BTRFS_SUPER_MIRROR_MAX : 1; + u64 transid = 0; ++ bool metadata_uuid_set = false; + u64 bytenr; + + if (sb_bytenr != BTRFS_SUPER_INFO_OFFSET) { +@@ -1505,9 +1534,18 @@ int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr, + continue; + + if (!fsid_is_initialized) { ++ if (btrfs_super_incompat_flags(buf) & ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID) { ++ metadata_uuid_set = true; ++ memcpy(metadata_uuid, buf->metadata_uuid, ++ sizeof(metadata_uuid)); ++ } + memcpy(fsid, buf->fsid, sizeof(fsid)); + fsid_is_initialized = 1; +- } else if (memcmp(fsid, buf->fsid, sizeof(fsid))) { ++ } else if (memcmp(fsid, buf->fsid, sizeof(fsid)) || ++ (metadata_uuid_set && memcmp(metadata_uuid, ++ buf->metadata_uuid, ++ sizeof(metadata_uuid)))) { + /* + * the superblocks (the original one and + * its backups) contain data of different +@@ -1608,7 +1646,7 @@ int write_all_supers(struct btrfs_fs_info *fs_info) + btrfs_set_stack_device_io_width(dev_item, dev->io_width); + btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); + memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); +- memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); ++ memcpy(dev_item->fsid, fs_info->metadata_uuid, BTRFS_FSID_SIZE); + + flags = btrfs_super_flags(sb); + btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); +diff --git a/free-space-tree.c b/free-space-tree.c +index 6ef57928f1a9..0a3305415657 100644 +--- a/free-space-tree.c ++++ b/free-space-tree.c +@@ -1453,7 +1453,8 @@ static struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, + btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(leaf, objectid); + root->node = leaf; +- write_extent_buffer(leaf, fs_info->fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); ++ write_extent_buffer(leaf, fs_info->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); +diff --git a/image/main.c b/image/main.c +index 343dea7833de..4654c31256d6 100644 +--- a/image/main.c ++++ b/image/main.c +@@ -1404,7 +1404,7 @@ static void *restore_worker(void *data) + list_del_init(&async->list); + + if (mdres->compress_method == COMPRESS_ZLIB) { +- size = compress_size; ++ size = compress_size; + pthread_mutex_unlock(&mdres->mutex); + ret = uncompress(buffer, (unsigned long *)&size, + async->buffer, async->bufsize); +@@ -1596,9 +1596,12 @@ static int fill_mdres_info(struct mdrestore_struct *mdres, + + super = (struct btrfs_super_block *)outbuf; + mdres->nodesize = btrfs_super_nodesize(super); +- memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE); +- memcpy(mdres->uuid, super->dev_item.uuid, +- BTRFS_UUID_SIZE); ++ if (btrfs_super_incompat_flags(super) & ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID) ++ memcpy(mdres->fsid, super->metadata_uuid, BTRFS_FSID_SIZE); ++ else ++ memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE); ++ memcpy(mdres->uuid, super->dev_item.uuid, BTRFS_UUID_SIZE); + mdres->devid = le64_to_cpu(super->dev_item.devid); + free(buffer); + return 0; +@@ -1725,7 +1728,7 @@ static int read_chunk_block(struct mdrestore_struct *mdres, u8 *buffer, + + if (memcmp(mdres->fsid, eb->data + offsetof(struct btrfs_header, fsid), + BTRFS_FSID_SIZE)) { +- error("filesystem UUID of eb %llu does not match", ++ error("filesystem metadata UUID of eb %llu does not match", + (unsigned long long)bytenr); + ret = -EIO; + goto out; +@@ -2039,9 +2042,13 @@ static int build_chunk_tree(struct mdrestore_struct *mdres, + super = (struct btrfs_super_block *)buffer; + chunk_root_bytenr = btrfs_super_chunk_root(super); + mdres->nodesize = btrfs_super_nodesize(super); +- memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE); +- memcpy(mdres->uuid, super->dev_item.uuid, +- BTRFS_UUID_SIZE); ++ if (btrfs_super_incompat_flags(super) & ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID) ++ memcpy(mdres->fsid, super->metadata_uuid, BTRFS_FSID_SIZE); ++ else ++ memcpy(mdres->fsid, super->fsid, BTRFS_FSID_SIZE); ++ ++ memcpy(mdres->uuid, super->dev_item.uuid, BTRFS_UUID_SIZE); + mdres->devid = le64_to_cpu(super->dev_item.devid); + free(buffer); + pthread_mutex_unlock(&mdres->mutex); +@@ -2492,7 +2499,7 @@ static int update_disk_super_on_device(struct btrfs_fs_info *info, + key.offset = cur_devid; + + btrfs_init_path(&path); +- ret = btrfs_search_slot(NULL, info->chunk_root, &key, &path, 0, 0); ++ ret = btrfs_search_slot(NULL, info->chunk_root, &key, &path, 0, 0); + if (ret) { + error("search key failed: %d", ret); + ret = -EIO; +diff --git a/volumes.c b/volumes.c +index 0dd082cd1718..6ef871637d7a 100644 +--- a/volumes.c ++++ b/volumes.c +@@ -142,13 +142,19 @@ static struct btrfs_device *find_device(struct btrfs_fs_devices *fs_devices, + return NULL; + } + +-static struct btrfs_fs_devices *find_fsid(u8 *fsid) ++static struct btrfs_fs_devices *find_fsid(u8 *fsid, u8 *metadata_uuid) + { + struct btrfs_fs_devices *fs_devices; + + list_for_each_entry(fs_devices, &fs_uuids, list) { +- if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0) ++ if (metadata_uuid && (memcmp(fsid, fs_devices->fsid, ++ BTRFS_FSID_SIZE) == 0) && ++ (memcmp(metadata_uuid, fs_devices->metadata_uuid, ++ BTRFS_FSID_SIZE) == 0)) { + return fs_devices; ++ } else if (memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE) == 0){ ++ return fs_devices; ++ } + } + return NULL; + } +@@ -160,8 +166,15 @@ static int device_list_add(const char *path, + struct btrfs_device *device; + struct btrfs_fs_devices *fs_devices; + u64 found_transid = btrfs_super_generation(disk_super); ++ bool metadata_uuid = (btrfs_super_incompat_flags(disk_super) & ++ BTRFS_FEATURE_INCOMPAT_METADATA_UUID); ++ ++ if (metadata_uuid) ++ fs_devices = find_fsid(disk_super->fsid, ++ disk_super->metadata_uuid); ++ else ++ fs_devices = find_fsid(disk_super->fsid, NULL); + +- fs_devices = find_fsid(disk_super->fsid); + if (!fs_devices) { + fs_devices = kzalloc(sizeof(*fs_devices), GFP_NOFS); + if (!fs_devices) +@@ -169,6 +182,13 @@ static int device_list_add(const char *path, + INIT_LIST_HEAD(&fs_devices->devices); + list_add(&fs_devices->list, &fs_uuids); + memcpy(fs_devices->fsid, disk_super->fsid, BTRFS_FSID_SIZE); ++ if (metadata_uuid) ++ memcpy(fs_devices->metadata_uuid, ++ disk_super->metadata_uuid, BTRFS_FSID_SIZE); ++ else ++ memcpy(fs_devices->metadata_uuid, fs_devices->fsid, ++ BTRFS_FSID_SIZE); ++ + fs_devices->latest_devid = devid; + fs_devices->latest_trans = found_transid; + fs_devices->lowest_devid = (u64)-1; +@@ -721,7 +741,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans, + ptr = (unsigned long)btrfs_device_uuid(dev_item); + write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); + ptr = (unsigned long)btrfs_device_fsid(dev_item); +- write_extent_buffer(leaf, fs_info->fsid, ptr, BTRFS_UUID_SIZE); ++ write_extent_buffer(leaf, fs_info->metadata_uuid, ptr, BTRFS_UUID_SIZE); + btrfs_mark_buffer_dirty(leaf); + ret = 0; + +@@ -1698,7 +1718,7 @@ struct btrfs_device *btrfs_find_device(struct btrfs_fs_info *fs_info, u64 devid, + cur_devices = fs_info->fs_devices; + while (cur_devices) { + if (!fsid || +- (!memcmp(cur_devices->fsid, fsid, BTRFS_UUID_SIZE) || ++ (!memcmp(cur_devices->metadata_uuid, fsid, BTRFS_FSID_SIZE) || + fs_info->ignore_fsid_mismatch)) { + device = find_device(cur_devices, devid, uuid); + if (device) +@@ -1980,7 +2000,7 @@ static int open_seed_devices(struct btrfs_fs_info *fs_info, u8 *fsid) + fs_devices = fs_devices->seed; + } + +- fs_devices = find_fsid(fsid); ++ fs_devices = find_fsid(fsid, NULL); + if (!fs_devices) { + /* missing all seed devices */ + fs_devices = kzalloc(sizeof(*fs_devices), GFP_NOFS); +@@ -2019,7 +2039,7 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, + BTRFS_UUID_SIZE); + read_extent_buffer(leaf, fs_uuid, + (unsigned long)btrfs_device_fsid(dev_item), +- BTRFS_UUID_SIZE); ++ BTRFS_FSID_SIZE); + + if (memcmp(fs_uuid, fs_info->fsid, BTRFS_UUID_SIZE)) { + ret = open_seed_devices(fs_info, fs_uuid); +diff --git a/volumes.h b/volumes.h +index 44284ee75adb..e30bcef7dba5 100644 +--- a/volumes.h ++++ b/volumes.h +@@ -71,6 +71,7 @@ struct btrfs_device { + + struct btrfs_fs_devices { + u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ ++ u8 metadata_uuid[BTRFS_FSID_SIZE]; /* FS specific uuid */ + + /* the device with this id has the most recent copy of the super */ + u64 latest_devid; +-- +2.17.1 + diff --git a/0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch b/0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch new file mode 100644 index 0000000..b995fef --- /dev/null +++ b/0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch @@ -0,0 +1,340 @@ +From 9afa70a4087f42c529cc93253d7144f220f007f3 Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Thu, 11 Oct 2018 18:04:00 +0300 +Subject: [PATCH 2/6] btrfs-progs: btrfstune: Add support for changing the user + uuid + +This allows us to change the use-visible UUID on filesytems from +userspace if desired, by copying the existing UUID to the new location +for metadata comparisons. If this is done, an incompat flag must be +set to prevent older filesystems from mounting the filesystem, but +the original UUID can be restored, and the incompat flag removed. + +This introduces the new -m|-M UUID options similar to current +-u|-U UUID ones with the difference that we don't rewrite the fsid but +just copy the old uuid and set a new one. Additionally running with +[-M old-uuid] clears the incompat flag and retains only fsid on-disk. + +Additionally it's not allowed to intermix -m/-u/-U/-M options in a +single invocation of btrfstune, nor is it allowed to change the uuid +while there is a uuid rewrite in-progress. Also changing the uuid of a +seed device is not currently allowed (can change in the future). + +Example: + +btrfstune -m /dev/loop1 +btrfs inspect-internal dump-super /dev/loop1 + +superblock: bytenr=65536, device=/dev/loop1 +--------------------------------------------------------- +csum_type 0 (crc32c) +csum_size 4 +csum 0x4b7ea749 [match] + + + +fsid 0efc41d3-4451-49f3-8108-7b8bdbcf5ae8 +metadata_uuid 352715e7-62cf-4ae0-92ee-85a574adc318 + + + +incompat_flags 0x541 + ( MIXED_BACKREF | + EXTENDED_IREF | + SKINNY_METADATA | + METADATA_UUID ) + + + +dev_item.uuid 0610deee-dfc3-498b-9449-a06533cdec98 +dev_item.fsid 352715e7-62cf-4ae0-92ee-85a574adc318 [match] + + + +mount /dev/loop1 btrfs-mnt/ +btrfs fi show btrfs-mnt/ + +Label: none uuid: 0efc41d3-4451-49f3-8108-7b8bdbcf5ae8 + Total devices 1 FS bytes used 128.00KiB + devid 1 size 5.00GiB used 536.00MiB path /dev/loop1 + +In this case a new btrfs filesystem was created and the original uuid +was 352715e7-62cf-4ae0-92ee-85a574adc318, then btrfstune was run which +copied that value over to metadata_uuid field and set the current fsid +to 0efc41d3-4451-49f3-8108-7b8bdbcf5ae8. And as far as userspace is +concerned this is the fsid of the fs. + +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +--- + btrfstune.c | 185 +++++++++++++++++++++++++++++++++++++++++++++------- + ctree.h | 1 + + 2 files changed, 161 insertions(+), 25 deletions(-) + +diff --git a/btrfstune.c b/btrfstune.c +index ad70772b6962..b6ce201155f7 100644 +--- a/btrfstune.c ++++ b/btrfstune.c +@@ -73,6 +73,116 @@ static int update_seeding_flag(struct btrfs_root *root, int set_flag) + return ret; + } + ++/* ++ * Return 0 for no unfinished fsid change. ++ * Return >0 for unfinished fsid change, and restore unfinished fsid/ ++ * chunk_tree_id into fsid_ret/chunk_id_ret. ++ */ ++static int check_unfinished_fsid_change(struct btrfs_fs_info *fs_info, ++ uuid_t fsid_ret, uuid_t chunk_id_ret) ++{ ++ struct btrfs_root *tree_root = fs_info->tree_root; ++ u64 flags = btrfs_super_flags(fs_info->super_copy); ++ ++ if (flags & (BTRFS_SUPER_FLAG_CHANGING_FSID | ++ BTRFS_SUPER_FLAG_CHANGING_FSID_V2)) { ++ memcpy(fsid_ret, fs_info->super_copy->fsid, BTRFS_FSID_SIZE); ++ read_extent_buffer(tree_root->node, chunk_id_ret, ++ btrfs_header_chunk_tree_uuid(tree_root->node), ++ BTRFS_UUID_SIZE); ++ return 1; ++ } ++ return 0; ++} ++ ++static int set_metadata_uuid(struct btrfs_root *root, const char *uuid_string) ++{ ++ struct btrfs_super_block *disk_super; ++ uuid_t new_fsid, unused1, unused2; ++ struct btrfs_trans_handle *trans; ++ bool new_uuid = true; ++ u64 incompat_flags; ++ bool uuid_changed; ++ u64 super_flags; ++ int ret; ++ ++ disk_super = root->fs_info->super_copy; ++ super_flags = btrfs_super_flags(disk_super); ++ incompat_flags = btrfs_super_incompat_flags(disk_super); ++ uuid_changed = incompat_flags & BTRFS_FEATURE_INCOMPAT_METADATA_UUID; ++ ++ if (super_flags & BTRFS_SUPER_FLAG_SEEDING) { ++ fprintf(stderr, "Cannot set metadata UUID on a seed device\n"); ++ return 1; ++ } ++ ++ if (check_unfinished_fsid_change(root->fs_info, unused1, unused2)) { ++ fprintf(stderr, "UUID rewrite in progress, cannot change " ++ "fsid\n"); ++ return 1; ++ } ++ ++ if (uuid_string) ++ uuid_parse(uuid_string, new_fsid); ++ else ++ uuid_generate(new_fsid); ++ ++ new_uuid = (memcmp(new_fsid, disk_super->fsid, BTRFS_FSID_SIZE) != 0); ++ ++ /* Step 1 sets the in progress flag */ ++ trans = btrfs_start_transaction(root, 1); ++ super_flags |= BTRFS_SUPER_FLAG_CHANGING_FSID_V2; ++ btrfs_set_super_flags(disk_super, super_flags); ++ ret = btrfs_commit_transaction(trans, root); ++ if (ret < 0) ++ return ret; ++ ++ if (new_uuid && uuid_changed && memcmp(disk_super->metadata_uuid, ++ new_fsid, BTRFS_FSID_SIZE) == 0) { ++ /* ++ * Changing fsid to be the same as metadata uuid, so just ++ * disable the flag ++ */ ++ memcpy(disk_super->fsid, &new_fsid, BTRFS_FSID_SIZE); ++ incompat_flags &= ~BTRFS_FEATURE_INCOMPAT_METADATA_UUID; ++ btrfs_set_super_incompat_flags(disk_super, incompat_flags); ++ memset(disk_super->metadata_uuid, 0, BTRFS_FSID_SIZE); ++ } else if (new_uuid && uuid_changed && memcmp(disk_super->metadata_uuid, ++ new_fsid, BTRFS_FSID_SIZE)) { ++ /* ++ * Changing fsid on an already changed FS, in this case we ++ * only change the fsid and don't touch metadata uuid as it ++ * has already the correct value ++ */ ++ memcpy(disk_super->fsid, &new_fsid, BTRFS_FSID_SIZE); ++ } else if (new_uuid && !uuid_changed) { ++ /* ++ * First time changing the fsid, copy the fsid to metadata_uuid ++ */ ++ incompat_flags |= BTRFS_FEATURE_INCOMPAT_METADATA_UUID; ++ btrfs_set_super_incompat_flags(disk_super, incompat_flags); ++ memcpy(disk_super->metadata_uuid, disk_super->fsid, ++ BTRFS_FSID_SIZE); ++ memcpy(disk_super->fsid, &new_fsid, BTRFS_FSID_SIZE); ++ } else { ++ /* Setting the same fsid as current, do nothing */ ++ return 0; ++ } ++ ++ trans = btrfs_start_transaction(root, 1); ++ ++ /* ++ * Step 2 is to write the metadata_uuid, set the incompat flag and ++ * clear the in progress flag ++ */ ++ super_flags &= ~BTRFS_SUPER_FLAG_CHANGING_FSID_V2; ++ btrfs_set_super_flags(disk_super, super_flags); ++ ++ /* Then actually copy the metadata uuid and set the incompat bit */ ++ ++ return btrfs_commit_transaction(trans, root); ++} ++ + static int set_super_incompat_flags(struct btrfs_root *root, u64 flags) + { + struct btrfs_trans_handle *trans; +@@ -268,26 +378,6 @@ static int change_fsid_done(struct btrfs_fs_info *fs_info) + return write_all_supers(fs_info); + } + +-/* +- * Return 0 for no unfinished fsid change. +- * Return >0 for unfinished fsid change, and restore unfinished fsid/ +- * chunk_tree_id into fsid_ret/chunk_id_ret. +- */ +-static int check_unfinished_fsid_change(struct btrfs_fs_info *fs_info, +- uuid_t fsid_ret, uuid_t chunk_id_ret) +-{ +- struct btrfs_root *tree_root = fs_info->tree_root; +- u64 flags = btrfs_super_flags(fs_info->super_copy); +- +- if (flags & BTRFS_SUPER_FLAG_CHANGING_FSID) { +- memcpy(fsid_ret, fs_info->super_copy->fsid, BTRFS_FSID_SIZE); +- read_extent_buffer(tree_root->node, chunk_id_ret, +- btrfs_header_chunk_tree_uuid(tree_root->node), +- BTRFS_UUID_SIZE); +- return 1; +- } +- return 0; +-} + + /* + * Change fsid of a given fs. +@@ -381,8 +471,10 @@ static void print_usage(void) + printf("\t-x \t\tenable skinny metadata extent refs\n"); + printf("\t-n \t\tenable no-holes feature (more efficient sparse file representation)\n"); + printf("\t-f \t\tforce to do dangerous operation, make sure that you are aware of the dangers\n"); +- printf("\t-u \t\tchange fsid, use a random one\n"); +- printf("\t-U UUID\t\tchange fsid to UUID\n"); ++ printf("\t-u \t\trewrite fsid, use a random one\n"); ++ printf("\t-U UUID\t\trewrite fsid to UUID\n"); ++ printf("\t-m \t\tchange only user-facing uuid (more lightweight than -u|-U)\n"); ++ printf("\t-M UUID\t\tchange fsid to UUID\n"); + } + + int main(int argc, char *argv[]) +@@ -394,6 +486,7 @@ int main(int argc, char *argv[]) + int seeding_flag = 0; + u64 seeding_value = 0; + int random_fsid = 0; ++ int change_metadata_uuid = 0; + char *new_fsid_str = NULL; + int ret; + u64 super_flags = 0; +@@ -404,7 +497,7 @@ int main(int argc, char *argv[]) + { "help", no_argument, NULL, GETOPT_VAL_HELP}, + { NULL, 0, NULL, 0 } + }; +- int c = getopt_long(argc, argv, "S:rxfuU:n", long_options, NULL); ++ int c = getopt_long(argc, argv, "S:rxfuU:nmM:", long_options, NULL); + + if (c < 0) + break; +@@ -433,6 +526,15 @@ int main(int argc, char *argv[]) + ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH; + random_fsid = 1; + break; ++ case 'M': ++ ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH; ++ change_metadata_uuid = 1; ++ new_fsid_str = optarg; ++ break; ++ case 'm': ++ ctree_flags |= OPEN_CTREE_IGNORE_FSID_MISMATCH; ++ change_metadata_uuid = 1; ++ break; + case GETOPT_VAL_HELP: + default: + print_usage(); +@@ -451,7 +553,8 @@ int main(int argc, char *argv[]) + error("random fsid can't be used with specified fsid"); + return 1; + } +- if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str)) { ++ if (!super_flags && !seeding_flag && !(random_fsid || new_fsid_str) && ++ !change_metadata_uuid) { + error("at least one option should be specified"); + print_usage(); + return 1; +@@ -498,6 +601,12 @@ int main(int argc, char *argv[]) + } + + if (seeding_flag) { ++ if (btrfs_fs_incompat(root->fs_info, METADATA_UUID)) { ++ fprintf(stderr, "SEED flag cannot be changed on a metadata-uuid changed fs\n"); ++ ret = 1; ++ goto out; ++ } ++ + if (!seeding_value && !force) { + warning( + "this is dangerous, clearing the seeding flag may cause the derived device not to be mountable!"); +@@ -522,7 +631,33 @@ int main(int argc, char *argv[]) + total++; + } + +- if (random_fsid || new_fsid_str) { ++ if (change_metadata_uuid) { ++ if (seeding_flag) { ++ fprintf(stderr, ++ "Not allowed to set both seeding flag and uuid metadata\n"); ++ ret = 1; ++ goto out; ++ } ++ ++ if (new_fsid_str) ++ ret = set_metadata_uuid(root, new_fsid_str); ++ else ++ ret = set_metadata_uuid(root, NULL); ++ ++ if (!ret) ++ success++; ++ total++; ++ } ++ ++ if (random_fsid || (new_fsid_str && !change_metadata_uuid)) { ++ if (btrfs_fs_incompat(root->fs_info, METADATA_UUID)) { ++ fprintf(stderr, ++ "Cannot rewrite fsid while METADATA_UUID flag is active. \n" ++ "Ensure fsid and metadata_uuid match before retrying.\n"); ++ ret = 1; ++ goto out; ++ } ++ + if (!force) { + warning( + "it's recommended to run 'btrfs check --readonly' before this operation.\n" +diff --git a/ctree.h b/ctree.h +index 45ef02e7fb45..be5ecf8fe7c1 100644 +--- a/ctree.h ++++ b/ctree.h +@@ -330,6 +330,7 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes) + #define BTRFS_SUPER_FLAG_METADUMP (1ULL << 33) + #define BTRFS_SUPER_FLAG_METADUMP_V2 (1ULL << 34) + #define BTRFS_SUPER_FLAG_CHANGING_FSID (1ULL << 35) ++#define BTRFS_SUPER_FLAG_CHANGING_FSID_V2 (1ULL << 36) + + #define BTRFS_BACKREF_REV_MAX 256 + #define BTRFS_BACKREF_REV_SHIFT 56 +-- +2.17.1 + diff --git a/0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch b/0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch new file mode 100644 index 0000000..f789a1b --- /dev/null +++ b/0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch @@ -0,0 +1,252 @@ +From 0e8e98121455f53a129c9fe825d465c6a7749e9b Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Thu, 11 Oct 2018 18:04:02 +0300 +Subject: [PATCH 3/6] btrfs-progs: Remove fsid/metdata_uuid fields from fs_info + +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +--- + btrfstune.c | 5 +++-- + check/main.c | 2 +- + chunk-recover.c | 11 +++++------ + ctree.c | 11 ++++++----- + ctree.h | 2 -- + disk-io.c | 18 +++++++++--------- + free-space-tree.c | 5 +++-- + volumes.c | 5 +++-- + 8 files changed, 30 insertions(+), 29 deletions(-) + +diff --git a/btrfstune.c b/btrfstune.c +index b6ce201155f7..500308b556fe 100644 +--- a/btrfstune.c ++++ b/btrfstune.c +@@ -359,7 +359,8 @@ static int change_fsid_prepare(struct btrfs_fs_info *fs_info) + return ret; + + /* Also need to change the metadatauuid of the fs info */ +- memcpy(fs_info->metadata_uuid, fs_info->new_fsid, BTRFS_FSID_SIZE); ++ memcpy(fs_info->fs_devices->metadata_uuid, fs_info->new_fsid, ++ BTRFS_FSID_SIZE); + + /* also restore new chunk_tree_id into tree_root for restore */ + write_extent_buffer(tree_root->node, fs_info->new_chunk_tree_uuid, +@@ -416,7 +417,7 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + fs_info->new_fsid = new_fsid; + fs_info->new_chunk_tree_uuid = new_chunk_id; + +- memcpy(old_fsid, (const char*)fs_info->fsid, BTRFS_UUID_SIZE); ++ memcpy(old_fsid, (const char*)fs_info->fs_devices->fsid, BTRFS_UUID_SIZE); + uuid_unparse(old_fsid, uuid_buf); + printf("Current fsid: %s\n", uuid_buf); + +diff --git a/check/main.c b/check/main.c +index 915be1b5afd2..dbb7da5b1dc2 100644 +--- a/check/main.c ++++ b/check/main.c +@@ -8424,7 +8424,7 @@ static int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans, + btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(c, root->root_key.objectid); + +- write_extent_buffer(c, root->fs_info->metadata_uuid, ++ 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, +diff --git a/chunk-recover.c b/chunk-recover.c +index 31325bfc54e0..959c169f79a4 100644 +--- a/chunk-recover.c ++++ b/chunk-recover.c +@@ -1155,7 +1155,7 @@ static int __rebuild_chunk_root(struct btrfs_trans_handle *trans, + btrfs_set_header_level(cow, 0); + btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(cow, BTRFS_CHUNK_TREE_OBJECTID); +- write_extent_buffer(cow, root->fs_info->metadata_uuid, ++ write_extent_buffer(cow, root->fs_info->fs_devices->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + write_extent_buffer(cow, root->fs_info->chunk_tree_uuid, +@@ -1457,7 +1457,7 @@ open_ctree_with_broken_chunk(struct recover_control *rc) + goto out_devices; + } + +- memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE); ++ ASSERT(!memcmp(disk_super->fsid, rc->fs_devices->fsid, BTRFS_FSID_SIZE)); + fs_info->sectorsize = btrfs_super_sectorsize(disk_super); + fs_info->nodesize = btrfs_super_nodesize(disk_super); + fs_info->stripesize = btrfs_super_stripesize(disk_super); +@@ -1469,10 +1469,9 @@ open_ctree_with_broken_chunk(struct recover_control *rc) + features = btrfs_super_incompat_flags(disk_super); + + if (features & BTRFS_FEATURE_INCOMPAT_METADATA_UUID) +- memcpy(fs_info->metadata_uuid, disk_super->metadata_uuid, +- BTRFS_FSID_SIZE); +- else +- memcpy(fs_info->metadata_uuid, fs_info->fsid, BTRFS_FSID_SIZE); ++ ASSERT(!memcmp(disk_super->metadata_uuid, ++ fs_info->fs_devices->metadata_uuid, ++ BTRFS_FSID_SIZE)); + + btrfs_setup_root(fs_info->chunk_root, fs_info, + BTRFS_CHUNK_TREE_OBJECTID); +diff --git a/ctree.c b/ctree.c +index 548d6e2c1f62..e7bb26e65c55 100644 +--- a/ctree.c ++++ b/ctree.c +@@ -23,6 +23,7 @@ + #include "internal.h" + #include "sizes.h" + #include "messages.h" ++#include "volumes.h" + + static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root + *root, struct btrfs_path *path, int level); +@@ -134,7 +135,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, + else + btrfs_set_header_owner(cow, new_root_objectid); + +- write_extent_buffer(cow, root->fs_info->metadata_uuid, ++ write_extent_buffer(cow, root->fs_info->fs_devices->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + WARN_ON(btrfs_header_generation(buf) > trans->transid); +@@ -308,7 +309,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans, + else + btrfs_set_header_owner(cow, root->root_key.objectid); + +- write_extent_buffer(cow, root->fs_info->metadata_uuid, ++ write_extent_buffer(cow, root->fs_info->fs_devices->metadata_uuid, + btrfs_header_fsid(), BTRFS_FSID_SIZE); + + WARN_ON(!(buf->flags & EXTENT_BAD_TRANSID) && +@@ -1548,7 +1549,7 @@ static int noinline insert_new_root(struct btrfs_trans_handle *trans, + + root_add_used(root, root->fs_info->nodesize); + +- write_extent_buffer(c, root->fs_info->metadata_uuid, ++ 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, +@@ -1669,7 +1670,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root + 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->metadata_uuid, ++ 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), +@@ -2251,7 +2252,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans, + 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->metadata_uuid, ++ 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, +diff --git a/ctree.h b/ctree.h +index be5ecf8fe7c1..dec0dab1dde5 100644 +--- a/ctree.h ++++ b/ctree.h +@@ -1093,8 +1093,6 @@ struct btrfs_block_group_cache { + struct btrfs_device; + struct btrfs_fs_devices; + struct btrfs_fs_info { +- u8 fsid[BTRFS_FSID_SIZE]; +- u8 metadata_uuid[BTRFS_FSID_SIZE]; + u8 *new_fsid; + u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; + u8 *new_chunk_tree_uuid; +diff --git a/disk-io.c b/disk-io.c +index 1e5fac89b127..8ead97d079ac 100644 +--- a/disk-io.c ++++ b/disk-io.c +@@ -118,7 +118,7 @@ static void print_tree_block_error(struct btrfs_fs_info *fs_info, + read_extent_buffer(eb, buf, btrfs_header_fsid(), + BTRFS_UUID_SIZE); + uuid_unparse(buf, found_uuid); +- uuid_unparse(fs_info->metadata_uuid, fs_uuid); ++ uuid_unparse(fs_info->fs_devices->metadata_uuid, fs_uuid); + fprintf(stderr, "fsid mismatch, want=%s, have=%s\n", + fs_uuid, found_uuid); + break; +@@ -1184,13 +1184,12 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, const char *path, + goto out_devices; + } + +- memcpy(fs_info->fsid, &disk_super->fsid, BTRFS_FSID_SIZE); +- if (btrfs_fs_incompat(fs_info, METADATA_UUID)) { +- memcpy(fs_info->metadata_uuid, disk_super->metadata_uuid, +- BTRFS_FSID_SIZE); +- } else { +- memcpy(fs_info->metadata_uuid, fs_info->fsid, BTRFS_FSID_SIZE); +- } ++ ASSERT(!memcmp(disk_super->fsid, fs_devices->fsid, BTRFS_FSID_SIZE)); ++ ASSERT(!memcmp(disk_super->fsid, fs_devices->fsid, BTRFS_FSID_SIZE)); ++ if (btrfs_fs_incompat(fs_info, METADATA_UUID)) ++ ASSERT(!memcmp(disk_super->metadata_uuid, ++ fs_devices->metadata_uuid, BTRFS_FSID_SIZE)); ++ + fs_info->sectorsize = btrfs_super_sectorsize(disk_super); + fs_info->nodesize = btrfs_super_nodesize(disk_super); + fs_info->stripesize = btrfs_super_stripesize(disk_super); +@@ -1646,7 +1645,8 @@ int write_all_supers(struct btrfs_fs_info *fs_info) + btrfs_set_stack_device_io_width(dev_item, dev->io_width); + btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); + memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); +- memcpy(dev_item->fsid, fs_info->metadata_uuid, BTRFS_FSID_SIZE); ++ memcpy(dev_item->fsid, fs_info->fs_devices->metadata_uuid, ++ BTRFS_FSID_SIZE); + + flags = btrfs_super_flags(sb); + btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); +diff --git a/free-space-tree.c b/free-space-tree.c +index 0a3305415657..2251b825890f 100644 +--- a/free-space-tree.c ++++ b/free-space-tree.c +@@ -20,6 +20,7 @@ + #include "disk-io.h" + #include "free-space-cache.h" + #include "free-space-tree.h" ++#include "volumes.h" + #include "transaction.h" + #include "bitops.h" + #include "internal.h" +@@ -1453,8 +1454,8 @@ static struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, + btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); + btrfs_set_header_owner(leaf, objectid); + root->node = leaf; +- write_extent_buffer(leaf, fs_info->metadata_uuid, btrfs_header_fsid(), +- BTRFS_FSID_SIZE); ++ 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); +diff --git a/volumes.c b/volumes.c +index 6ef871637d7a..2c6aaf42c5fb 100644 +--- a/volumes.c ++++ b/volumes.c +@@ -741,7 +741,8 @@ int btrfs_add_device(struct btrfs_trans_handle *trans, + ptr = (unsigned long)btrfs_device_uuid(dev_item); + write_extent_buffer(leaf, device->uuid, ptr, BTRFS_UUID_SIZE); + ptr = (unsigned long)btrfs_device_fsid(dev_item); +- write_extent_buffer(leaf, fs_info->metadata_uuid, ptr, BTRFS_UUID_SIZE); ++ write_extent_buffer(leaf, fs_info->fs_devices->metadata_uuid, ptr, ++ BTRFS_UUID_SIZE); + btrfs_mark_buffer_dirty(leaf); + ret = 0; + +@@ -2041,7 +2042,7 @@ static int read_one_dev(struct btrfs_fs_info *fs_info, + (unsigned long)btrfs_device_fsid(dev_item), + BTRFS_FSID_SIZE); + +- if (memcmp(fs_uuid, fs_info->fsid, BTRFS_UUID_SIZE)) { ++ if (memcmp(fs_uuid, fs_info->fs_devices->fsid, BTRFS_UUID_SIZE)) { + ret = open_seed_devices(fs_info, fs_uuid); + if (ret) + return ret; +-- +2.17.1 + diff --git a/0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch b/0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch new file mode 100644 index 0000000..325bc1a --- /dev/null +++ b/0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch @@ -0,0 +1,205 @@ +From 1a438fc67c6b389221f20e25c13acd195fa0656b Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Thu, 11 Oct 2018 18:04:03 +0300 +Subject: [PATCH 4/6] btrfs-progs: Remove btrfs_fs_info::new_fsid + +This member was used only by btrfstune when using the old method to +change fsid. It's only an in-memory value with a very specific +purpose so it makes no sense to pollute a generic structure such as +btrfs_fs_info with it. Just remove it and pass it as a function +argument where pertinent. No functional changes. + +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +--- + btrfstune.c | 46 +++++++++++++++++++++------------------------- + ctree.h | 1 - + 2 files changed, 21 insertions(+), 26 deletions(-) + +diff --git a/btrfstune.c b/btrfstune.c +index 500308b556fe..74a7c37195b0 100644 +--- a/btrfstune.c ++++ b/btrfstune.c +@@ -201,15 +201,15 @@ static int set_super_incompat_flags(struct btrfs_root *root, u64 flags) + return ret; + } + +-static int change_buffer_header_uuid(struct extent_buffer *eb) ++static int change_buffer_header_uuid(struct extent_buffer *eb, uuid_t new_fsid) + { + struct btrfs_fs_info *fs_info = eb->fs_info; + int same_fsid = 1; + int same_chunk_tree_uuid = 1; + int ret; + +- same_fsid = !memcmp_extent_buffer(eb, fs_info->new_fsid, +- btrfs_header_fsid(), BTRFS_FSID_SIZE); ++ same_fsid = !memcmp_extent_buffer(eb, new_fsid, btrfs_header_fsid(), ++ BTRFS_FSID_SIZE); + same_chunk_tree_uuid = + !memcmp_extent_buffer(eb, fs_info->new_chunk_tree_uuid, + btrfs_header_chunk_tree_uuid(eb), +@@ -217,7 +217,7 @@ static int change_buffer_header_uuid(struct extent_buffer *eb) + if (same_fsid && same_chunk_tree_uuid) + return 0; + if (!same_fsid) +- write_extent_buffer(eb, fs_info->new_fsid, btrfs_header_fsid(), ++ write_extent_buffer(eb, new_fsid, btrfs_header_fsid(), + BTRFS_FSID_SIZE); + if (!same_chunk_tree_uuid) + write_extent_buffer(eb, fs_info->new_chunk_tree_uuid, +@@ -228,7 +228,7 @@ static int change_buffer_header_uuid(struct extent_buffer *eb) + return ret; + } + +-static int change_extents_uuid(struct btrfs_fs_info *fs_info) ++static int change_extents_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsid) + { + struct btrfs_root *root = fs_info->extent_root; + struct btrfs_path path; +@@ -267,7 +267,7 @@ static int change_extents_uuid(struct btrfs_fs_info *fs_info) + ret = PTR_ERR(eb); + goto out; + } +- ret = change_buffer_header_uuid(eb); ++ ret = change_buffer_header_uuid(eb, new_fsid); + free_extent_buffer(eb); + if (ret < 0) { + error("failed to change uuid of tree block: %llu", +@@ -289,27 +289,27 @@ static int change_extents_uuid(struct btrfs_fs_info *fs_info) + return ret; + } + +-static int change_device_uuid(struct extent_buffer *eb, int slot) ++static int change_device_uuid(struct extent_buffer *eb, int slot, ++ uuid_t new_fsid) + { + struct btrfs_dev_item *di; + struct btrfs_fs_info *fs_info = eb->fs_info; + int ret = 0; + + di = btrfs_item_ptr(eb, slot, struct btrfs_dev_item); +- if (!memcmp_extent_buffer(eb, fs_info->new_fsid, ++ if (!memcmp_extent_buffer(eb, new_fsid, + (unsigned long)btrfs_device_fsid(di), + BTRFS_FSID_SIZE)) + return ret; + +- write_extent_buffer(eb, fs_info->new_fsid, +- (unsigned long)btrfs_device_fsid(di), ++ write_extent_buffer(eb, new_fsid, (unsigned long)btrfs_device_fsid(di), + BTRFS_FSID_SIZE); + ret = write_tree_block(NULL, fs_info, eb); + + return ret; + } + +-static int change_devices_uuid(struct btrfs_fs_info *fs_info) ++static int change_devices_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsid) + { + struct btrfs_root *root = fs_info->chunk_root; + struct btrfs_path path; +@@ -327,7 +327,8 @@ static int change_devices_uuid(struct btrfs_fs_info *fs_info) + if (key.type != BTRFS_DEV_ITEM_KEY || + key.objectid != BTRFS_DEV_ITEMS_OBJECTID) + goto next; +- ret = change_device_uuid(path.nodes[0], path.slots[0]); ++ ret = change_device_uuid(path.nodes[0], path.slots[0], ++ new_fsid); + if (ret < 0) + goto out; + next: +@@ -344,7 +345,7 @@ static int change_devices_uuid(struct btrfs_fs_info *fs_info) + return ret; + } + +-static int change_fsid_prepare(struct btrfs_fs_info *fs_info) ++static int change_fsid_prepare(struct btrfs_fs_info *fs_info, uuid_t new_fsid) + { + struct btrfs_root *tree_root = fs_info->tree_root; + u64 flags = btrfs_super_flags(fs_info->super_copy); +@@ -353,14 +354,13 @@ static int change_fsid_prepare(struct btrfs_fs_info *fs_info) + flags |= BTRFS_SUPER_FLAG_CHANGING_FSID; + btrfs_set_super_flags(fs_info->super_copy, flags); + +- memcpy(fs_info->super_copy->fsid, fs_info->new_fsid, BTRFS_FSID_SIZE); ++ memcpy(fs_info->super_copy->fsid, new_fsid, BTRFS_FSID_SIZE); + ret = write_all_supers(fs_info); + if (ret < 0) + return ret; + + /* Also need to change the metadatauuid of the fs info */ +- memcpy(fs_info->fs_devices->metadata_uuid, fs_info->new_fsid, +- BTRFS_FSID_SIZE); ++ memcpy(fs_info->fs_devices->metadata_uuid, new_fsid, BTRFS_FSID_SIZE); + + /* also restore new chunk_tree_id into tree_root for restore */ + write_extent_buffer(tree_root->node, fs_info->new_chunk_tree_uuid, +@@ -414,7 +414,6 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + + uuid_generate(new_chunk_id); + } +- fs_info->new_fsid = new_fsid; + fs_info->new_chunk_tree_uuid = new_chunk_id; + + memcpy(old_fsid, (const char*)fs_info->fs_devices->fsid, BTRFS_UUID_SIZE); +@@ -425,13 +424,13 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + printf("New fsid: %s\n", uuid_buf); + /* Now we can begin fsid change */ + printf("Set superblock flag CHANGING_FSID\n"); +- ret = change_fsid_prepare(fs_info); ++ ret = change_fsid_prepare(fs_info, new_fsid); + if (ret < 0) + goto out; + + /* Change extents first */ + printf("Change fsid in extents\n"); +- ret = change_extents_uuid(fs_info); ++ ret = change_extents_uuid(fs_info, new_fsid); + if (ret < 0) { + error("failed to change UUID of metadata: %d", ret); + goto out; +@@ -439,17 +438,15 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + + /* Then devices */ + printf("Change fsid on devices\n"); +- ret = change_devices_uuid(fs_info); ++ ret = change_devices_uuid(fs_info, new_fsid); + if (ret < 0) { + error("failed to change UUID of devices: %d", ret); + goto out; + } + + /* Last, change fsid in super */ +- memcpy(fs_info->fs_devices->fsid, fs_info->new_fsid, +- BTRFS_FSID_SIZE); +- memcpy(fs_info->super_copy->fsid, fs_info->new_fsid, +- BTRFS_FSID_SIZE); ++ memcpy(fs_info->fs_devices->fsid, new_fsid, BTRFS_FSID_SIZE); ++ memcpy(fs_info->super_copy->fsid, new_fsid, BTRFS_FSID_SIZE); + ret = write_all_supers(fs_info); + if (ret < 0) + goto out; +@@ -457,7 +454,6 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + /* Now fsid change is done */ + printf("Clear superblock flag CHANGING_FSID\n"); + ret = change_fsid_done(fs_info); +- fs_info->new_fsid = NULL; + fs_info->new_chunk_tree_uuid = NULL; + printf("Fsid change finished\n"); + out: +diff --git a/ctree.h b/ctree.h +index dec0dab1dde5..2abdea676b92 100644 +--- a/ctree.h ++++ b/ctree.h +@@ -1093,7 +1093,6 @@ struct btrfs_block_group_cache { + struct btrfs_device; + struct btrfs_fs_devices; + struct btrfs_fs_info { +- u8 *new_fsid; + u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; + u8 *new_chunk_tree_uuid; + struct btrfs_root *fs_root; +-- +2.17.1 + diff --git a/0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch b/0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch new file mode 100644 index 0000000..8d4c2af --- /dev/null +++ b/0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch @@ -0,0 +1,41 @@ +From eb9657f801e4565acb8ba6b59f69e34316104c52 Mon Sep 17 00:00:00 2001 +From: Nikolay Borisov +Date: Thu, 11 Oct 2018 18:04:04 +0300 +Subject: [PATCH 5/6] btrfs-progs: Directly pass root to change_devices_uuid + +This function currently takes an fs_info only to reference the chunk +root. Just pass the root directly. No functional changes. + +Signed-off-by: Nikolay Borisov +Signed-off-by: David Sterba +--- + btrfstune.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/btrfstune.c b/btrfstune.c +index 74a7c37195b0..7466f7f4a198 100644 +--- a/btrfstune.c ++++ b/btrfstune.c +@@ -309,9 +309,8 @@ static int change_device_uuid(struct extent_buffer *eb, int slot, + return ret; + } + +-static int change_devices_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsid) ++static int change_devices_uuid(struct btrfs_root *root, uuid_t new_fsid) + { +- struct btrfs_root *root = fs_info->chunk_root; + struct btrfs_path path; + struct btrfs_key key = {0, 0, 0}; + int ret = 0; +@@ -438,7 +437,7 @@ static int change_uuid(struct btrfs_fs_info *fs_info, const char *new_fsid_str) + + /* Then devices */ + printf("Change fsid on devices\n"); +- ret = change_devices_uuid(fs_info, new_fsid); ++ ret = change_devices_uuid(fs_info->chunk_root, new_fsid); + if (ret < 0) { + error("failed to change UUID of devices: %d", ret); + goto out; +-- +2.17.1 + diff --git a/btrfsprogs.changes b/btrfsprogs.changes index 82f9e45..dc65190 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Thu Jan 17 07:48:54 UTC 2019 - nborisov@suse.com + +- Implement fate#325871 + * Added 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch + * Added 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch + * Added 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch + * Added 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch + * Added 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch + ------------------------------------------------------------------- Thu Dec 6 00:00:00 CET 2018 - dsterba@suse.cz diff --git a/btrfsprogs.spec b/btrfsprogs.spec index 01a9666..2b8f12f 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -46,6 +46,11 @@ Source4: setup-btrfs.sh Source5: sles11-defaults.h Patch1: mkfs-default-features.patch +Patch2: 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch +Patch3: 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch +Patch4: 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch +Patch5: 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch +Patch6: 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch %if %build_docs BuildRequires: asciidoc @@ -169,6 +174,11 @@ build applications to interface with Btrfs using libbtrfsutil. %prep %setup -q -n btrfs-progs-v%{version} %patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 %build ./autogen.sh