linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Sterba <dsterba@suse.cz>
To: Stefan Roesch <shr@fb.com>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH v1 2/3] btrfs: expose chunk size in sysfs.
Date: Mon, 4 Apr 2022 18:52:01 +0200	[thread overview]
Message-ID: <20220404165201.GT15609@twin.jikos.cz> (raw)
In-Reply-To: <20220208193122.492533-3-shr@fb.com>

On Tue, Feb 08, 2022 at 11:31:21AM -0800, Stefan Roesch wrote:
> This adds a new sysfs entry in /sys/fs/btrfs/<uuid>/allocation/<block
> type>/chunk_size. This allows to query the chunk size and also set the
> chunk size.
> 
> Signed-off-by: Stefan Roesch <shr@fb.com>
> ---
>  fs/btrfs/sysfs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 94 insertions(+)
> 
> diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
> index beb7f72d50b8..ca337117f15b 100644
> --- a/fs/btrfs/sysfs.c
> +++ b/fs/btrfs/sysfs.c
> @@ -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 inline struct kobject *get_btrfs_kobj(struct kobject *kobj);
>  
>  static struct btrfs_feature_attr *to_btrfs_feature_attr(struct kobj_attribute *a)
>  {
> @@ -708,6 +710,81 @@ static ssize_t btrfs_space_info_show_##field(struct kobject *kobj,	\
>  }									\
>  BTRFS_ATTR(space_info, field, btrfs_space_info_show_##field)
>  
> +/*
> + * Return space info chunk size.
> + */

Comment not necessary.

> +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", atomic64_read(&sinfo->chunk_size));
> +}
> +
> +/*
> + * Store new user supplied chunk size in space info.
> + *
> + * Note: If the new chunk size value is larger than 10% of free space it is
> + *       reduced to match that limit.
> + */
> +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));
> +	u64 val;
> +	int ret;
> +
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
> +	if (!fs_info) {
> +		pr_err("couldn't get fs_info\n");

What's the reason for such error message? I would end up in the system
log without any context so it does not bring any value to user nor does
it tell what wen wrong.

Checking other functions, there's no such check in most of them and I
don't think it's needed, the filesystem can't be unmounted with open
file references to sysfs.

> +		return -EPERM;
> +	}
> +
> +	if (sb_rdonly(fs_info->sb))
> +		return -EROFS;
> +
> +	if (!fs_info->fs_devices)
> +		return -EINVAL;
> +
> +	if (btrfs_is_zoned(fs_info))
> +		return -EINVAL;
> +
> +	if (!space_info) {
> +		btrfs_err(fs_info, "couldn't get space_info\n");

Same as the error message above.

Also I'm not sure there could be a NULL space_info, it's one of the core
data structures used all the time.

> +		return -EPERM;
> +	}
> +
> +	/* System block type must not be changed. */
> +	if (space_info->flags & BTRFS_BLOCK_GROUP_SYSTEM)
> +		return -EINVAL;

This would probably be EPERM, EINVAL is for invalid values (like out of
range).

> +
> +	ret = kstrtoull(buf, 10, &val);

As this is supposed to be used by humans, it's better to use memparse
that also translates the K/M/G suffix so it's easy to write '256M' etc.

> +	if (ret)
> +		return ret;
> +
> +	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 &= ~(SZ_256M - 1);

Where does this requirement come from?

> +
> +	/* Must be at least 256M. */
> +	if (val < SZ_256M)
> +		return -EINVAL;
> +
> +	btrfs_update_space_info_chunk_size(space_info, val);
> +
> +	return val;
> +}
> +
>  SPACE_INFO_ATTR(flags);
>  SPACE_INFO_ATTR(total_bytes);
>  SPACE_INFO_ATTR(bytes_used);
> @@ -718,6 +795,8 @@ 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);
>  
>  /*
>   * Allocation information about block group types.
> @@ -735,6 +814,7 @@ static struct attribute *space_info_attrs[] = {
>  	BTRFS_ATTR_PTR(space_info, bytes_zone_unusable),
>  	BTRFS_ATTR_PTR(space_info, disk_used),
>  	BTRFS_ATTR_PTR(space_info, disk_total),
> +	BTRFS_ATTR_PTR(space_info, chunk_size),
>  	NULL,
>  };
>  ATTRIBUTE_GROUPS(space_info);
> @@ -1099,6 +1179,20 @@ static inline struct btrfs_fs_info *to_fs_info(struct kobject *kobj)
>  	return to_fs_devs(kobj)->fs_info;
>  }
>  
> +/*
> + * Get btrfs sysfs kobject.
> + */
> +static inline struct kobject *get_btrfs_kobj(struct kobject *kobj)
> +{
> +	while (kobj) {
> +		if (kobj->ktype == &btrfs_ktype)
> +			return kobj;
> +		kobj = kobj->parent;
> +	}
> +
> +	return NULL;
> +}

There's the to_fs_info helper to get fs_info from any kobj, why is
get_btrfs_kobj needed to traverse back?

  reply	other threads:[~2022-04-04 21:25 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-08 19:31 [PATCH v1 0/3] btrfs: add sysfs switch to get/set metadata size Stefan Roesch
2022-02-08 19:31 ` [PATCH v1 1/3] btrfs: store chunk size in space-info struct Stefan Roesch
2022-04-04 16:36   ` David Sterba
2022-06-16 20:53     ` Stefan Roesch
2022-02-08 19:31 ` [PATCH v1 2/3] btrfs: expose chunk size in sysfs Stefan Roesch
2022-04-04 16:52   ` David Sterba [this message]
2022-06-16 20:56     ` Stefan Roesch
2022-02-08 19:31 ` [PATCH v1 3/3] btrfs: add force_chunk_alloc sysfs entry to force allocation Stefan Roesch
2022-04-04 17:02   ` David Sterba
2022-06-16 20:59     ` Stefan Roesch
2022-06-17 14:14       ` David Sterba
2022-02-28 19:30 ` [PATCH v1 0/3] btrfs: add sysfs switch to get/set metadata size Josef Bacik
2022-04-04 16:31 ` David Sterba
2022-05-27 13:34   ` David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220404165201.GT15609@twin.jikos.cz \
    --to=dsterba@suse.cz \
    --cc=kernel-team@fb.com \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=shr@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).