From bbad3810abe8832ff865fa80a1397792ae06744ab92e33bd6380bf278a09955c Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 17 Jan 2019 14:35:40 +0000 Subject: [PATCH 1/4] 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 From b6c7ca75274a318fb08dcf47b9ed6a5327c1b750bb15f4fbb0504ca5b617ac82 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 17 Jan 2019 15:03:53 +0000 Subject: [PATCH 2/4] Accepting request 666758 from home:dsterba:branches:filesystems - Use %license instead of %doc [bsc#1082318] (builds on all products) OBS-URL: https://build.opensuse.org/request/show/666758 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=308 --- btrfsprogs.changes | 5 +++++ btrfsprogs.spec | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/btrfsprogs.changes b/btrfsprogs.changes index dc65190..2b573c1 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Jan 17 15:45:01 CET 2019 - kukuk@suse.de + +- Use %license instead of %doc [bsc#1082318] + ------------------------------------------------------------------- Thu Jan 17 07:48:54 UTC 2019 - nborisov@suse.com diff --git a/btrfsprogs.spec b/btrfsprogs.spec index 2b8f12f..cb32c93 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -1,7 +1,7 @@ # # spec file for package btrfsprogs # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -283,7 +283,12 @@ done %files %defattr(-, root, root) +%if 0%{?suse_version} < 1200 +# SLE11 doesn't know about %license %doc COPYING +%else +%license COPYING +%endif /sbin/fsck.btrfs # mkinitrd utils /sbin/btrfs From 41fbca90839ab7e95c92f65d85751ee08b8ff4b4e677fc3cd406d7a19018a2f6 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Mon, 21 Jan 2019 13:36:56 +0000 Subject: [PATCH 3/4] Accepting request 667178 from home:avindra:branches:filesystems - update to version 4.20 * new feature: metadata uuid * lightweight change of UUID without rewriting all metadata (incompatible change) * done by btrfstune -m/-M, needs kernel support, 5.0+ * image: * fix block groups when restoring from multi-device image * only enlarge result image if it's a regular file * check * more device extent checks and fixes * can repair dir item with mismatched hash * mkfs: uuid tree created with proper contents * fix mount point detection due to partial prefix match * other: * new tests, build fixes, doc updates * libbtrfsutil: fix tests if kernel lacks support for new subvolume ioctls - partial cleanup with spec-cleaner - drop 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch - drop 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch - drop 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch - drop 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch - drop 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch OBS-URL: https://build.opensuse.org/request/show/667178 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=309 --- ...-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 -- btrfs-progs-v4.19.1.tar.gz | 3 - btrfs-progs-v4.20.tar.gz | 3 + btrfsprogs.changes | 27 + btrfsprogs.spec | 14 +- 9 files changed, 32 insertions(+), 1494 deletions(-) delete mode 100644 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch delete mode 100644 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch delete mode 100644 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch delete mode 100644 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch delete mode 100644 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch delete mode 100644 btrfs-progs-v4.19.1.tar.gz create mode 100644 btrfs-progs-v4.20.tar.gz diff --git a/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch b/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch deleted file mode 100644 index 9227210..0000000 --- a/0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch +++ /dev/null @@ -1,641 +0,0 @@ -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 deleted file mode 100644 index b995fef..0000000 --- a/0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch +++ /dev/null @@ -1,340 +0,0 @@ -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 deleted file mode 100644 index f789a1b..0000000 --- a/0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch +++ /dev/null @@ -1,252 +0,0 @@ -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 deleted file mode 100644 index 325bc1a..0000000 --- a/0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch +++ /dev/null @@ -1,205 +0,0 @@ -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 deleted file mode 100644 index 8d4c2af..0000000 --- a/0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch +++ /dev/null @@ -1,41 +0,0 @@ -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/btrfs-progs-v4.19.1.tar.gz b/btrfs-progs-v4.19.1.tar.gz deleted file mode 100644 index a380e98..0000000 --- a/btrfs-progs-v4.19.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:92114f5ee3949eebcc87846b914a18248bacb42d515c459af2ac5ddbf213a8cd -size 2455352 diff --git a/btrfs-progs-v4.20.tar.gz b/btrfs-progs-v4.20.tar.gz new file mode 100644 index 0000000..a80cd6a --- /dev/null +++ b/btrfs-progs-v4.20.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f1c3e40bd7791d2c18029b31ff081778c15fad12986c47c98838addfaf391bd +size 2487014 diff --git a/btrfsprogs.changes b/btrfsprogs.changes index 2b573c1..e80cb4d 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,30 @@ +------------------------------------------------------------------- +Sat Jan 19 16:44:57 UTC 2019 - Avindra Goolcharan + +- update to version 4.20 + * new feature: metadata uuid + * lightweight change of UUID without rewriting all metadata + (incompatible change) + * done by btrfstune -m/-M, needs kernel support, 5.0+ + * image: + * fix block groups when restoring from multi-device image + * only enlarge result image if it's a regular file + * check + * more device extent checks and fixes + * can repair dir item with mismatched hash + * mkfs: uuid tree created with proper contents + * fix mount point detection due to partial prefix match + * other: + * new tests, build fixes, doc updates + * libbtrfsutil: fix tests if kernel lacks support for new + subvolume ioctls +- partial cleanup with spec-cleaner +- drop 0001-btrfs-progs-Add-support-for-metadata_uuid-field.patch +- drop 0002-btrfs-progs-btrfstune-Add-support-for-changing-the-u.patch +- drop 0003-btrfs-progs-Remove-fsid-metdata_uuid-fields-from-fs_.patch +- drop 0004-btrfs-progs-Remove-btrfs_fs_info-new_fsid.patch +- drop 0005-btrfs-progs-Directly-pass-root-to-change_devices_uui.patch + ------------------------------------------------------------------- Mon Jan 17 15:45:01 CET 2019 - kukuk@suse.de diff --git a/btrfsprogs.spec b/btrfsprogs.spec index cb32c93..5aff40f 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -31,12 +31,12 @@ %define build_docs 0 Name: btrfsprogs -Version: 4.19.1 +Version: 4.20 Release: 0 Summary: Utilities for the Btrfs filesystem License: GPL-2.0-only Group: System/Filesystems -Url: http://btrfs.wiki.kernel.org/index.php/Main_Page +URL: https://btrfs.wiki.kernel.org/index.php/Main_Page #Git-Web: http://git.kernel.org/cgit/linux/kernel/git/kdave/btrfs-progs.git #Git-Clone: git://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs Source: https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs/btrfs-progs-v%{version}.tar.gz @@ -46,11 +46,6 @@ 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 @@ -174,11 +169,6 @@ 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 From 9646e4b22282d7981363b82f1fb999db15ff4911ed97b96303385196561e18c3 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 23 Jan 2019 13:12:59 +0000 Subject: [PATCH 4/4] Accepting request 668079 from home:dsterba:branches:filesystems - update to version 4.20.1 OBS-URL: https://build.opensuse.org/request/show/668079 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=310 --- btrfs-progs-v4.20.1.tar.gz | 3 +++ btrfs-progs-v4.20.tar.gz | 3 --- btrfsprogs.changes | 7 +++++++ btrfsprogs.spec | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 btrfs-progs-v4.20.1.tar.gz delete mode 100644 btrfs-progs-v4.20.tar.gz diff --git a/btrfs-progs-v4.20.1.tar.gz b/btrfs-progs-v4.20.1.tar.gz new file mode 100644 index 0000000..77a0a9b --- /dev/null +++ b/btrfs-progs-v4.20.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54d9d9cd1376d5205ba5c578bc4acd0ae1567a5931fb86f86789109c4fe89d7f +size 2487153 diff --git a/btrfs-progs-v4.20.tar.gz b/btrfs-progs-v4.20.tar.gz deleted file mode 100644 index a80cd6a..0000000 --- a/btrfs-progs-v4.20.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f1c3e40bd7791d2c18029b31ff081778c15fad12986c47c98838addfaf391bd -size 2487014 diff --git a/btrfsprogs.changes b/btrfsprogs.changes index e80cb4d..5ac90f3 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Wed Jan 23 00:00:00 CET 2019 - dsterba@suse.cz + +- update to version 4.20.1 + * libbtrfs: fix build of external tools due to missing symbols + * ci: enable library test + ------------------------------------------------------------------- Sat Jan 19 16:44:57 UTC 2019 - Avindra Goolcharan diff --git a/btrfsprogs.spec b/btrfsprogs.spec index 5aff40f..8a43519 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -31,7 +31,7 @@ %define build_docs 0 Name: btrfsprogs -Version: 4.20 +Version: 4.20.1 Release: 0 Summary: Utilities for the Btrfs filesystem License: GPL-2.0-only