forked from Minki/linux
btrfs: sysfs: export chunk size in space infos
Add new sysfs knob /sys/fs/btrfs/<uuid>/allocation/<type>/chunk_size. This allows to query the chunk size and also set the chunk size. Constraints: - can be changed by root only - system chunk size can't be set - maximum chunk size is 10% of the filesystem size - final value is rounded down to a multiple of 256M - cannot be set on zoned filesystem Note, that rounding and the 10% clamp will result to a different value on filesystems smaller than 10G, typically 768M. Signed-off-by: Stefan Roesch <shr@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> [ Changes to original submission: - document setting constraints - drop read-only requirement - drop unnecessary error messages - fix return values of _store callback - use memparse for the value - fix rounding down to 256M ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f6fca3917b
commit
19fc516a51
@ -21,6 +21,7 @@
|
||||
#include "space-info.h"
|
||||
#include "block-group.h"
|
||||
#include "qgroup.h"
|
||||
#include "misc.h"
|
||||
|
||||
/*
|
||||
* Structure name Path
|
||||
@ -92,6 +93,7 @@ static struct btrfs_feature_attr btrfs_attr_features_##_name = { \
|
||||
|
||||
static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj);
|
||||
static inline struct btrfs_fs_devices *to_fs_devs(struct kobject *kobj);
|
||||
static struct kobject *get_btrfs_kobj(struct kobject *kobj);
|
||||
|
||||
static struct btrfs_feature_attr *to_btrfs_feature_attr(struct kobj_attribute *a)
|
||||
{
|
||||
@ -709,6 +711,66 @@ static ssize_t btrfs_space_info_show_##field(struct kobject *kobj, \
|
||||
} \
|
||||
BTRFS_ATTR(space_info, field, btrfs_space_info_show_##field)
|
||||
|
||||
static ssize_t btrfs_chunk_size_show(struct kobject *kobj,
|
||||
struct kobj_attribute *a, char *buf)
|
||||
{
|
||||
struct btrfs_space_info *sinfo = to_space_info(kobj);
|
||||
|
||||
return sysfs_emit(buf, "%llu\n", READ_ONCE(sinfo->chunk_size));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
static ssize_t btrfs_chunk_size_store(struct kobject *kobj,
|
||||
struct kobj_attribute *a,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct btrfs_space_info *space_info = to_space_info(kobj);
|
||||
struct btrfs_fs_info *fs_info = to_fs_info(get_btrfs_kobj(kobj));
|
||||
char *retptr;
|
||||
u64 val;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!fs_info->fs_devices)
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
|
||||
val = memparse(buf, &retptr);
|
||||
/* There could be trailing '\n', also catch any typos after the value */
|
||||
retptr = skip_spaces(retptr);
|
||||
if (*retptr != 0 || val == 0)
|
||||
return -EINVAL;
|
||||
|
||||
val = min(val, BTRFS_MAX_DATA_CHUNK_SIZE);
|
||||
|
||||
/* Limit stripe size to 10% of available space. */
|
||||
val = min(div_factor(fs_info->fs_devices->total_rw_bytes, 1), val);
|
||||
|
||||
/* Must be multiple of 256M. */
|
||||
val &= ~((u64)SZ_256M - 1);
|
||||
|
||||
/* Must be at least 256M. */
|
||||
if (val < SZ_256M)
|
||||
return -EINVAL;
|
||||
|
||||
btrfs_update_space_info_chunk_size(space_info, val);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
SPACE_INFO_ATTR(flags);
|
||||
SPACE_INFO_ATTR(total_bytes);
|
||||
SPACE_INFO_ATTR(bytes_used);
|
||||
@ -719,6 +781,7 @@ SPACE_INFO_ATTR(bytes_readonly);
|
||||
SPACE_INFO_ATTR(bytes_zone_unusable);
|
||||
SPACE_INFO_ATTR(disk_used);
|
||||
SPACE_INFO_ATTR(disk_total);
|
||||
BTRFS_ATTR_RW(space_info, chunk_size, btrfs_chunk_size_show, btrfs_chunk_size_store);
|
||||
|
||||
static ssize_t btrfs_sinfo_bg_reclaim_threshold_show(struct kobject *kobj,
|
||||
struct kobj_attribute *a,
|
||||
@ -773,6 +836,7 @@ static struct attribute *space_info_attrs[] = {
|
||||
BTRFS_ATTR_PTR(space_info, disk_used),
|
||||
BTRFS_ATTR_PTR(space_info, disk_total),
|
||||
BTRFS_ATTR_PTR(space_info, bg_reclaim_threshold),
|
||||
BTRFS_ATTR_PTR(space_info, chunk_size),
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(space_info);
|
||||
@ -1140,6 +1204,16 @@ static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
|
||||
return to_fs_devs(kobj)->fs_info;
|
||||
}
|
||||
|
||||
static struct kobject *get_btrfs_kobj(struct kobject *kobj)
|
||||
{
|
||||
while (kobj) {
|
||||
if (kobj->ktype == &btrfs_ktype)
|
||||
return kobj;
|
||||
kobj = kobj->parent;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define NUM_FEATURE_BITS 64
|
||||
#define BTRFS_FEATURE_NAME_MAX 13
|
||||
static char btrfs_unknown_feature_names[FEAT_MAX][NUM_FEATURE_BITS][BTRFS_FEATURE_NAME_MAX];
|
||||
|
Loading…
Reference in New Issue
Block a user