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 x(inum, 8) 108 109 enum disk_accounting_type { 110 #define x(f, nr) BCH_DISK_ACCOUNTING_##f = nr, 111 BCH_DISK_ACCOUNTING_TYPES() 112 #undef x 113 BCH_DISK_ACCOUNTING_TYPE_NR, 114 }; 115 116 struct bch_nr_inodes { 117 }; 118 119 struct bch_persistent_reserved { 120 __u8 nr_replicas; 121 }; 122 123 struct bch_dev_data_type { 124 __u8 dev; 125 __u8 data_type; 126 }; 127 128 struct bch_acct_compression { 129 __u8 type; 130 }; 131 132 struct bch_acct_snapshot { 133 __u32 id; 134 } __packed; 135 136 struct bch_acct_btree { 137 __u32 id; 138 } __packed; 139 140 struct bch_acct_inum { 141 __u64 inum; 142 } __packed; 143 144 struct bch_acct_rebalance_work { 145 }; 146 147 struct disk_accounting_pos { 148 union { 149 struct { 150 __u8 type; 151 union { 152 struct bch_nr_inodes nr_inodes; 153 struct bch_persistent_reserved persistent_reserved; 154 struct bch_replicas_entry_v1 replicas; 155 struct bch_dev_data_type dev_data_type; 156 struct bch_acct_compression compression; 157 struct bch_acct_snapshot snapshot; 158 struct bch_acct_btree btree; 159 struct bch_acct_rebalance_work rebalance_work; 160 struct bch_acct_inum inum; 161 } __packed; 162 } __packed; 163 struct bpos _pad; 164 }; 165 }; 166 167 #endif /* _BCACHEFS_DISK_ACCOUNTING_FORMAT_H */ 168