* Store new chunk size in space info. Can be called on a read-only filesystem.
*
* If the new chunk size value is larger than 10% of free space it is reduced
- * to match that limit. Alignment must be to 256M and the system chunk size
- * cannot be set.
+ * to match that limit. Alignment must be to 256M for data and metadata chunks,
+ * 32M for system chunks.
*/
static ssize_t btrfs_chunk_size_store(struct kobject *kobj,
struct kobj_attribute *a,
struct btrfs_fs_info *fs_info = to_fs_info(get_btrfs_kobj(kobj));
char *retptr;
u64 val;
+ u64 min_size;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (btrfs_is_zoned(fs_info))
return -EINVAL;
- /* System block type must not be changed. */
- if (space_info->flags & BTRFS_BLOCK_GROUP_SYSTEM)
- return -EPERM;
+ /* System block type must not be smaller than minimum. */
+ if (space_info->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
+ min_size = SZ_32M;
+ } else {
+ min_size = SZ_256M;
+ }
val = memparse(buf, &retptr);
/* There could be trailing '\n', also catch any typos after the value */
/* Limit stripe size to 10% of available space. */
val = min(mult_perc(fs_info->fs_devices->total_rw_bytes, 10), val);
- /* Must be multiple of 256M. */
- val &= ~((u64)SZ_256M - 1);
+ /* Must be multiple of min size. */
+ val &= ~((u64)min_size - 1);
- /* Must be at least 256M. */
- if (val < SZ_256M)
+ /* Must be at least 256M for data, 32M for system. */
+ if (val < min_size)
return -EINVAL;
btrfs_update_space_info_chunk_size(space_info, val);