This adds per-compression-type accounting of compressed and uncompressed
size as well as number of extents - meaning we can now see compression
ratio (without walking the whole filesystem).

Signed-off-by: Kent Overstreet <[email protected]>
---
 fs/bcachefs/buckets.c                | 45 ++++++++++++++++++++++++----
 fs/bcachefs/disk_accounting.c        |  4 +++
 fs/bcachefs/disk_accounting_format.h |  8 ++++-
 3 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index 506bb580bff4..6078b67e51cf 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -503,6 +503,7 @@ static int __trigger_extent(struct btree_trans *trans,
                : BCH_DATA_user;
        s64 dirty_sectors = 0;
        int ret = 0;
+       u64 compression_acct[3] = { 1, 0, 0 };
 
        struct disk_accounting_key acc = {
                .type                   = BCH_DISK_ACCOUNTING_replicas,
@@ -511,6 +512,10 @@ static int __trigger_extent(struct btree_trans *trans,
                .replicas.nr_required   = 1,
        };
 
+       struct disk_accounting_key compression_key = {
+               .type                   = BCH_DISK_ACCOUNTING_compression,
+       };
+
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
                s64 disk_sectors;
                ret = bch2_trigger_pointer(trans, btree_id, level, k, p, 
&disk_sectors, flags);
@@ -519,12 +524,13 @@ static int __trigger_extent(struct btree_trans *trans,
 
                bool stale = ret > 0;
 
+               if (p.ptr.cached && stale)
+                       continue;
+
                if (p.ptr.cached) {
-                       if (!stale) {
-                               ret = bch2_mod_dev_cached_sectors(trans, 
p.ptr.dev, disk_sectors, gc);
-                               if (ret)
-                                       return ret;
-                       }
+                       ret = bch2_mod_dev_cached_sectors(trans, p.ptr.dev, 
disk_sectors, gc);
+                       if (ret)
+                               return ret;
                } else if (!p.has_ec) {
                        dirty_sectors          += disk_sectors;
                        acc.replicas.devs[acc.replicas.nr_devs++] = p.ptr.dev;
@@ -540,6 +546,26 @@ static int __trigger_extent(struct btree_trans *trans,
                         */
                        acc.replicas.nr_required = 0;
                }
+
+               if (compression_key.compression.type &&
+                   compression_key.compression.type != p.crc.compression_type) 
{
+                       if (flags & BTREE_TRIGGER_OVERWRITE)
+                               bch2_u64s_neg(compression_acct, 3);
+
+                       ret = bch2_disk_accounting_mod(trans, &compression_key, 
compression_acct, 2, gc);
+                       if (ret)
+                               return ret;
+
+                       compression_acct[0] = 1;
+                       compression_acct[1] = 0;
+                       compression_acct[2] = 0;
+               }
+
+               compression_key.compression.type = p.crc.compression_type;
+               if (p.crc.compression_type) {
+                       compression_acct[1] += p.crc.uncompressed_size;
+                       compression_acct[2] += p.crc.compressed_size;
+               }
        }
 
        if (acc.replicas.nr_devs) {
@@ -548,6 +574,15 @@ static int __trigger_extent(struct btree_trans *trans,
                        return ret;
        }
 
+       if (compression_key.compression.type) {
+               if (flags & BTREE_TRIGGER_OVERWRITE)
+                       bch2_u64s_neg(compression_acct, 3);
+
+               ret = bch2_disk_accounting_mod(trans, &compression_key, 
compression_acct, 3, gc);
+               if (ret)
+                       return ret;
+       }
+
        return 0;
 }
 
diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c
index 8d7b6ab66e71..dc020d651d0a 100644
--- a/fs/bcachefs/disk_accounting.c
+++ b/fs/bcachefs/disk_accounting.c
@@ -5,6 +5,7 @@
 #include "btree_update.h"
 #include "btree_write_buffer.h"
 #include "buckets.h"
+#include "compress.h"
 #include "disk_accounting.h"
 #include "error.h"
 #include "journal_io.h"
@@ -91,6 +92,9 @@ void bch2_accounting_key_to_text(struct printbuf *out, struct 
disk_accounting_ke
        case BCH_DISK_ACCOUNTING_dev_stripe_buckets:
                prt_printf(out, "dev=%u", k->dev_stripe_buckets.dev);
                break;
+       case BCH_DISK_ACCOUNTING_compression:
+               bch2_prt_compression_type(out, k->compression.type);
+               break;
        }
 }
 
diff --git a/fs/bcachefs/disk_accounting_format.h 
b/fs/bcachefs/disk_accounting_format.h
index e06a42f0d578..75bfc9bce79f 100644
--- a/fs/bcachefs/disk_accounting_format.h
+++ b/fs/bcachefs/disk_accounting_format.h
@@ -95,7 +95,8 @@ static inline bool data_type_is_hidden(enum bch_data_type 
type)
        x(persistent_reserved,  1)              \
        x(replicas,             2)              \
        x(dev_data_type,        3)              \
-       x(dev_stripe_buckets,   4)
+       x(dev_stripe_buckets,   4)              \
+       x(compression,          5)
 
 enum disk_accounting_type {
 #define x(f, nr)       BCH_DISK_ACCOUNTING_##f = nr,
@@ -120,6 +121,10 @@ struct bch_dev_stripe_buckets {
        __u8                    dev;
 };
 
+struct bch_acct_compression {
+       __u8                    type;
+};
+
 struct disk_accounting_key {
        union {
        struct {
@@ -130,6 +135,7 @@ struct disk_accounting_key {
                struct bch_replicas_entry_v1    replicas;
                struct bch_dev_data_type        dev_data_type;
                struct bch_dev_stripe_buckets   dev_stripe_buckets;
+               struct bch_acct_compression     compression;
                };
        };
                struct bpos                     _pad;
-- 
2.43.0


Reply via email to