summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-06-18 21:06:42 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2020-06-18 21:07:01 -0400
commit7e67fea424114346ad60fb237fb4eb3d653bb57a (patch)
treee19bf38cfde5f38972b816c12f980429f3aed8a8
parent700b6bfc1817d73fcb80c52d627ed2ec19db148a (diff)
bcachefs: Track sectors of erasure coded data
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/bcachefs_ioctl.h4
-rw-r--r--fs/bcachefs/buckets.c31
-rw-r--r--fs/bcachefs/buckets_types.h4
-rw-r--r--fs/bcachefs/chardev.c9
-rw-r--r--fs/bcachefs/sysfs.c2
5 files changed, 34 insertions, 16 deletions
diff --git a/fs/bcachefs/bcachefs_ioctl.h b/fs/bcachefs/bcachefs_ioctl.h
index ba8c75706bf1..d71157a3e073 100644
--- a/fs/bcachefs/bcachefs_ioctl.h
+++ b/fs/bcachefs/bcachefs_ioctl.h
@@ -275,9 +275,13 @@ struct bch_ioctl_dev_usage {
__u32 bucket_size;
__u64 nr_buckets;
+ __u64 available_buckets;
__u64 buckets[BCH_DATA_NR];
__u64 sectors[BCH_DATA_NR];
+
+ __u64 ec_buckets;
+ __u64 ec_sectors;
};
/*
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index f75edb3c175a..4c9371991fa6 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -374,6 +374,11 @@ static inline int is_fragmented_bucket(struct bucket_mark m,
return 0;
}
+static inline int bucket_stripe_sectors(struct bucket_mark m)
+{
+ return m.stripe ? m.dirty_sectors : 0;
+}
+
static inline enum bch_data_type bucket_type(struct bucket_mark m)
{
return m.cached_sectors && !m.dirty_sectors
@@ -441,33 +446,35 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
struct bucket_mark old, struct bucket_mark new,
bool gc)
{
- struct bch_dev_usage *dev_usage;
+ struct bch_dev_usage *u;
percpu_rwsem_assert_held(&c->mark_lock);
preempt_disable();
- dev_usage = this_cpu_ptr(ca->usage[gc]);
+ u = this_cpu_ptr(ca->usage[gc]);
if (bucket_type(old))
- account_bucket(fs_usage, dev_usage, bucket_type(old),
+ account_bucket(fs_usage, u, bucket_type(old),
-1, -ca->mi.bucket_size);
if (bucket_type(new))
- account_bucket(fs_usage, dev_usage, bucket_type(new),
+ account_bucket(fs_usage, u, bucket_type(new),
1, ca->mi.bucket_size);
- dev_usage->buckets_alloc +=
+ u->buckets_alloc +=
(int) new.owned_by_allocator - (int) old.owned_by_allocator;
- dev_usage->buckets_ec +=
- (int) new.stripe - (int) old.stripe;
- dev_usage->buckets_unavailable +=
+ u->buckets_unavailable +=
is_unavailable_bucket(new) - is_unavailable_bucket(old);
- dev_usage->sectors[old.data_type] -= old.dirty_sectors;
- dev_usage->sectors[new.data_type] += new.dirty_sectors;
- dev_usage->sectors[BCH_DATA_CACHED] +=
+ u->buckets_ec += (int) new.stripe - (int) old.stripe;
+ u->sectors_ec += bucket_stripe_sectors(new) -
+ bucket_stripe_sectors(old);
+
+ u->sectors[old.data_type] -= old.dirty_sectors;
+ u->sectors[new.data_type] += new.dirty_sectors;
+ u->sectors[BCH_DATA_CACHED] +=
(int) new.cached_sectors - (int) old.cached_sectors;
- dev_usage->sectors_fragmented +=
+ u->sectors_fragmented +=
is_fragmented_bucket(new, ca) - is_fragmented_bucket(old, ca);
preempt_enable();
diff --git a/fs/bcachefs/buckets_types.h b/fs/bcachefs/buckets_types.h
index 59e92a6d26be..53f22726893d 100644
--- a/fs/bcachefs/buckets_types.h
+++ b/fs/bcachefs/buckets_types.h
@@ -53,12 +53,14 @@ struct bucket_array {
struct bch_dev_usage {
u64 buckets[BCH_DATA_NR];
u64 buckets_alloc;
- u64 buckets_ec;
u64 buckets_unavailable;
/* _compressed_ sectors: */
u64 sectors[BCH_DATA_NR];
u64 sectors_fragmented;
+
+ u64 buckets_ec;
+ u64 sectors_ec;
};
struct bch_fs_usage {
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c
index 5028d0dcc2d6..3af521947502 100644
--- a/fs/bcachefs/chardev.c
+++ b/fs/bcachefs/chardev.c
@@ -470,9 +470,12 @@ static long bch2_ioctl_dev_usage(struct bch_fs *c,
src = bch2_dev_usage_read(c, ca);
- arg.state = ca->mi.state;
- arg.bucket_size = ca->mi.bucket_size;
- arg.nr_buckets = ca->mi.nbuckets - ca->mi.first_bucket;
+ arg.state = ca->mi.state;
+ arg.bucket_size = ca->mi.bucket_size;
+ arg.nr_buckets = ca->mi.nbuckets - ca->mi.first_bucket;
+ arg.available_buckets = arg.nr_buckets - src.buckets_unavailable;
+ arg.ec_buckets = src.buckets_ec;
+ arg.ec_sectors = src.sectors_ec;
for (i = 0; i < BCH_DATA_NR; i++) {
arg.buckets[i] = src.buckets[i];
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index b163064f0c5c..c169d282a1f9 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -846,6 +846,7 @@ static ssize_t show_dev_alloc_debug(struct bch_dev *ca, char *buf)
" meta: %llu\n"
" user: %llu\n"
" cached: %llu\n"
+ " erasure coded: %llu\n"
" fragmented: %llu\n"
" copygc threshold: %llu\n"
"freelist_wait: %s\n"
@@ -872,6 +873,7 @@ static ssize_t show_dev_alloc_debug(struct bch_dev *ca, char *buf)
stats.sectors[BCH_DATA_BTREE],
stats.sectors[BCH_DATA_USER],
stats.sectors[BCH_DATA_CACHED],
+ stats.sectors_ec,
stats.sectors_fragmented,
ca->copygc_threshold,
c->freelist_wait.list.first ? "waiting" : "empty",