1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BCACHEFS_DISK_ACCOUNTING_FORMAT_H 3 #define _BCACHEFS_DISK_ACCOUNTING_FORMAT_H 4 5 #include "replicas_format.h" 6 7 /* 8 * Disk accounting - KEY_TYPE_accounting - on disk format: 9 * 10 * Here, the key has considerably more structure than a typical key (bpos); an 11 * accounting key is 'struct disk_accounting_pos', which is a union of bpos. 12 * 13 * More specifically: a key is just a muliword integer (where word endianness 14 * matches native byte order), so we're treating bpos as an opaque 20 byte 15 * integer and mapping bch_accounting_key to that. 16 * 17 * This is a type-tagged union of all our various subtypes; a disk accounting 18 * key can be device counters, replicas counters, et cetera - it's extensible. 19 * 20 * The value is a list of u64s or s64s; the number of counters is specific to a 21 * given accounting type. 22 * 23 * Unlike with other key types, updates are _deltas_, and the deltas are not 24 * resolved until the update to the underlying btree, done by btree write buffer 25 * flush or journal replay. 26 * 27 * Journal replay in particular requires special handling. The journal tracks a 28 * range of entries which may possibly have not yet been applied to the btree 29 * yet - it does not know definitively whether individual entries are dirty and 30 * still need to be applied. 31 * 32 * To handle this, we use the version field of struct bkey, and give every 33 * accounting update a unique version number - a total ordering in time; the 34 * version number is derived from the key's position in the journal. Then 35 * journal replay can compare the version number of the key from the journal 36 * with the version number of the key in the btree to determine if a key needs 37 * to be replayed. 38 * 39 * For this to work, we must maintain this strict time ordering of updates as 40 * they are flushed to the btree, both via write buffer flush and via journal 41 * replay. This has complications for the write buffer code while journal replay 42 * is still in progress; the write buffer cannot flush any accounting keys to 43 * the btree until journal replay has finished replaying its accounting keys, or 44 * the (newer) version number of the keys from the write buffer will cause 45 * updates from journal replay to be lost. 46 */ 47 48 struct bch_accounting { 49 struct bch_val v; 50 __u64 d[]; 51 }; 52 53 #define BCH_ACCOUNTING_MAX_COUNTERS 3 54 55 #define BCH_DATA_TYPES() \ 56 x(free, 0) \ 57 x(sb, 1) \ 58 x(journal, 2) \ 59 x(btree, 3) \ 60 x(user, 4) \ 61 x(cached, 5) \ 62 x(parity, 6) \ 63 x(stripe, 7) \ 64 x(need_gc_gens, 8) \ 65 x(need_discard, 9) \ 66 x(unstriped, 10) 67 68 enum bch_data_type { 69 #define x(t, n) BCH_DATA_##t, 70 BCH_DATA_TYPES() 71 #undef x 72 BCH_DATA_NR 73 }; 74 75 static inline bool data_type_is_empty(enum bch_data_type type) 76 { 77 switch (type) { 78 case BCH_DATA_free: 79 case BCH_DATA_need_gc_gens: 80 case BCH_DATA_need_discard: 81 return true; 82 default: 83 return false; 84 } 85 } 86 87 static inline bool data_type_is_hidden(enum bch_data_type type) 88 { 89 switch (type) { 90 case BCH_DATA_sb: 91 case BCH_DATA_journal: 92 return true; 93 default: 94 return false; 95 } 96 } 97 98 #define BCH_DISK_ACCOUNTING_TYPES() \ 99 x(nr_inodes, 0) \ 100 x(persistent_reserved, 1) \ 101 x(replicas, 2) \ 102 x(dev_data_type, 3) \ 103 x(compression, 4) \ 104 x(snapshot, 5) \ 105 x(btree, 6) \ 106 x(rebalance_work, 7) 107 108 enum disk_accounting_type { 109 #define x(f, nr) BCH_DISK_ACCOUNTING_##f = nr, 110 BCH_DISK_ACCOUNTING_TYPES() 111 #undef x 112 BCH_DISK_ACCOUNTING_TYPE_NR, 113 }; 114 115 struct bch_nr_inodes { 116 }; 117 118 struct bch_persistent_reserved { 119 __u8 nr_replicas; 120 }; 121 122 struct bch_dev_data_type { 123 __u8 dev; 124 __u8 data_type; 125 }; 126 127 struct bch_dev_stripe_buckets { 128 __u8 dev; 129 }; 130 131 struct bch_acct_compression { 132 __u8 type; 133 }; 134 135 struct bch_acct_snapshot { 136 __u32 id; 137 }; 138 139 struct bch_acct_btree { 140 __u32 id; 141 }; 142 143 struct disk_accounting_pos { 144 union { 145 struct { 146 __u8 type; 147 union { 148 struct bch_nr_inodes nr_inodes; 149 struct bch_persistent_reserved persistent_reserved; 150 struct bch_replicas_entry_v1 replicas; 151 struct bch_dev_data_type dev_data_type; 152 struct bch_dev_stripe_buckets dev_stripe_buckets; 153 struct bch_acct_compression compression; 154 struct bch_acct_snapshot snapshot; 155 struct bch_acct_btree btree; 156 }; 157 }; 158 struct bpos _pad; 159 }; 160 }; 161 162 #endif /* _BCACHEFS_DISK_ACCOUNTING_FORMAT_H */ 163