Skip to content

Commit 077e473

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_accounting_invalid()
Implement bch2_accounting_invalid(); check for junk at the end, and replicas accounting entries in particular need to be checked or we'll pop asserts later. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent f39bae2 commit 077e473

File tree

4 files changed

+73
-8
lines changed

4 files changed

+73
-8
lines changed

fs/bcachefs/disk_accounting.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,74 @@ int bch2_mod_dev_cached_sectors(struct btree_trans *trans,
114114
return bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc);
115115
}
116116

117+
static inline bool is_zero(char *start, char *end)
118+
{
119+
BUG_ON(start > end);
120+
121+
for (; start < end; start++)
122+
if (*start)
123+
return false;
124+
return true;
125+
}
126+
127+
#define field_end(p, member) (((void *) (&p.member)) + sizeof(p.member))
128+
117129
int bch2_accounting_invalid(struct bch_fs *c, struct bkey_s_c k,
118130
enum bch_validate_flags flags,
119131
struct printbuf *err)
120132
{
121-
return 0;
133+
struct disk_accounting_pos acc_k;
134+
bpos_to_disk_accounting_pos(&acc_k, k.k->p);
135+
void *end = &acc_k + 1;
136+
int ret = 0;
137+
138+
switch (acc_k.type) {
139+
case BCH_DISK_ACCOUNTING_nr_inodes:
140+
end = field_end(acc_k, nr_inodes);
141+
break;
142+
case BCH_DISK_ACCOUNTING_persistent_reserved:
143+
end = field_end(acc_k, persistent_reserved);
144+
break;
145+
case BCH_DISK_ACCOUNTING_replicas:
146+
bkey_fsck_err_on(!acc_k.replicas.nr_devs,
147+
c, err, accounting_key_replicas_nr_devs_0,
148+
"accounting key replicas entry with nr_devs=0");
149+
150+
bkey_fsck_err_on(acc_k.replicas.nr_required > acc_k.replicas.nr_devs ||
151+
(acc_k.replicas.nr_required > 1 &&
152+
acc_k.replicas.nr_required == acc_k.replicas.nr_devs),
153+
c, err, accounting_key_replicas_nr_required_bad,
154+
"accounting key replicas entry with bad nr_required");
155+
156+
for (unsigned i = 0; i + 1 < acc_k.replicas.nr_devs; i++)
157+
bkey_fsck_err_on(acc_k.replicas.devs[i] > acc_k.replicas.devs[i + 1],
158+
c, err, accounting_key_replicas_devs_unsorted,
159+
"accounting key replicas entry with unsorted devs");
160+
161+
end = (void *) &acc_k.replicas + replicas_entry_bytes(&acc_k.replicas);
162+
break;
163+
case BCH_DISK_ACCOUNTING_dev_data_type:
164+
end = field_end(acc_k, dev_data_type);
165+
break;
166+
case BCH_DISK_ACCOUNTING_compression:
167+
end = field_end(acc_k, compression);
168+
break;
169+
case BCH_DISK_ACCOUNTING_snapshot:
170+
end = field_end(acc_k, snapshot);
171+
break;
172+
case BCH_DISK_ACCOUNTING_btree:
173+
end = field_end(acc_k, btree);
174+
break;
175+
case BCH_DISK_ACCOUNTING_rebalance_work:
176+
end = field_end(acc_k, rebalance_work);
177+
break;
178+
}
179+
180+
bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)),
181+
c, err, accounting_key_junk_at_end,
182+
"junk at end of accounting key");
183+
fsck_err:
184+
return ret;
122185
}
123186

124187
void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k)

fs/bcachefs/disk_accounting_format.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,6 @@ struct bch_dev_data_type {
124124
__u8 data_type;
125125
};
126126

127-
struct bch_dev_stripe_buckets {
128-
__u8 dev;
129-
};
130-
131127
struct bch_acct_compression {
132128
__u8 type;
133129
};
@@ -140,6 +136,9 @@ struct bch_acct_btree {
140136
__u32 id;
141137
};
142138

139+
struct bch_acct_rebalance_work {
140+
};
141+
143142
struct disk_accounting_pos {
144143
union {
145144
struct {
@@ -149,10 +148,10 @@ struct disk_accounting_pos {
149148
struct bch_persistent_reserved persistent_reserved;
150149
struct bch_replicas_entry_v1 replicas;
151150
struct bch_dev_data_type dev_data_type;
152-
struct bch_dev_stripe_buckets dev_stripe_buckets;
153151
struct bch_acct_compression compression;
154152
struct bch_acct_snapshot snapshot;
155153
struct bch_acct_btree btree;
154+
struct bch_acct_rebalance_work rebalance_work;
156155
};
157156
};
158157
struct bpos _pad;

fs/bcachefs/replicas.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ static int bch2_memcmp(const void *l, const void *r, const void *priv)
2424
static void verify_replicas_entry(struct bch_replicas_entry_v1 *e)
2525
{
2626
#ifdef CONFIG_BCACHEFS_DEBUG
27-
BUG_ON(e->data_type >= BCH_DATA_NR);
2827
BUG_ON(!e->nr_devs);
2928
BUG_ON(e->nr_required > 1 &&
3029
e->nr_required >= e->nr_devs);

fs/bcachefs/sb-errors_format.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,11 @@ enum bch_fsck_flags {
287287
x(accounting_replicas_not_marked, 273, 0) \
288288
x(invalid_btree_id, 274, 0) \
289289
x(alloc_key_io_time_bad, 275, 0) \
290-
x(alloc_key_fragmentation_lru_wrong, 276, FSCK_AUTOFIX)
290+
x(alloc_key_fragmentation_lru_wrong, 276, FSCK_AUTOFIX) \
291+
x(accounting_key_junk_at_end, 277, 0) \
292+
x(accounting_key_replicas_nr_devs_0, 278, 0) \
293+
x(accounting_key_replicas_nr_required_bad, 279, 0) \
294+
x(accounting_key_replicas_devs_unsorted, 280, 0) \
291295

292296
enum bch_sb_error_id {
293297
#define x(t, n, ...) BCH_FSCK_ERR_##t = n,

0 commit comments

Comments
 (0)