From 3f27e608663ef0feb0c2e22001da79df7817fa3f Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 3 Oct 2023 11:46:14 +0800 Subject: [PATCH] btrfs-progs: mkfs: add option to specify device uuid Add option --device-uuid that will set the device uuid item in super block. This is useful for creating a filesystem with a specific device uuid, namely for testing. Signed-off-by: Anand Jain Signed-off-by: David Sterba --- Documentation/mkfs.btrfs.rst | 6 ++++++ mkfs/common.c | 7 ++++++- mkfs/common.h | 5 +++++ mkfs/main.c | 13 +++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Documentation/mkfs.btrfs.rst b/Documentation/mkfs.btrfs.rst index c0fd92f7..e4b53b86 100644 --- a/Documentation/mkfs.btrfs.rst +++ b/Documentation/mkfs.btrfs.rst @@ -183,6 +183,12 @@ OPTIONS you can duplicate the UUID. However, for a multi-device filesystem, the UUID must not already exist on any currently present filesystem. +--device-uuid + Create the filesystem with the given device-uuid *UUID* (also known as + UUID_SUB in :command:`blkid`). For a single device filesystem, you can + duplicate the device-uuid. However, used for a multi-device filesystem + this option will not work at the moment. + -v|--verbose Increase verbosity level, default is 1. diff --git a/mkfs/common.c b/mkfs/common.c index d400413c..5e56b33d 100644 --- a/mkfs/common.c +++ b/mkfs/common.c @@ -435,7 +435,12 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg) } else { uuid_parse(cfg->fs_uuid, super.fsid); } - uuid_generate(super.dev_item.uuid); + if (!*cfg->dev_uuid) { + uuid_generate(super.dev_item.uuid); + uuid_unparse(super.dev_item.uuid, cfg->dev_uuid); + } else { + uuid_parse(cfg->dev_uuid, super.dev_item.uuid); + } uuid_generate(chunk_tree_uuid); for (i = 0; i < blocks_nr; i++) { diff --git a/mkfs/common.h b/mkfs/common.h index 06ddc926..d9183c99 100644 --- a/mkfs/common.h +++ b/mkfs/common.h @@ -90,7 +90,12 @@ struct btrfs_mkfs_config { /* Logical addresses of superblock [0] and other tree roots */ u64 blocks[MKFS_BLOCK_COUNT + 1]; + + /* btrfs_super_block filesystem uuid */ char fs_uuid[BTRFS_UUID_UNPARSED_SIZE]; + + /* Set the given uuid to super block device_item. */ + char dev_uuid[BTRFS_UUID_UNPARSED_SIZE]; char chunk_uuid[BTRFS_UUID_UNPARSED_SIZE]; /* Superblock offset after make_btrfs */ diff --git a/mkfs/main.c b/mkfs/main.c index 4f6223ab..26116fc7 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -431,6 +431,7 @@ static const char * const mkfs_usage[] = { OPTLINE("-O|--features LIST", "comma separated list of filesystem features (use '-O list-all' to list features)"), OPTLINE("-L|--label LABEL", "set the filesystem label"), OPTLINE("-U|--uuid UUID", "specify the filesystem UUID (must be unique for a filesystem with multiple devices)"), + OPTLINE("--device-uuid UUID", "Specify the filesystem device UUID (a.k.a sub-uuid) (for single device filesystem only)"), "Creation:", OPTLINE("-b|--byte-count SIZE", "set size of each device to SIZE (filesystem size is sum of all device sizes)"), OPTLINE("-r|--rootdir DIR", "copy files from DIR to the image root directory"), @@ -1161,6 +1162,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv) struct btrfs_mkfs_features features = btrfs_mkfs_default_features; enum btrfs_csum_type csum_type = BTRFS_CSUM_TYPE_CRC32; char fs_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 }; + char dev_uuid[BTRFS_UUID_UNPARSED_SIZE] = { 0 }; u32 nodesize = 0; bool nodesize_forced = false; u32 sectorsize = 0; @@ -1187,6 +1189,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv) GETOPT_VAL_SHRINK = GETOPT_VAL_FIRST, GETOPT_VAL_CHECKSUM, GETOPT_VAL_GLOBAL_ROOTS, + GETOPT_VAL_DEVICE_UUID, }; static const struct option long_options[] = { { "byte-count", required_argument, NULL, 'b' }, @@ -1208,6 +1211,8 @@ int BOX_MAIN(mkfs)(int argc, char **argv) { "features", required_argument, NULL, 'O' }, { "runtime-features", required_argument, NULL, 'R' }, { "uuid", required_argument, NULL, 'U' }, + { "device-uuid", required_argument, NULL, + GETOPT_VAL_DEVICE_UUID }, { "quiet", 0, NULL, 'q' }, { "verbose", 0, NULL, 'v' }, { "shrink", no_argument, NULL, GETOPT_VAL_SHRINK }, @@ -1332,6 +1337,9 @@ int BOX_MAIN(mkfs)(int argc, char **argv) case 'q': bconf_be_quiet(); break; + case GETOPT_VAL_DEVICE_UUID: + strncpy(dev_uuid, optarg, BTRFS_UUID_UNPARSED_SIZE - 1); + break; case GETOPT_VAL_SHRINK: shrink_rootdir = true; break; @@ -1373,6 +1381,10 @@ int BOX_MAIN(mkfs)(int argc, char **argv) error("the option -r is limited to a single device"); goto error; } + if (strlen(dev_uuid) != 0 && device_count > 1) { + error("the option --device-uuid is limited to a single device"); + goto error; + } if (shrink_rootdir && source_dir == NULL) { error("the option --shrink must be used with --rootdir"); goto error; @@ -1733,6 +1745,7 @@ int BOX_MAIN(mkfs)(int argc, char **argv) mkfs_cfg.label = label; memcpy(mkfs_cfg.fs_uuid, fs_uuid, sizeof(mkfs_cfg.fs_uuid)); + memcpy(mkfs_cfg.dev_uuid, dev_uuid, sizeof(mkfs_cfg.dev_uuid)); mkfs_cfg.num_bytes = dev_block_count; mkfs_cfg.nodesize = nodesize; mkfs_cfg.sectorsize = sectorsize;