Commit d728f2e5 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

btrfs: simplify support block size check



Currently we manually check the block size against 3 different values:

- 4K
- PAGE_SIZE
- MIN_BLOCKSIZE

Those 3 values can match or differ from each other.  This makes it
pretty complex to output the supported block sizes.

Considering we're going to add block size > page size support soon, this
can make the support block size sysfs attribute much harder to
implement.

To make it easier, factor out a helper, btrfs_supported_blocksize() to
do a simple check for the block size.

Then utilize it in the two locations:

- btrfs_validate_super()
  This is very straightforward

- supported_sectorsizes_show()
  Iterate through all valid block sizes, and only output supported ones.

  This is to make future full range block sizes support much easier.

Reviewed-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 0a6dcd42
Loading
Loading
Loading
Loading
+1 −15
Original line number Diff line number Diff line
@@ -2438,21 +2438,7 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info,
		ret = -EINVAL;
	}

	/*
	 * We only support at most 3 sectorsizes: 4K, PAGE_SIZE, MIN_BLOCKSIZE.
	 *
	 * For 4K page sized systems with non-debug builds, all 3 matches (4K).
	 * For 4K page sized systems with debug builds, there are two block sizes
	 * supported. (4K and 2K)
	 *
	 * We can support 16K sectorsize with 64K page size without problem,
	 * but such sectorsize/pagesize combination doesn't make much sense.
	 * 4K will be our future standard, PAGE_SIZE is supported from the very
	 * beginning.
	 */
	if (sectorsize > PAGE_SIZE || (sectorsize != SZ_4K &&
				       sectorsize != PAGE_SIZE &&
				       sectorsize != BTRFS_MIN_BLOCKSIZE)) {
	if (!btrfs_supported_blocksize(sectorsize)) {
		btrfs_err(fs_info,
			"sectorsize %llu not yet supported for page size %lu",
			sectorsize, PAGE_SIZE);
+27 −0
Original line number Diff line number Diff line
@@ -54,6 +54,33 @@ size_t __attribute_const__ btrfs_get_num_csums(void)
	return ARRAY_SIZE(btrfs_csums);
}

/*
 * We support the following block sizes for all systems:
 *
 * - 4K
 *   This is the most common block size. For PAGE SIZE > 4K cases the subage
 *   mode is used.
 *
 * - PAGE_SIZE
 *   The straightforward block size to support.
 *
 * And extra support for the following block sizes based on the kernel config:
 *
 * - MIN_BLOCKSIZE
 *   This is either 4K (regular builds) or 2K (debug builds)
 *   This allows testing subpage routines on x86_64.
 */
bool __attribute_const__ btrfs_supported_blocksize(u32 blocksize)
{
	/* @blocksize should be validated first. */
	ASSERT(is_power_of_2(blocksize) && blocksize >= BTRFS_MIN_BLOCKSIZE &&
	       blocksize <= BTRFS_MAX_BLOCKSIZE);

	if (blocksize == PAGE_SIZE || blocksize == SZ_4K || blocksize == BTRFS_MIN_BLOCKSIZE)
		return true;
	return false;
}

/*
 * Start exclusive operation @type, return true on success.
 */
+3 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ struct btrfs_space_info;
#define BTRFS_MIN_BLOCKSIZE	(SZ_4K)
#endif

#define BTRFS_MAX_BLOCKSIZE	(SZ_64K)

#define BTRFS_MAX_EXTENT_SIZE SZ_128M

#define BTRFS_OLDEST_GENERATION	0ULL
@@ -997,6 +999,7 @@ static inline unsigned int btrfs_blocks_per_folio(const struct btrfs_fs_info *fs
	return folio_size(folio) >> fs_info->sectorsize_bits;
}

bool __attribute_const__ btrfs_supported_blocksize(u32 blocksize);
bool btrfs_exclop_start(struct btrfs_fs_info *fs_info,
			enum btrfs_exclusive_operation type);
bool btrfs_exclop_start_try_lock(struct btrfs_fs_info *fs_info,
+10 −6
Original line number Diff line number Diff line
@@ -409,13 +409,17 @@ static ssize_t supported_sectorsizes_show(struct kobject *kobj,
					  char *buf)
{
	ssize_t ret = 0;
	bool has_output = false;

	if (BTRFS_MIN_BLOCKSIZE != SZ_4K && BTRFS_MIN_BLOCKSIZE != PAGE_SIZE)
		ret += sysfs_emit_at(buf, ret, "%u ", BTRFS_MIN_BLOCKSIZE);
	if (PAGE_SIZE > SZ_4K)
		ret += sysfs_emit_at(buf, ret, "%u ", SZ_4K);
	ret += sysfs_emit_at(buf, ret, "%lu\n", PAGE_SIZE);

	for (u32 cur = BTRFS_MIN_BLOCKSIZE; cur <= BTRFS_MAX_BLOCKSIZE; cur *= 2) {
		if (!btrfs_supported_blocksize(cur))
			continue;
		if (has_output)
			ret += sysfs_emit_at(buf, ret, " ");
		ret += sysfs_emit_at(buf, ret, "%u", cur);
		has_output = true;
	}
	ret += sysfs_emit_at(buf, ret, "\n");
	return ret;
}
BTRFS_ATTR(static_feature, supported_sectorsizes,