From: Auke Kok Date: Tue, 27 May 2025 19:34:43 +0000 (-0700) Subject: libblkid: Add scoutfs filesystem. X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=a9a298ca7e3bfff568b1d0e4958bd0aa47b8459a;p=thirdparty%2Futil-linux.git libblkid: Add scoutfs filesystem. The scoutfs filesystem is maintained out-of-tree, but current enough that we want to submit it for inclusion in libblkid - there's a few users out there that would benefit from being able to have lsblk aid in diagnosing and identifying. For more information about scoutfs, visit the github page here: https://github.com/versity/scoutfs Test images are provided for both data and meta devices. These were taken from validation samples. The wiper is set to only wipe a minute part of the filesystem - basically only the superblock. This is adequately destructive. Signed-off-by: Auke Kok --- diff --git a/libblkid/meson.build b/libblkid/meson.build index 2a23b8dbc..2435692cd 100644 --- a/libblkid/meson.build +++ b/libblkid/meson.build @@ -93,6 +93,7 @@ lib_blkid_sources = ''' src/superblocks/promise_raid.c src/superblocks/reiserfs.c src/superblocks/romfs.c + src/superblocks/scoutfs.c src/superblocks/silicon_raid.c src/superblocks/squashfs.c src/superblocks/stratis.c diff --git a/libblkid/src/Makemodule.am b/libblkid/src/Makemodule.am index 78ebb2225..321d3fbe9 100644 --- a/libblkid/src/Makemodule.am +++ b/libblkid/src/Makemodule.am @@ -83,6 +83,7 @@ libblkid_la_SOURCES = \ libblkid/src/superblocks/promise_raid.c \ libblkid/src/superblocks/reiserfs.c \ libblkid/src/superblocks/romfs.c \ + libblkid/src/superblocks/scoutfs.c \ libblkid/src/superblocks/silicon_raid.c \ libblkid/src/superblocks/squashfs.c \ libblkid/src/superblocks/stratis.c \ diff --git a/libblkid/src/superblocks/scoutfs.c b/libblkid/src/superblocks/scoutfs.c new file mode 100644 index 000000000..b89794523 --- /dev/null +++ b/libblkid/src/superblocks/scoutfs.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2025 Versity, Inc. + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ + +#include + +#include "superblocks.h" +#include "crc32c.h" + +enum { + SCOUTFS_TYPE_DATA, + SCOUTFS_TYPE_METADATA, +}; + +#define SCOUTFS_UUID_BYTES 16 + +#define SCOUTFS_BLOCK_SM_SHIFT 12 +#define SCOUTFS_BLOCK_SM_SIZE (1 << SCOUTFS_BLOCK_SM_SHIFT) +#define SCOUTFS_BLOCK_LG_SHIFT 16 +#define SCOUTFS_BLOCK_LG_SIZE (1 << SCOUTFS_BLOCK_LG_SHIFT) + +struct scoutfs_block_header { + uint32_t crc; + uint32_t magic; + uint64_t fsid; + uint64_t seq; + uint64_t blkno; +}; + +#define SCOUTFS_FLAG_IS_META_BDEV 0x01 + +struct scoutfs_super_block { + struct scoutfs_block_header hdr; + uint64_t id; + uint64_t fmt_vers; + uint64_t flags; + uint8_t uuid[SCOUTFS_UUID_BYTES]; + /* rest omitted */ +}; + +static int probe_scoutfs(blkid_probe pr, const struct blkid_idmag *mag) +{ + const struct scoutfs_super_block *sb; + const unsigned char *buf; + uint32_t crc; + + /* scoutfs_super_block is always in a SCOUTFS_BLOCK_SM_SIZE block */ + buf = blkid_probe_get_sb_buffer(pr, mag, SCOUTFS_BLOCK_SM_SIZE); + if (buf == NULL) + return errno ? -errno : 1; + sb = (struct scoutfs_super_block *)buf; + + crc = crc32c(~0, (char *)buf + sizeof(sb->hdr.crc), SCOUTFS_BLOCK_SM_SIZE - sizeof(sb->hdr.crc)); + if (!blkid_probe_verify_csum(pr, crc, le32_to_cpu(sb->hdr.crc))) + return BLKID_PROBE_NONE; + + blkid_probe_sprintf_version(pr, "%"PRIu64, le64_to_cpu(sb->fmt_vers)); + blkid_probe_set_uuid(pr, sb->uuid); + blkid_probe_sprintf_value(pr, "FSID", "%016"PRIx64, le64_to_cpu(sb->hdr.fsid)); + blkid_probe_set_wiper(pr, 0, 0x10000); + + if (mag->hint == SCOUTFS_TYPE_METADATA) { + /* meta blocksize is 64k blocks */ + blkid_probe_set_fsblocksize(pr, SCOUTFS_BLOCK_LG_SIZE); + blkid_probe_set_block_size(pr, SCOUTFS_BLOCK_LG_SIZE); + + if (!(le64_to_cpu(sb->flags) & SCOUTFS_FLAG_IS_META_BDEV)) + return BLKID_PROBE_NONE; + } else { + /* data blocksize is 4k blocks */ + blkid_probe_set_fsblocksize(pr, SCOUTFS_BLOCK_SM_SIZE); + blkid_probe_set_block_size(pr, SCOUTFS_BLOCK_SM_SIZE); + + if (le64_to_cpu(sb->flags) & SCOUTFS_FLAG_IS_META_BDEV) + return BLKID_PROBE_NONE; + } + + return 0; +} + +/* + * Scoutfs has the same magic value for the data and the meta devices, + * and the superblock format used in them is identical, except for the + * flag used to indicate the meta device superblock. + */ +const struct blkid_idinfo scoutfs_meta_idinfo = +{ + .name = "scoutfs_meta", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_scoutfs, + .minsz = 0x20000, + .magics = { + { + .magic = "\x8b\x42\x3c\x10", + .hint = SCOUTFS_TYPE_METADATA, + .kboff = 64, + .sboff = 4, + .len = 4, + }, + { NULL } + } +}; + +const struct blkid_idinfo scoutfs_data_idinfo = +{ + .name = "scoutfs_data", + .usage = BLKID_USAGE_FILESYSTEM, + .probefunc = probe_scoutfs, + .minsz = 0x20000, + .magics = { + { + .magic = "\x8b\x42\x3c\x10", + .hint = SCOUTFS_TYPE_DATA, + .kboff = 64, + .sboff = 4, + .len = 4, + }, + { NULL } + } +}; diff --git a/libblkid/src/superblocks/superblocks.c b/libblkid/src/superblocks/superblocks.c index 82047f186..0fd9cc5f6 100644 --- a/libblkid/src/superblocks/superblocks.c +++ b/libblkid/src/superblocks/superblocks.c @@ -158,6 +158,8 @@ static const struct blkid_idinfo *idinfos[] = &refs_idinfo, &cramfs_idinfo, &romfs_idinfo, + &scoutfs_meta_idinfo, + &scoutfs_data_idinfo, &minix_idinfo, &gfs_idinfo, &gfs2_idinfo, diff --git a/libblkid/src/superblocks/superblocks.h b/libblkid/src/superblocks/superblocks.h index 140261eae..af3eb2fa3 100644 --- a/libblkid/src/superblocks/superblocks.h +++ b/libblkid/src/superblocks/superblocks.h @@ -46,6 +46,8 @@ extern const struct blkid_idinfo exfs_idinfo; extern const struct blkid_idinfo gfs_idinfo; extern const struct blkid_idinfo gfs2_idinfo; extern const struct blkid_idinfo romfs_idinfo; +extern const struct blkid_idinfo scoutfs_meta_idinfo; +extern const struct blkid_idinfo scoutfs_data_idinfo; extern const struct blkid_idinfo ocfs_idinfo; extern const struct blkid_idinfo ocfs2_idinfo; extern const struct blkid_idinfo oracleasm_idinfo; diff --git a/tests/expected/blkid/low-probe-scoutfs_data b/tests/expected/blkid/low-probe-scoutfs_data new file mode 100644 index 000000000..28767e846 --- /dev/null +++ b/tests/expected/blkid/low-probe-scoutfs_data @@ -0,0 +1,8 @@ +ID_FS_BLOCK_SIZE=4096 +ID_FS_FSBLOCKSIZE=4096 +ID_FS_FSID=7ccb1220c4306893 +ID_FS_TYPE=scoutfs_data +ID_FS_USAGE=filesystem +ID_FS_UUID=bf33ff54-5260-46ee-9505-c369e4c49882 +ID_FS_UUID_ENC=bf33ff54-5260-46ee-9505-c369e4c49882 +ID_FS_VERSION=2 diff --git a/tests/expected/blkid/low-probe-scoutfs_meta b/tests/expected/blkid/low-probe-scoutfs_meta new file mode 100644 index 000000000..c050abab4 --- /dev/null +++ b/tests/expected/blkid/low-probe-scoutfs_meta @@ -0,0 +1,8 @@ +ID_FS_BLOCK_SIZE=65536 +ID_FS_FSBLOCKSIZE=65536 +ID_FS_FSID=7ccb1220c4306893 +ID_FS_TYPE=scoutfs_meta +ID_FS_USAGE=filesystem +ID_FS_UUID=bf33ff54-5260-46ee-9505-c369e4c49882 +ID_FS_UUID_ENC=bf33ff54-5260-46ee-9505-c369e4c49882 +ID_FS_VERSION=2 diff --git a/tests/ts/blkid/images-fs/scoutfs_data.img.xz b/tests/ts/blkid/images-fs/scoutfs_data.img.xz new file mode 100644 index 000000000..5b29fb954 Binary files /dev/null and b/tests/ts/blkid/images-fs/scoutfs_data.img.xz differ diff --git a/tests/ts/blkid/images-fs/scoutfs_meta.img.xz b/tests/ts/blkid/images-fs/scoutfs_meta.img.xz new file mode 100644 index 000000000..404316556 Binary files /dev/null and b/tests/ts/blkid/images-fs/scoutfs_meta.img.xz differ