From: Jeff Mahoney <jeffm@suse.com>
To: linux-btrfs@vger.kernel.org
Cc: dsterba@suse.com
Subject: Re: [patch 10/13] btrfs: publish allocation data in sysfs
Date: Tue, 29 Oct 2013 14:49:15 -0400 [thread overview]
Message-ID: <5270032B.3050508@suse.com> (raw)
In-Reply-To: <20131021212008.047727368@suse.com>
[-- Attachment #1: Type: text/plain, Size: 13342 bytes --]
On 10/21/13, 5:19 PM, Jeff Mahoney wrote:
> While trying to debug ENOSPC issues, it's helpful to understand what the
> kernel's view of the available space is. We export this information
> via ioctl, but sysfs files are more easily used.
>
> Signed-off-by: Jeff Mahoney <jeffm@suse.com>
> ---
> fs/btrfs/ctree.h | 5 +
> fs/btrfs/extent-tree.c | 72 ++++++++++++++++++++++-
> fs/btrfs/sysfs.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++
> fs/btrfs/sysfs.h | 8 ++
> 4 files changed, 228 insertions(+), 5 deletions(-)
>
> --- a/fs/btrfs/ctree.h 2013-10-21 16:10:00.212037722 -0400
> +++ b/fs/btrfs/ctree.h 2013-10-21 16:10:02.743982088 -0400
> @@ -1143,6 +1143,9 @@ struct btrfs_space_info {
> spinlock_t lock;
> struct rw_semaphore groups_sem;
> wait_queue_head_t wait;
> +
> + struct kobject kobj;
> + struct kobject block_group_kobjs[BTRFS_NR_RAID_TYPES];
> };
>
> #define BTRFS_BLOCK_RSV_GLOBAL 1
> @@ -1518,6 +1521,7 @@ struct btrfs_fs_info {
> int thread_pool_size;
>
> struct kobject super_kobj;
> + struct kobject *space_info_kobj;
> struct completion kobj_unregister;
> int do_barriers;
> int closing;
> @@ -3171,6 +3175,7 @@ struct btrfs_block_group_cache *btrfs_lo
> struct btrfs_fs_info *info,
> u64 bytenr);
> void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
> +int get_block_group_index(struct btrfs_block_group_cache *cache);
> struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
> struct btrfs_root *root, u32 blocksize,
> u64 parent, u64 root_objectid,
> --- a/fs/btrfs/extent-tree.c 2013-10-21 16:09:33.476623940 -0400
> +++ b/fs/btrfs/extent-tree.c 2013-10-21 16:10:02.751981911 -0400
> @@ -36,6 +36,7 @@
> #include "locking.h"
> #include "free-space-cache.h"
> #include "math.h"
> +#include "sysfs.h"
>
> #undef SCRAMBLE_DELAYED_REFS
>
> @@ -3389,6 +3390,13 @@ int btrfs_extent_readonly(struct btrfs_r
> return readonly;
> }
>
> +static const char * const alloc_names[] = {
> + "data",
> + "system",
> + "mixed",
> + "metadata",
> +};
> +
Sigh. There was a missing quilt refresh here. This obviously doesn't work.
-Jeff
> static int update_space_info(struct btrfs_fs_info *info, u64 flags,
> u64 total_bytes, u64 bytes_used,
> struct btrfs_space_info **space_info)
> @@ -3444,11 +3452,21 @@ static int update_space_info(struct btrf
> found->chunk_alloc = 0;
> found->flush = 0;
> init_waitqueue_head(&found->wait);
> +
> + ret = kobject_init_and_add(&found->kobj, &space_info_ktype,
> + info->space_info_kobj, "%s",
> + alloc_names[found->flags - 1]);
> + if (ret) {
> + kfree(found);
> + return ret;
> + }
> +
> *space_info = found;
> list_add_rcu(&found->list, &info->space_info);
> if (flags & BTRFS_BLOCK_GROUP_DATA)
> info->data_sinfo = found;
> - return 0;
> +
> + return ret;
> }
>
> static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
> @@ -6090,11 +6108,29 @@ int __get_raid_index(u64 flags)
> return BTRFS_RAID_SINGLE; /* BTRFS_BLOCK_GROUP_SINGLE */
> }
>
> -static int get_block_group_index(struct btrfs_block_group_cache *cache)
> +int get_block_group_index(struct btrfs_block_group_cache *cache)
> {
> return __get_raid_index(cache->flags);
> }
>
> +static const char *btrfs_raid_type_names[BTRFS_NR_RAID_TYPES] = {
> + [BTRFS_RAID_RAID10] = "raid10",
> + [BTRFS_RAID_RAID1] = "raid1",
> + [BTRFS_RAID_DUP] = "dup",
> + [BTRFS_RAID_RAID0] = "raid0",
> + [BTRFS_RAID_SINGLE] = "single",
> + [BTRFS_RAID_RAID5] = "raid5",
> + [BTRFS_RAID_RAID6] = "raid6",
> +};
> +
> +const char *get_raid_name(enum btrfs_raid_types type)
> +{
> + if (type >= BTRFS_NR_RAID_TYPES)
> + return NULL;
> +
> + return btrfs_raid_type_names[type];
> +}
> +
> enum btrfs_loop_type {
> LOOP_CACHING_NOWAIT = 0,
> LOOP_CACHING_WAIT = 1,
> @@ -8272,6 +8308,8 @@ int btrfs_free_block_groups(struct btrfs
> release_global_block_rsv(info);
>
> while(!list_empty(&info->space_info)) {
> + int i;
> +
> space_info = list_entry(info->space_info.next,
> struct btrfs_space_info,
> list);
> @@ -8283,9 +8321,17 @@ int btrfs_free_block_groups(struct btrfs
> dump_space_info(space_info, 0, 0);
> }
> }
> - percpu_counter_destroy(&space_info->total_bytes_pinned);
> list_del(&space_info->list);
> - kfree(space_info);
> + for (i = 0; i < BTRFS_NR_RAID_TYPES; i++) {
> + struct kobject *kobj;
> + kobj = &space_info->block_group_kobjs[i];
> + if (kobj->parent) {
> + kobject_del(kobj);
> + kobject_put(kobj);
> + }
> + }
> + kobject_del(&space_info->kobj);
> + kobject_put(&space_info->kobj);
> }
> return 0;
> }
> @@ -8296,6 +8342,19 @@ static void __link_block_group(struct bt
> int index = get_block_group_index(cache);
>
> down_write(&space_info->groups_sem);
> + if (list_empty(&space_info->block_groups[index])) {
> + struct kobject *kobj = &space_info->block_group_kobjs[index];
> + int ret;
> +
> + kobject_get(&space_info->kobj); /* put in release */
> + ret = kobject_init_and_add(kobj, &btrfs_raid_ktype,
> + &space_info->kobj,
> + get_raid_name(index));
> + if (ret) {
> + pr_warn("btrfs: failed to add kobject for block cache. ignoring.\n");
> + kobject_put(&space_info->kobj);
> + }
> + }
> list_add_tail(&cache->list, &space_info->block_groups[index]);
> up_write(&space_info->groups_sem);
> }
> @@ -8736,8 +8795,11 @@ int btrfs_remove_block_group(struct btrf
> * are still on the list after taking the semaphore
> */
> list_del_init(&block_group->list);
> - if (list_empty(&block_group->space_info->block_groups[index]))
> + if (list_empty(&block_group->space_info->block_groups[index])) {
> + kobject_del(&block_group->space_info->block_group_kobjs[index]);
> + kobject_put(&block_group->space_info->block_group_kobjs[index]);
> clear_avail_alloc_bits(root->fs_info, block_group->flags);
> + }
> up_write(&block_group->space_info->groups_sem);
>
> if (block_group->cached == BTRFS_CACHE_STARTED)
> --- a/fs/btrfs/sysfs.c 2013-10-21 16:10:01.856001602 -0400
> +++ b/fs/btrfs/sysfs.c 2013-10-21 16:10:02.751981911 -0400
> @@ -219,6 +219,140 @@ static const struct attribute_group btrf
> .attrs = btrfs_supported_feature_attrs,
> };
>
> +static ssize_t btrfs_show_u64(u64 *value_ptr, spinlock_t *lock, char *buf)
> +{
> + u64 val;
> + if (lock)
> + spin_lock(lock);
> + val = *value_ptr;
> + if (lock)
> + spin_unlock(lock);
> + return snprintf(buf, PAGE_SIZE, "%llu\n", val);
> +}
> +
> +static ssize_t global_rsv_size_show(struct kobject *kobj,
> + struct kobj_attribute *ka, char *buf)
> +{
> + struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
> + struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
> + return btrfs_show_u64(&block_rsv->size, &block_rsv->lock, buf);
> +}
> +BTRFS_ATTR(global_rsv_size, 0444, global_rsv_size_show);
> +
> +static ssize_t global_rsv_reserved_show(struct kobject *kobj,
> + struct kobj_attribute *a, char *buf)
> +{
> + struct btrfs_fs_info *fs_info = to_fs_info(kobj->parent);
> + struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
> + return btrfs_show_u64(&block_rsv->reserved, &block_rsv->lock, buf);
> +}
> +BTRFS_ATTR(global_rsv_reserved, 0444, global_rsv_reserved_show);
> +
> +#define to_space_info(_kobj) container_of(_kobj, struct btrfs_space_info, kobj)
> +
> +static ssize_t raid_bytes_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf);
> +BTRFS_RAID_ATTR(total_bytes, raid_bytes_show);
> +BTRFS_RAID_ATTR(used_bytes, raid_bytes_show);
> +
> +static ssize_t raid_bytes_show(struct kobject *kobj,
> + struct kobj_attribute *attr, char *buf)
> +
> +{
> + struct btrfs_space_info *sinfo = to_space_info(kobj->parent);
> + struct btrfs_block_group_cache *block_group;
> + int index = kobj - sinfo->block_group_kobjs;
> + u64 val = 0;
> +
> + down_read(&sinfo->groups_sem);
> + list_for_each_entry(block_group, &sinfo->block_groups[index], list) {
> + if (&attr->attr == BTRFS_RAID_ATTR_PTR(total_bytes))
> + val += block_group->key.offset;
> + else
> + val += btrfs_block_group_used(&block_group->item);
> + }
> + up_read(&sinfo->groups_sem);
> + return snprintf(buf, PAGE_SIZE, "%llu\n", val);
> +}
> +
> +static struct attribute *raid_attributes[] = {
> + BTRFS_RAID_ATTR_PTR(total_bytes),
> + BTRFS_RAID_ATTR_PTR(used_bytes),
> + NULL
> +};
> +
> +static void release_raid_kobj(struct kobject *kobj)
> +{
> + kobject_put(kobj->parent);
> +}
> +
> +struct kobj_type btrfs_raid_ktype = {
> + .sysfs_ops = &kobj_sysfs_ops,
> + .release = release_raid_kobj,
> + .default_attrs = raid_attributes,
> +};
> +
> +#define SPACE_INFO_ATTR(field) \
> +static ssize_t btrfs_space_info_show_##field(struct kobject *kobj, \
> + struct kobj_attribute *a, \
> + char *buf) \
> +{ \
> + struct btrfs_space_info *sinfo = to_space_info(kobj); \
> + return btrfs_show_u64(&sinfo->field, &sinfo->lock, buf); \
> +} \
> +BTRFS_ATTR(field, 0444, btrfs_space_info_show_##field)
> +
> +static ssize_t btrfs_space_info_show_total_bytes_pinned(struct kobject *kobj,
> + struct kobj_attribute *a,
> + char *buf)
> +{
> + struct btrfs_space_info *sinfo = to_space_info(kobj);
> + s64 val = percpu_counter_sum(&sinfo->total_bytes_pinned);
> + return snprintf(buf, PAGE_SIZE, "%lld\n", val);
> +}
> +
> +SPACE_INFO_ATTR(flags);
> +SPACE_INFO_ATTR(total_bytes);
> +SPACE_INFO_ATTR(bytes_used);
> +SPACE_INFO_ATTR(bytes_pinned);
> +SPACE_INFO_ATTR(bytes_reserved);
> +SPACE_INFO_ATTR(bytes_may_use);
> +SPACE_INFO_ATTR(disk_used);
> +SPACE_INFO_ATTR(disk_total);
> +BTRFS_ATTR(total_bytes_pinned, 0444, btrfs_space_info_show_total_bytes_pinned);
> +
> +static struct attribute *space_info_attrs[] = {
> + BTRFS_ATTR_PTR(flags),
> + BTRFS_ATTR_PTR(total_bytes),
> + BTRFS_ATTR_PTR(bytes_used),
> + BTRFS_ATTR_PTR(bytes_pinned),
> + BTRFS_ATTR_PTR(bytes_reserved),
> + BTRFS_ATTR_PTR(bytes_may_use),
> + BTRFS_ATTR_PTR(disk_used),
> + BTRFS_ATTR_PTR(disk_total),
> + BTRFS_ATTR_PTR(total_bytes_pinned),
> + NULL,
> +};
> +
> +static void space_info_release(struct kobject *kobj)
> +{
> + struct btrfs_space_info *sinfo = to_space_info(kobj);
> + percpu_counter_destroy(&sinfo->total_bytes_pinned);
> + kfree(sinfo);
> +}
> +
> +struct kobj_type space_info_ktype = {
> + .sysfs_ops = &kobj_sysfs_ops,
> + .release = space_info_release,
> + .default_attrs = space_info_attrs,
> +};
> +
> +static const struct attribute *allocation_attrs[] = {
> + BTRFS_ATTR_PTR(global_rsv_reserved),
> + BTRFS_ATTR_PTR(global_rsv_size),
> + NULL,
> +};
> +
> static void btrfs_release_super_kobj(struct kobject *kobj)
> {
> struct btrfs_fs_info *fs_info = to_fs_info(kobj);
> @@ -239,6 +373,9 @@ static inline struct btrfs_fs_info *to_f
>
> void btrfs_sysfs_remove_one(struct btrfs_fs_info *fs_info)
> {
> + sysfs_remove_files(fs_info->space_info_kobj, allocation_attrs);
> + kobject_del(fs_info->space_info_kobj);
> + kobject_put(fs_info->space_info_kobj);
> kobject_del(&fs_info->super_kobj);
> kobject_put(&fs_info->super_kobj);
> wait_for_completion(&fs_info->kobj_unregister);
> @@ -391,6 +528,17 @@ int btrfs_sysfs_add_one(struct btrfs_fs_
> if (error)
> goto failure;
>
> + fs_info->space_info_kobj = kobject_create_and_add("allocation",
> + &fs_info->super_kobj);
> + if (!fs_info->space_info_kobj) {
> + error = -ENOMEM;
> + goto failure;
> + }
> +
> + error = sysfs_create_files(fs_info->space_info_kobj, allocation_attrs);
> + if (error)
> + goto failure;
> +
> return 0;
> failure:
> btrfs_sysfs_remove_one(fs_info);
> --- a/fs/btrfs/sysfs.h 2013-10-21 16:10:01.860001514 -0400
> +++ b/fs/btrfs/sysfs.h 2013-10-21 16:10:02.751981911 -0400
> @@ -22,6 +22,12 @@ static struct kobj_attribute btrfs_attr_
> BTRFS_ATTR_RW(_name, _mode, _show, NULL)
> #define BTRFS_ATTR_PTR(_name) (&btrfs_attr_##_name.attr)
>
> +#define BTRFS_RAID_ATTR(_name, _show) \
> +static struct kobj_attribute btrfs_raid_attr_##_name = \
> + __INIT_KOBJ_ATTR(_name, 0444, _show, NULL)
> +#define BTRFS_RAID_ATTR_PTR(_name) (&btrfs_raid_attr_##_name.attr)
> +
> +
> struct btrfs_feature_attr {
> struct kobj_attribute kobj_attr;
> enum btrfs_feature_set feature_set;
> @@ -53,4 +59,6 @@ static struct btrfs_feature_attr btrfs_a
> to_btrfs_feature_attr(attr_to_btrfs_attr(a))
> char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags);
> extern const char * const btrfs_feature_set_names[3];
> +extern struct kobj_type space_info_ktype;
> +extern struct kobj_type btrfs_raid_ktype;
> #endif /* _BTRFS_SYSFS_H_ */
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Jeff Mahoney
SUSE Labs
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 841 bytes --]
next prev parent reply other threads:[~2013-10-29 18:49 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-21 21:19 [patch 00/13] sysfs publishing patchset Jeff Mahoney
2013-10-21 21:19 ` [patch 01/13] btrfs: add ioctls to query/change feature bits online Jeff Mahoney
2013-10-21 21:19 ` [patch 02/13] kobject: export kobj_sysfs_ops Jeff Mahoney
2013-10-22 14:44 ` Jeff Mahoney
2013-10-21 21:19 ` [patch 03/13] btrfs: publish supported featured in sysfs Jeff Mahoney
2013-10-21 21:19 ` [patch 04/13] btrfs: publish per-super attributes " Jeff Mahoney
2013-10-21 21:19 ` [patch 05/13] btrfs: publish per-super features " Jeff Mahoney
2013-10-21 21:19 ` [patch 06/13] btrfs: publish unknown feature bits " Jeff Mahoney
2013-10-21 21:19 ` [patch 07/13] btrfs: add ability to change features via sysfs Jeff Mahoney
2013-10-21 21:19 ` [patch 08/13] btrfs: use feature attribute names to print better error messages Jeff Mahoney
2013-10-21 21:19 ` [patch 09/13] btrfs: add ioctl to export size of global metadata reservation Jeff Mahoney
2013-10-21 21:19 ` [patch 10/13] btrfs: publish allocation data in sysfs Jeff Mahoney
2013-10-29 18:49 ` Jeff Mahoney [this message]
2013-10-21 21:19 ` [patch 11/13] btrfs: publish device membership " Jeff Mahoney
2013-10-21 21:19 ` [patch 12/13] btrfs: publish fs label " Jeff Mahoney
2013-10-21 21:19 ` [patch 13/13] btrfs: add tracing for failed reservations Jeff Mahoney
2013-10-22 18:26 ` [patch 00/13] sysfs publishing patchset Josef Bacik
2013-10-22 18:39 ` Jeff Mahoney
2013-10-22 20:43 ` Josef Bacik
2013-10-29 18:25 ` Goffredo Baroncelli
2013-10-29 20:26 ` Jeff Mahoney
2013-10-29 21:57 ` Goffredo Baroncelli
-- strict thread matches above, loose matches on Subject: below --
2013-11-01 17:06 [PATCH 00/13] [PATCH 00/13] sysfs publishing patchset (v2) Jeff Mahoney
2013-11-01 17:07 ` [PATCH 10/13] btrfs: publish allocation data in sysfs Jeff Mahoney
2013-11-15 20:33 [PATCH 00/13] sysfs publishing patchset (v3) Jeff Mahoney
2013-11-15 20:34 ` [PATCH 10/13] btrfs: publish allocation data in sysfs Jeff Mahoney
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=5270032B.3050508@suse.com \
--to=jeffm@suse.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
/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).