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  
data_type_is_empty(enum bch_data_type type)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  
data_type_is_hidden(enum bch_data_type type)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