From 82611f51a5dcb138af307d7834fdfa2e3516938f Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Thu, 15 Apr 2021 13:30:11 +0800 Subject: [PATCH] btrfs-progs: mkfs: only output the warning if the sectorsize is not supported Currently mkfs.btrfs will output a warning message if the sectorsize is not the same as page size: WARNING: the filesystem may not be mountable, sectorsize 4096 doesn't match page size 65536 But since btrfs subpage support for 64K page size is coming, this output is populating the golden output of fstests, causing tons of false alerts. This patch will teach mkfs.btrfs to check /sys/fs/btrfs/features/supported_sectorsizes and check if the sector size is supported. Then only output above warning message if the sector size is not supported or the file is not found (ie. kernel does not export the file yet). Reviewed-by: Boris Burkov Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- common/fsfeatures.c | 49 ++++++++++++++++++++++++++++++++++++++++++++- common/utils.c | 15 ++++++++++++++ common/utils.h | 1 + 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/common/fsfeatures.c b/common/fsfeatures.c index 569208a9..ec3d967e 100644 --- a/common/fsfeatures.c +++ b/common/fsfeatures.c @@ -327,8 +327,50 @@ u32 get_running_kernel_version(void) return version; } + +/* + * The buffer size is strlen of "4096 8192 16384 32768 65536", which is 28, + * then round up to 32. + */ +#define SUPPORTED_SECTORSIZE_BUF_SIZE 32 + +/* + * Check if current kernel supports the given size + */ +static bool check_supported_sectorsize(u32 sectorsize) +{ + char supported_buf[SUPPORTED_SECTORSIZE_BUF_SIZE] = { 0 }; + char sectorsize_buf[SUPPORTED_SECTORSIZE_BUF_SIZE] = { 0 }; + char *this_char; + char *save_ptr = NULL; + int fd; + int ret; + + fd = sysfs_open_file("features/supported_sectorsizes"); + if (fd < 0) + return false; + ret = sysfs_read_file(fd, supported_buf, SUPPORTED_SECTORSIZE_BUF_SIZE); + close(fd); + if (ret < 0) + return false; + snprintf(sectorsize_buf, SUPPORTED_SECTORSIZE_BUF_SIZE, "%u", sectorsize); + + for (this_char = strtok_r(supported_buf, " ", &save_ptr); + this_char != NULL; + this_char = strtok_r(NULL, " ", &save_ptr)) { + /* + * Also check the terminal '\0' to handle cases like + * "4096" and "40960". + */ + if (!strncmp(this_char, sectorsize_buf, strlen(sectorsize_buf) + 1)) + return true; + } + return false; +} + int btrfs_check_sectorsize(u32 sectorsize) { + bool sectorsize_checked = false; u32 page_size = (u32)sysconf(_SC_PAGESIZE); if (!is_power_of_2(sectorsize)) { @@ -340,7 +382,12 @@ int btrfs_check_sectorsize(u32 sectorsize) sectorsize); return -EINVAL; } - if (page_size != sectorsize) + if (page_size == sectorsize) + sectorsize_checked = true; + else + sectorsize_checked = check_supported_sectorsize(sectorsize); + + if (!sectorsize_checked) warning( "the filesystem may not be mountable, sectorsize %u doesn't match page size %u", sectorsize, page_size); diff --git a/common/utils.c b/common/utils.c index 57e41432..821dce34 100644 --- a/common/utils.c +++ b/common/utils.c @@ -2205,6 +2205,21 @@ int sysfs_open_fsid_file(int fd, const char *filename) return open(sysfs_file, O_RDONLY); } +/* + * Open a file in the toplevel sysfs directory and return the file descriptor + * or error. + */ +int sysfs_open_file(const char *name) +{ + char path[PATH_MAX]; + int ret; + + ret = path_cat_out(path, "/sys/fs/btrfs", name); + if (ret < 0) + return ret; + return open(path, O_RDONLY); +} + /* * Read up to @size bytes to @buf from @fd */ diff --git a/common/utils.h b/common/utils.h index c38bdb08..00340723 100644 --- a/common/utils.h +++ b/common/utils.h @@ -168,6 +168,7 @@ void init_rand_seed(u64 seed); char *btrfs_test_for_multiple_profiles(int fd); int btrfs_warn_multiple_profiles(int fd); +int sysfs_open_file(const char *name); int sysfs_open_fsid_file(int fd, const char *filename); int sysfs_read_file(int fd, char *buf, size_t size);