| /* SPDX-License-Identifier: GPL-2.0 */ |
| #ifndef _BCACHEFS_DISK_ACCOUNTING_FORMAT_H |
| #define _BCACHEFS_DISK_ACCOUNTING_FORMAT_H |
| |
| #include "replicas_format.h" |
| |
| /* |
| * Disk accounting - KEY_TYPE_accounting - on disk format: |
| * |
| * Here, the key has considerably more structure than a typical key (bpos); an |
| * accounting key is 'struct disk_accounting_pos', which is a union of bpos. |
| * |
| * More specifically: a key is just a muliword integer (where word endianness |
| * matches native byte order), so we're treating bpos as an opaque 20 byte |
| * integer and mapping bch_accounting_key to that. |
| * |
| * This is a type-tagged union of all our various subtypes; a disk accounting |
| * key can be device counters, replicas counters, et cetera - it's extensible. |
| * |
| * The value is a list of u64s or s64s; the number of counters is specific to a |
| * given accounting type. |
| * |
| * Unlike with other key types, updates are _deltas_, and the deltas are not |
| * resolved until the update to the underlying btree, done by btree write buffer |
| * flush or journal replay. |
| * |
| * Journal replay in particular requires special handling. The journal tracks a |
| * range of entries which may possibly have not yet been applied to the btree |
| * yet - it does not know definitively whether individual entries are dirty and |
| * still need to be applied. |
| * |
| * To handle this, we use the version field of struct bkey, and give every |
| * accounting update a unique version number - a total ordering in time; the |
| * version number is derived from the key's position in the journal. Then |
| * journal replay can compare the version number of the key from the journal |
| * with the version number of the key in the btree to determine if a key needs |
| * to be replayed. |
| * |
| * For this to work, we must maintain this strict time ordering of updates as |
| * they are flushed to the btree, both via write buffer flush and via journal |
| * replay. This has complications for the write buffer code while journal replay |
| * is still in progress; the write buffer cannot flush any accounting keys to |
| * the btree until journal replay has finished replaying its accounting keys, or |
| * the (newer) version number of the keys from the write buffer will cause |
| * updates from journal replay to be lost. |
| */ |
| |
| struct bch_accounting { |
| struct bch_val v; |
| __u64 d[]; |
| }; |
| |
| #define BCH_ACCOUNTING_MAX_COUNTERS 3 |
| |
| #define BCH_DATA_TYPES() \ |
| x(free, 0) \ |
| x(sb, 1) \ |
| x(journal, 2) \ |
| x(btree, 3) \ |
| x(user, 4) \ |
| x(cached, 5) \ |
| x(parity, 6) \ |
| x(stripe, 7) \ |
| x(need_gc_gens, 8) \ |
| x(need_discard, 9) \ |
| x(unstriped, 10) |
| |
| enum bch_data_type { |
| #define x(t, n) BCH_DATA_##t, |
| BCH_DATA_TYPES() |
| #undef x |
| BCH_DATA_NR |
| }; |
| |
| static inline bool data_type_is_empty(enum bch_data_type type) |
| { |
| switch (type) { |
| case BCH_DATA_free: |
| case BCH_DATA_need_gc_gens: |
| case BCH_DATA_need_discard: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| static inline bool data_type_is_hidden(enum bch_data_type type) |
| { |
| switch (type) { |
| case BCH_DATA_sb: |
| case BCH_DATA_journal: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| #define BCH_DISK_ACCOUNTING_TYPES() \ |
| x(nr_inodes, 0) \ |
| x(persistent_reserved, 1) \ |
| x(replicas, 2) \ |
| x(dev_data_type, 3) \ |
| x(compression, 4) \ |
| x(snapshot, 5) \ |
| x(btree, 6) \ |
| x(rebalance_work, 7) \ |
| x(inum, 8) |
| |
| enum disk_accounting_type { |
| #define x(f, nr) BCH_DISK_ACCOUNTING_##f = nr, |
| BCH_DISK_ACCOUNTING_TYPES() |
| #undef x |
| BCH_DISK_ACCOUNTING_TYPE_NR, |
| }; |
| |
| struct bch_nr_inodes { |
| }; |
| |
| struct bch_persistent_reserved { |
| __u8 nr_replicas; |
| }; |
| |
| struct bch_dev_data_type { |
| __u8 dev; |
| __u8 data_type; |
| }; |
| |
| struct bch_acct_compression { |
| __u8 type; |
| }; |
| |
| struct bch_acct_snapshot { |
| __u32 id; |
| } __packed; |
| |
| struct bch_acct_btree { |
| __u32 id; |
| } __packed; |
| |
| struct bch_acct_inum { |
| __u64 inum; |
| } __packed; |
| |
| struct bch_acct_rebalance_work { |
| }; |
| |
| struct disk_accounting_pos { |
| union { |
| struct { |
| __u8 type; |
| union { |
| struct bch_nr_inodes nr_inodes; |
| struct bch_persistent_reserved persistent_reserved; |
| struct bch_replicas_entry_v1 replicas; |
| struct bch_dev_data_type dev_data_type; |
| struct bch_acct_compression compression; |
| struct bch_acct_snapshot snapshot; |
| struct bch_acct_btree btree; |
| struct bch_acct_rebalance_work rebalance_work; |
| struct bch_acct_inum inum; |
| } __packed; |
| } __packed; |
| struct bpos _pad; |
| }; |
| }; |
| |
| #endif /* _BCACHEFS_DISK_ACCOUNTING_FORMAT_H */ |