1 // SPDX-License-Identifier: GPL-2.0
2
3 #include "bcachefs.h"
4 #include "bcachefs_ioctl.h"
5 #include "btree_cache.h"
6 #include "btree_journal_iter.h"
7 #include "btree_update.h"
8 #include "btree_write_buffer.h"
9 #include "buckets.h"
10 #include "compress.h"
11 #include "disk_accounting.h"
12 #include "error.h"
13 #include "journal_io.h"
14 #include "replicas.h"
15
16 /*
17 * Notes on disk accounting:
18 *
19 * We have two parallel sets of counters to be concerned with, and both must be
20 * kept in sync.
21 *
22 * - Persistent/on disk accounting, stored in the accounting btree and updated
23 * via btree write buffer updates that treat new accounting keys as deltas to
24 * apply to existing values. But reading from a write buffer btree is
25 * expensive, so we also have
26 *
27 * - In memory accounting, where accounting is stored as an array of percpu
28 * counters, indexed by an eytzinger array of disk acounting keys/bpos (which
29 * are the same thing, excepting byte swabbing on big endian).
30 *
31 * Cheap to read, but non persistent.
32 *
33 * Disk accounting updates are generated by transactional triggers; these run as
34 * keys enter and leave the btree, and can compare old and new versions of keys;
35 * the output of these triggers are deltas to the various counters.
36 *
37 * Disk accounting updates are done as btree write buffer updates, where the
38 * counters in the disk accounting key are deltas that will be applied to the
39 * counter in the btree when the key is flushed by the write buffer (or journal
40 * replay).
41 *
42 * To do a disk accounting update:
43 * - initialize a disk_accounting_pos, to specify which counter is being update
44 * - initialize counter deltas, as an array of 1-3 s64s
45 * - call bch2_disk_accounting_mod()
46 *
47 * This queues up the accounting update to be done at transaction commit time.
48 * Underneath, it's a normal btree write buffer update.
49 *
50 * The transaction commit path is responsible for propagating updates to the in
51 * memory counters, with bch2_accounting_mem_mod().
52 *
53 * The commit path also assigns every disk accounting update a unique version
54 * number, based on the journal sequence number and offset within that journal
55 * buffer; this is used by journal replay to determine which updates have been
56 * done.
57 *
58 * The transaction commit path also ensures that replicas entry accounting
59 * updates are properly marked in the superblock (so that we know whether we can
60 * mount without data being unavailable); it will update the superblock if
61 * bch2_accounting_mem_mod() tells it to.
62 */
63
64 static const char * const disk_accounting_type_strs[] = {
65 #define x(t, n, ...) [n] = #t,
66 BCH_DISK_ACCOUNTING_TYPES()
67 #undef x
68 NULL
69 };
70
accounting_key_init(struct bkey_i * k,struct disk_accounting_pos * pos,s64 * d,unsigned nr)71 static inline void accounting_key_init(struct bkey_i *k, struct disk_accounting_pos *pos,
72 s64 *d, unsigned nr)
73 {
74 struct bkey_i_accounting *acc = bkey_accounting_init(k);
75
76 acc->k.p = disk_accounting_pos_to_bpos(pos);
77 set_bkey_val_u64s(&acc->k, sizeof(struct bch_accounting) / sizeof(u64) + nr);
78
79 memcpy_u64s_small(acc->v.d, d, nr);
80 }
81
82 static int bch2_accounting_update_sb_one(struct bch_fs *, struct bpos);
83
bch2_disk_accounting_mod(struct btree_trans * trans,struct disk_accounting_pos * k,s64 * d,unsigned nr,bool gc)84 int bch2_disk_accounting_mod(struct btree_trans *trans,
85 struct disk_accounting_pos *k,
86 s64 *d, unsigned nr, bool gc)
87 {
88 /* Normalize: */
89 switch (k->type) {
90 case BCH_DISK_ACCOUNTING_replicas:
91 bubble_sort(k->replicas.devs, k->replicas.nr_devs, u8_cmp);
92 break;
93 }
94
95 BUG_ON(nr > BCH_ACCOUNTING_MAX_COUNTERS);
96
97 struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;
98
99 accounting_key_init(&k_i.k, k, d, nr);
100
101 if (unlikely(gc)) {
102 int ret = bch2_accounting_mem_add(trans, bkey_i_to_s_c_accounting(&k_i.k), true);
103 if (ret == -BCH_ERR_btree_insert_need_mark_replicas)
104 ret = drop_locks_do(trans,
105 bch2_accounting_update_sb_one(trans->c, disk_accounting_pos_to_bpos(k))) ?:
106 bch2_accounting_mem_add(trans, bkey_i_to_s_c_accounting(&k_i.k), true);
107 return ret;
108 } else {
109 return bch2_trans_update_buffered(trans, BTREE_ID_accounting, &k_i.k);
110 }
111 }
112
bch2_mod_dev_cached_sectors(struct btree_trans * trans,unsigned dev,s64 sectors,bool gc)113 int bch2_mod_dev_cached_sectors(struct btree_trans *trans,
114 unsigned dev, s64 sectors,
115 bool gc)
116 {
117 struct disk_accounting_pos acc;
118 memset(&acc, 0, sizeof(acc));
119 acc.type = BCH_DISK_ACCOUNTING_replicas;
120 bch2_replicas_entry_cached(&acc.replicas, dev);
121
122 return bch2_disk_accounting_mod(trans, &acc, §ors, 1, gc);
123 }
124
is_zero(char * start,char * end)125 static inline bool is_zero(char *start, char *end)
126 {
127 BUG_ON(start > end);
128
129 for (; start < end; start++)
130 if (*start)
131 return false;
132 return true;
133 }
134
135 #define field_end(p, member) (((void *) (&p.member)) + sizeof(p.member))
136
137 static const unsigned bch2_accounting_type_nr_counters[] = {
138 #define x(f, id, nr) [BCH_DISK_ACCOUNTING_##f] = nr,
139 BCH_DISK_ACCOUNTING_TYPES()
140 #undef x
141 };
142
bch2_accounting_validate(struct bch_fs * c,struct bkey_s_c k,struct bkey_validate_context from)143 int bch2_accounting_validate(struct bch_fs *c, struct bkey_s_c k,
144 struct bkey_validate_context from)
145 {
146 struct disk_accounting_pos acc_k;
147 bpos_to_disk_accounting_pos(&acc_k, k.k->p);
148 void *end = &acc_k + 1;
149 int ret = 0;
150
151 bkey_fsck_err_on((from.flags & BCH_VALIDATE_commit) &&
152 bversion_zero(k.k->bversion),
153 c, accounting_key_version_0,
154 "accounting key with version=0");
155
156 switch (acc_k.type) {
157 case BCH_DISK_ACCOUNTING_nr_inodes:
158 end = field_end(acc_k, nr_inodes);
159 break;
160 case BCH_DISK_ACCOUNTING_persistent_reserved:
161 end = field_end(acc_k, persistent_reserved);
162 break;
163 case BCH_DISK_ACCOUNTING_replicas:
164 bkey_fsck_err_on(!acc_k.replicas.nr_devs,
165 c, accounting_key_replicas_nr_devs_0,
166 "accounting key replicas entry with nr_devs=0");
167
168 bkey_fsck_err_on(acc_k.replicas.nr_required > acc_k.replicas.nr_devs ||
169 (acc_k.replicas.nr_required > 1 &&
170 acc_k.replicas.nr_required == acc_k.replicas.nr_devs),
171 c, accounting_key_replicas_nr_required_bad,
172 "accounting key replicas entry with bad nr_required");
173
174 for (unsigned i = 0; i + 1 < acc_k.replicas.nr_devs; i++)
175 bkey_fsck_err_on(acc_k.replicas.devs[i] >= acc_k.replicas.devs[i + 1],
176 c, accounting_key_replicas_devs_unsorted,
177 "accounting key replicas entry with unsorted devs");
178
179 end = (void *) &acc_k.replicas + replicas_entry_bytes(&acc_k.replicas);
180 break;
181 case BCH_DISK_ACCOUNTING_dev_data_type:
182 end = field_end(acc_k, dev_data_type);
183 break;
184 case BCH_DISK_ACCOUNTING_compression:
185 end = field_end(acc_k, compression);
186 break;
187 case BCH_DISK_ACCOUNTING_snapshot:
188 end = field_end(acc_k, snapshot);
189 break;
190 case BCH_DISK_ACCOUNTING_btree:
191 end = field_end(acc_k, btree);
192 break;
193 case BCH_DISK_ACCOUNTING_rebalance_work:
194 end = field_end(acc_k, rebalance_work);
195 break;
196 }
197
198 bkey_fsck_err_on(!is_zero(end, (void *) (&acc_k + 1)),
199 c, accounting_key_junk_at_end,
200 "junk at end of accounting key");
201
202 bkey_fsck_err_on(bch2_accounting_counters(k.k) != bch2_accounting_type_nr_counters[acc_k.type],
203 c, accounting_key_nr_counters_wrong,
204 "accounting key with %u counters, should be %u",
205 bch2_accounting_counters(k.k), bch2_accounting_type_nr_counters[acc_k.type]);
206 fsck_err:
207 return ret;
208 }
209
bch2_accounting_key_to_text(struct printbuf * out,struct disk_accounting_pos * k)210 void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k)
211 {
212 if (k->type >= BCH_DISK_ACCOUNTING_TYPE_NR) {
213 prt_printf(out, "unknown type %u", k->type);
214 return;
215 }
216
217 prt_str(out, disk_accounting_type_strs[k->type]);
218 prt_str(out, " ");
219
220 switch (k->type) {
221 case BCH_DISK_ACCOUNTING_nr_inodes:
222 break;
223 case BCH_DISK_ACCOUNTING_persistent_reserved:
224 prt_printf(out, "replicas=%u", k->persistent_reserved.nr_replicas);
225 break;
226 case BCH_DISK_ACCOUNTING_replicas:
227 bch2_replicas_entry_to_text(out, &k->replicas);
228 break;
229 case BCH_DISK_ACCOUNTING_dev_data_type:
230 prt_printf(out, "dev=%u data_type=", k->dev_data_type.dev);
231 bch2_prt_data_type(out, k->dev_data_type.data_type);
232 break;
233 case BCH_DISK_ACCOUNTING_compression:
234 bch2_prt_compression_type(out, k->compression.type);
235 break;
236 case BCH_DISK_ACCOUNTING_snapshot:
237 prt_printf(out, "id=%u", k->snapshot.id);
238 break;
239 case BCH_DISK_ACCOUNTING_btree:
240 prt_str(out, "btree=");
241 bch2_btree_id_to_text(out, k->btree.id);
242 break;
243 }
244 }
245
bch2_accounting_to_text(struct printbuf * out,struct bch_fs * c,struct bkey_s_c k)246 void bch2_accounting_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
247 {
248 struct bkey_s_c_accounting acc = bkey_s_c_to_accounting(k);
249 struct disk_accounting_pos acc_k;
250 bpos_to_disk_accounting_pos(&acc_k, k.k->p);
251
252 bch2_accounting_key_to_text(out, &acc_k);
253
254 for (unsigned i = 0; i < bch2_accounting_counters(k.k); i++)
255 prt_printf(out, " %lli", acc.v->d[i]);
256 }
257
bch2_accounting_swab(struct bkey_s k)258 void bch2_accounting_swab(struct bkey_s k)
259 {
260 for (u64 *p = (u64 *) k.v;
261 p < (u64 *) bkey_val_end(k);
262 p++)
263 *p = swab64(*p);
264 }
265
__accounting_to_replicas(struct bch_replicas_entry_v1 * r,struct disk_accounting_pos * acc)266 static inline void __accounting_to_replicas(struct bch_replicas_entry_v1 *r,
267 struct disk_accounting_pos *acc)
268 {
269 unsafe_memcpy(r, &acc->replicas,
270 replicas_entry_bytes(&acc->replicas),
271 "variable length struct");
272 }
273
accounting_to_replicas(struct bch_replicas_entry_v1 * r,struct bpos p)274 static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p)
275 {
276 struct disk_accounting_pos acc_k;
277 bpos_to_disk_accounting_pos(&acc_k, p);
278
279 switch (acc_k.type) {
280 case BCH_DISK_ACCOUNTING_replicas:
281 __accounting_to_replicas(r, &acc_k);
282 return true;
283 default:
284 return false;
285 }
286 }
287
bch2_accounting_update_sb_one(struct bch_fs * c,struct bpos p)288 static int bch2_accounting_update_sb_one(struct bch_fs *c, struct bpos p)
289 {
290 struct bch_replicas_padded r;
291 return accounting_to_replicas(&r.e, p)
292 ? bch2_mark_replicas(c, &r.e)
293 : 0;
294 }
295
296 /*
297 * Ensure accounting keys being updated are present in the superblock, when
298 * applicable (i.e. replicas updates)
299 */
bch2_accounting_update_sb(struct btree_trans * trans)300 int bch2_accounting_update_sb(struct btree_trans *trans)
301 {
302 for (struct jset_entry *i = trans->journal_entries;
303 i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
304 i = vstruct_next(i))
305 if (jset_entry_is_key(i) && i->start->k.type == KEY_TYPE_accounting) {
306 int ret = bch2_accounting_update_sb_one(trans->c, i->start->k.p);
307 if (ret)
308 return ret;
309 }
310
311 return 0;
312 }
313
__bch2_accounting_mem_insert(struct bch_fs * c,struct bkey_s_c_accounting a)314 static int __bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a)
315 {
316 struct bch_accounting_mem *acc = &c->accounting;
317
318 /* raced with another insert, already present: */
319 if (eytzinger0_find(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
320 accounting_pos_cmp, &a.k->p) < acc->k.nr)
321 return 0;
322
323 struct accounting_mem_entry n = {
324 .pos = a.k->p,
325 .bversion = a.k->bversion,
326 .nr_counters = bch2_accounting_counters(a.k),
327 .v[0] = __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
328 sizeof(u64), GFP_KERNEL),
329 };
330
331 if (!n.v[0])
332 goto err;
333
334 if (acc->gc_running) {
335 n.v[1] = __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
336 sizeof(u64), GFP_KERNEL);
337 if (!n.v[1])
338 goto err;
339 }
340
341 if (darray_push(&acc->k, n))
342 goto err;
343
344 eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
345 accounting_pos_cmp, NULL);
346
347 if (trace_accounting_mem_insert_enabled()) {
348 struct printbuf buf = PRINTBUF;
349
350 bch2_accounting_to_text(&buf, c, a.s_c);
351 trace_accounting_mem_insert(c, buf.buf);
352 printbuf_exit(&buf);
353 }
354 return 0;
355 err:
356 free_percpu(n.v[1]);
357 free_percpu(n.v[0]);
358 return -BCH_ERR_ENOMEM_disk_accounting;
359 }
360
bch2_accounting_mem_insert(struct bch_fs * c,struct bkey_s_c_accounting a,enum bch_accounting_mode mode)361 int bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a,
362 enum bch_accounting_mode mode)
363 {
364 struct bch_replicas_padded r;
365
366 if (mode != BCH_ACCOUNTING_read &&
367 accounting_to_replicas(&r.e, a.k->p) &&
368 !bch2_replicas_marked_locked(c, &r.e))
369 return -BCH_ERR_btree_insert_need_mark_replicas;
370
371 percpu_up_read(&c->mark_lock);
372 percpu_down_write(&c->mark_lock);
373 int ret = __bch2_accounting_mem_insert(c, a);
374 percpu_up_write(&c->mark_lock);
375 percpu_down_read(&c->mark_lock);
376 return ret;
377 }
378
bch2_accounting_mem_insert_locked(struct bch_fs * c,struct bkey_s_c_accounting a,enum bch_accounting_mode mode)379 int bch2_accounting_mem_insert_locked(struct bch_fs *c, struct bkey_s_c_accounting a,
380 enum bch_accounting_mode mode)
381 {
382 struct bch_replicas_padded r;
383
384 if (mode != BCH_ACCOUNTING_read &&
385 accounting_to_replicas(&r.e, a.k->p) &&
386 !bch2_replicas_marked_locked(c, &r.e))
387 return -BCH_ERR_btree_insert_need_mark_replicas;
388
389 return __bch2_accounting_mem_insert(c, a);
390 }
391
accounting_mem_entry_is_zero(struct accounting_mem_entry * e)392 static bool accounting_mem_entry_is_zero(struct accounting_mem_entry *e)
393 {
394 for (unsigned i = 0; i < e->nr_counters; i++)
395 if (percpu_u64_get(e->v[0] + i) ||
396 (e->v[1] &&
397 percpu_u64_get(e->v[1] + i)))
398 return false;
399 return true;
400 }
401
bch2_accounting_mem_gc(struct bch_fs * c)402 void bch2_accounting_mem_gc(struct bch_fs *c)
403 {
404 struct bch_accounting_mem *acc = &c->accounting;
405
406 percpu_down_write(&c->mark_lock);
407 struct accounting_mem_entry *dst = acc->k.data;
408
409 darray_for_each(acc->k, src) {
410 if (accounting_mem_entry_is_zero(src)) {
411 free_percpu(src->v[0]);
412 free_percpu(src->v[1]);
413 } else {
414 *dst++ = *src;
415 }
416 }
417
418 acc->k.nr = dst - acc->k.data;
419 eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
420 accounting_pos_cmp, NULL);
421 percpu_up_write(&c->mark_lock);
422 }
423
424 /*
425 * Read out accounting keys for replicas entries, as an array of
426 * bch_replicas_usage entries.
427 *
428 * Note: this may be deprecated/removed at smoe point in the future and replaced
429 * with something more general, it exists to support the ioctl used by the
430 * 'bcachefs fs usage' command.
431 */
bch2_fs_replicas_usage_read(struct bch_fs * c,darray_char * usage)432 int bch2_fs_replicas_usage_read(struct bch_fs *c, darray_char *usage)
433 {
434 struct bch_accounting_mem *acc = &c->accounting;
435 int ret = 0;
436
437 darray_init(usage);
438
439 percpu_down_read(&c->mark_lock);
440 darray_for_each(acc->k, i) {
441 struct {
442 struct bch_replicas_usage r;
443 u8 pad[BCH_BKEY_PTRS_MAX];
444 } u;
445
446 if (!accounting_to_replicas(&u.r.r, i->pos))
447 continue;
448
449 u64 sectors;
450 bch2_accounting_mem_read_counters(acc, i - acc->k.data, §ors, 1, false);
451 u.r.sectors = sectors;
452
453 ret = darray_make_room(usage, replicas_usage_bytes(&u.r));
454 if (ret)
455 break;
456
457 memcpy(&darray_top(*usage), &u.r, replicas_usage_bytes(&u.r));
458 usage->nr += replicas_usage_bytes(&u.r);
459 }
460 percpu_up_read(&c->mark_lock);
461
462 if (ret)
463 darray_exit(usage);
464 return ret;
465 }
466
bch2_fs_accounting_read(struct bch_fs * c,darray_char * out_buf,unsigned accounting_types_mask)467 int bch2_fs_accounting_read(struct bch_fs *c, darray_char *out_buf, unsigned accounting_types_mask)
468 {
469
470 struct bch_accounting_mem *acc = &c->accounting;
471 int ret = 0;
472
473 darray_init(out_buf);
474
475 percpu_down_read(&c->mark_lock);
476 darray_for_each(acc->k, i) {
477 struct disk_accounting_pos a_p;
478 bpos_to_disk_accounting_pos(&a_p, i->pos);
479
480 if (!(accounting_types_mask & BIT(a_p.type)))
481 continue;
482
483 ret = darray_make_room(out_buf, sizeof(struct bkey_i_accounting) +
484 sizeof(u64) * i->nr_counters);
485 if (ret)
486 break;
487
488 struct bkey_i_accounting *a_out =
489 bkey_accounting_init((void *) &darray_top(*out_buf));
490 set_bkey_val_u64s(&a_out->k, i->nr_counters);
491 a_out->k.p = i->pos;
492 bch2_accounting_mem_read_counters(acc, i - acc->k.data,
493 a_out->v.d, i->nr_counters, false);
494
495 if (!bch2_accounting_key_is_zero(accounting_i_to_s_c(a_out)))
496 out_buf->nr += bkey_bytes(&a_out->k);
497 }
498
499 percpu_up_read(&c->mark_lock);
500
501 if (ret)
502 darray_exit(out_buf);
503 return ret;
504 }
505
bch2_accounting_free_counters(struct bch_accounting_mem * acc,bool gc)506 static void bch2_accounting_free_counters(struct bch_accounting_mem *acc, bool gc)
507 {
508 darray_for_each(acc->k, e) {
509 free_percpu(e->v[gc]);
510 e->v[gc] = NULL;
511 }
512 }
513
bch2_gc_accounting_start(struct bch_fs * c)514 int bch2_gc_accounting_start(struct bch_fs *c)
515 {
516 struct bch_accounting_mem *acc = &c->accounting;
517 int ret = 0;
518
519 percpu_down_write(&c->mark_lock);
520 darray_for_each(acc->k, e) {
521 e->v[1] = __alloc_percpu_gfp(e->nr_counters * sizeof(u64),
522 sizeof(u64), GFP_KERNEL);
523 if (!e->v[1]) {
524 bch2_accounting_free_counters(acc, true);
525 ret = -BCH_ERR_ENOMEM_disk_accounting;
526 break;
527 }
528 }
529
530 acc->gc_running = !ret;
531 percpu_up_write(&c->mark_lock);
532
533 return ret;
534 }
535
bch2_gc_accounting_done(struct bch_fs * c)536 int bch2_gc_accounting_done(struct bch_fs *c)
537 {
538 struct bch_accounting_mem *acc = &c->accounting;
539 struct btree_trans *trans = bch2_trans_get(c);
540 struct printbuf buf = PRINTBUF;
541 struct bpos pos = POS_MIN;
542 int ret = 0;
543
544 percpu_down_write(&c->mark_lock);
545 while (1) {
546 unsigned idx = eytzinger0_find_ge(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
547 accounting_pos_cmp, &pos);
548
549 if (idx >= acc->k.nr)
550 break;
551
552 struct accounting_mem_entry *e = acc->k.data + idx;
553 pos = bpos_successor(e->pos);
554
555 struct disk_accounting_pos acc_k;
556 bpos_to_disk_accounting_pos(&acc_k, e->pos);
557
558 if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
559 continue;
560
561 u64 src_v[BCH_ACCOUNTING_MAX_COUNTERS];
562 u64 dst_v[BCH_ACCOUNTING_MAX_COUNTERS];
563
564 unsigned nr = e->nr_counters;
565 bch2_accounting_mem_read_counters(acc, idx, dst_v, nr, false);
566 bch2_accounting_mem_read_counters(acc, idx, src_v, nr, true);
567
568 if (memcmp(dst_v, src_v, nr * sizeof(u64))) {
569 printbuf_reset(&buf);
570 prt_str(&buf, "accounting mismatch for ");
571 bch2_accounting_key_to_text(&buf, &acc_k);
572
573 prt_str(&buf, ": got");
574 for (unsigned j = 0; j < nr; j++)
575 prt_printf(&buf, " %llu", dst_v[j]);
576
577 prt_str(&buf, " should be");
578 for (unsigned j = 0; j < nr; j++)
579 prt_printf(&buf, " %llu", src_v[j]);
580
581 for (unsigned j = 0; j < nr; j++)
582 src_v[j] -= dst_v[j];
583
584 if (fsck_err(trans, accounting_mismatch, "%s", buf.buf)) {
585 percpu_up_write(&c->mark_lock);
586 ret = commit_do(trans, NULL, NULL, 0,
587 bch2_disk_accounting_mod(trans, &acc_k, src_v, nr, false));
588 percpu_down_write(&c->mark_lock);
589 if (ret)
590 goto err;
591
592 if (!test_bit(BCH_FS_may_go_rw, &c->flags)) {
593 memset(&trans->fs_usage_delta, 0, sizeof(trans->fs_usage_delta));
594 struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;
595
596 accounting_key_init(&k_i.k, &acc_k, src_v, nr);
597 bch2_accounting_mem_mod_locked(trans,
598 bkey_i_to_s_c_accounting(&k_i.k),
599 BCH_ACCOUNTING_normal, true);
600
601 preempt_disable();
602 struct bch_fs_usage_base *dst = this_cpu_ptr(c->usage);
603 struct bch_fs_usage_base *src = &trans->fs_usage_delta;
604 acc_u64s((u64 *) dst, (u64 *) src, sizeof(*src) / sizeof(u64));
605 preempt_enable();
606 }
607 }
608 }
609 }
610 err:
611 fsck_err:
612 percpu_up_write(&c->mark_lock);
613 printbuf_exit(&buf);
614 bch2_trans_put(trans);
615 bch_err_fn(c, ret);
616 return ret;
617 }
618
accounting_read_key(struct btree_trans * trans,struct bkey_s_c k)619 static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
620 {
621 struct bch_fs *c = trans->c;
622
623 if (k.k->type != KEY_TYPE_accounting)
624 return 0;
625
626 percpu_down_read(&c->mark_lock);
627 int ret = bch2_accounting_mem_mod_locked(trans, bkey_s_c_to_accounting(k),
628 BCH_ACCOUNTING_read, false);
629 percpu_up_read(&c->mark_lock);
630 return ret;
631 }
632
bch2_disk_accounting_validate_late(struct btree_trans * trans,struct disk_accounting_pos acc,u64 * v,unsigned nr)633 static int bch2_disk_accounting_validate_late(struct btree_trans *trans,
634 struct disk_accounting_pos acc,
635 u64 *v, unsigned nr)
636 {
637 struct bch_fs *c = trans->c;
638 struct printbuf buf = PRINTBUF;
639 int ret = 0, invalid_dev = -1;
640
641 switch (acc.type) {
642 case BCH_DISK_ACCOUNTING_replicas: {
643 struct bch_replicas_padded r;
644 __accounting_to_replicas(&r.e, &acc);
645
646 for (unsigned i = 0; i < r.e.nr_devs; i++)
647 if (r.e.devs[i] != BCH_SB_MEMBER_INVALID &&
648 !bch2_dev_exists(c, r.e.devs[i])) {
649 invalid_dev = r.e.devs[i];
650 goto invalid_device;
651 }
652
653 /*
654 * All replicas entry checks except for invalid device are done
655 * in bch2_accounting_validate
656 */
657 BUG_ON(bch2_replicas_entry_validate(&r.e, c, &buf));
658
659 if (fsck_err_on(!bch2_replicas_marked_locked(c, &r.e),
660 trans, accounting_replicas_not_marked,
661 "accounting not marked in superblock replicas\n%s",
662 (printbuf_reset(&buf),
663 bch2_accounting_key_to_text(&buf, &acc),
664 buf.buf))) {
665 /*
666 * We're not RW yet and still single threaded, dropping
667 * and retaking lock is ok:
668 */
669 percpu_up_write(&c->mark_lock);
670 ret = bch2_mark_replicas(c, &r.e);
671 if (ret)
672 goto fsck_err;
673 percpu_down_write(&c->mark_lock);
674 }
675 break;
676 }
677
678 case BCH_DISK_ACCOUNTING_dev_data_type:
679 if (!bch2_dev_exists(c, acc.dev_data_type.dev)) {
680 invalid_dev = acc.dev_data_type.dev;
681 goto invalid_device;
682 }
683 break;
684 }
685
686 fsck_err:
687 printbuf_exit(&buf);
688 return ret;
689 invalid_device:
690 if (fsck_err(trans, accounting_to_invalid_device,
691 "accounting entry points to invalid device %i\n%s",
692 invalid_dev,
693 (printbuf_reset(&buf),
694 bch2_accounting_key_to_text(&buf, &acc),
695 buf.buf))) {
696 for (unsigned i = 0; i < nr; i++)
697 v[i] = -v[i];
698
699 ret = commit_do(trans, NULL, NULL, 0,
700 bch2_disk_accounting_mod(trans, &acc, v, nr, false)) ?:
701 -BCH_ERR_remove_disk_accounting_entry;
702 } else {
703 ret = -BCH_ERR_remove_disk_accounting_entry;
704 }
705 goto fsck_err;
706 }
707
708 /*
709 * At startup time, initialize the in memory accounting from the btree (and
710 * journal)
711 */
bch2_accounting_read(struct bch_fs * c)712 int bch2_accounting_read(struct bch_fs *c)
713 {
714 struct bch_accounting_mem *acc = &c->accounting;
715 struct btree_trans *trans = bch2_trans_get(c);
716 struct printbuf buf = PRINTBUF;
717
718 /*
719 * We might run more than once if we rewind to start topology repair or
720 * btree node scan - and those might cause us to get different results,
721 * so we can't just skip if we've already run.
722 *
723 * Instead, zero out any accounting we have:
724 */
725 percpu_down_write(&c->mark_lock);
726 darray_for_each(acc->k, e)
727 percpu_memset(e->v[0], 0, sizeof(u64) * e->nr_counters);
728 for_each_member_device(c, ca)
729 percpu_memset(ca->usage, 0, sizeof(*ca->usage));
730 percpu_memset(c->usage, 0, sizeof(*c->usage));
731 percpu_up_write(&c->mark_lock);
732
733 struct btree_iter iter;
734 bch2_trans_iter_init(trans, &iter, BTREE_ID_accounting, POS_MIN,
735 BTREE_ITER_prefetch|BTREE_ITER_all_snapshots);
736 iter.flags &= ~BTREE_ITER_with_journal;
737 int ret = for_each_btree_key_continue(trans, iter,
738 BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, ({
739 struct bkey u;
740 struct bkey_s_c k = bch2_btree_path_peek_slot_exact(btree_iter_path(trans, &iter), &u);
741
742 if (k.k->type != KEY_TYPE_accounting)
743 continue;
744
745 struct disk_accounting_pos acc_k;
746 bpos_to_disk_accounting_pos(&acc_k, k.k->p);
747
748 if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
749 break;
750
751 if (!bch2_accounting_is_mem(acc_k)) {
752 struct disk_accounting_pos next;
753 memset(&next, 0, sizeof(next));
754 next.type = acc_k.type + 1;
755 bch2_btree_iter_set_pos(trans, &iter, disk_accounting_pos_to_bpos(&next));
756 continue;
757 }
758
759 accounting_read_key(trans, k);
760 }));
761 if (ret)
762 goto err;
763
764 struct journal_keys *keys = &c->journal_keys;
765 struct journal_key *dst = keys->data;
766 move_gap(keys, keys->nr);
767
768 darray_for_each(*keys, i) {
769 if (i->k->k.type == KEY_TYPE_accounting) {
770 struct disk_accounting_pos acc_k;
771 bpos_to_disk_accounting_pos(&acc_k, i->k->k.p);
772
773 if (!bch2_accounting_is_mem(acc_k))
774 continue;
775
776 struct bkey_s_c k = bkey_i_to_s_c(i->k);
777 unsigned idx = eytzinger0_find(acc->k.data, acc->k.nr,
778 sizeof(acc->k.data[0]),
779 accounting_pos_cmp, &k.k->p);
780
781 bool applied = idx < acc->k.nr &&
782 bversion_cmp(acc->k.data[idx].bversion, k.k->bversion) >= 0;
783
784 if (applied)
785 continue;
786
787 if (i + 1 < &darray_top(*keys) &&
788 i[1].k->k.type == KEY_TYPE_accounting &&
789 !journal_key_cmp(i, i + 1)) {
790 WARN_ON(bversion_cmp(i[0].k->k.bversion, i[1].k->k.bversion) >= 0);
791
792 i[1].journal_seq = i[0].journal_seq;
793
794 bch2_accounting_accumulate(bkey_i_to_accounting(i[1].k),
795 bkey_s_c_to_accounting(k));
796 continue;
797 }
798
799 ret = accounting_read_key(trans, k);
800 if (ret)
801 goto err;
802 }
803
804 *dst++ = *i;
805 }
806 keys->gap = keys->nr = dst - keys->data;
807
808 percpu_down_write(&c->mark_lock);
809
810 darray_for_each_reverse(acc->k, i) {
811 struct disk_accounting_pos acc_k;
812 bpos_to_disk_accounting_pos(&acc_k, i->pos);
813
814 u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
815 memset(v, 0, sizeof(v));
816
817 for (unsigned j = 0; j < i->nr_counters; j++)
818 v[j] = percpu_u64_get(i->v[0] + j);
819
820 /*
821 * If the entry counters are zeroed, it should be treated as
822 * nonexistent - it might point to an invalid device.
823 *
824 * Remove it, so that if it's re-added it gets re-marked in the
825 * superblock:
826 */
827 ret = bch2_is_zero(v, sizeof(v[0]) * i->nr_counters)
828 ? -BCH_ERR_remove_disk_accounting_entry
829 : bch2_disk_accounting_validate_late(trans, acc_k, v, i->nr_counters);
830
831 if (ret == -BCH_ERR_remove_disk_accounting_entry) {
832 free_percpu(i->v[0]);
833 free_percpu(i->v[1]);
834 darray_remove_item(&acc->k, i);
835 ret = 0;
836 continue;
837 }
838
839 if (ret)
840 goto fsck_err;
841 }
842
843 eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
844 accounting_pos_cmp, NULL);
845
846 preempt_disable();
847 struct bch_fs_usage_base *usage = this_cpu_ptr(c->usage);
848
849 for (unsigned i = 0; i < acc->k.nr; i++) {
850 struct disk_accounting_pos k;
851 bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);
852
853 u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
854 bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);
855
856 switch (k.type) {
857 case BCH_DISK_ACCOUNTING_persistent_reserved:
858 usage->reserved += v[0] * k.persistent_reserved.nr_replicas;
859 break;
860 case BCH_DISK_ACCOUNTING_replicas:
861 fs_usage_data_type_to_base(usage, k.replicas.data_type, v[0]);
862 break;
863 case BCH_DISK_ACCOUNTING_dev_data_type:
864 rcu_read_lock();
865 struct bch_dev *ca = bch2_dev_rcu_noerror(c, k.dev_data_type.dev);
866 if (ca) {
867 struct bch_dev_usage_type __percpu *d = &ca->usage->d[k.dev_data_type.data_type];
868 percpu_u64_set(&d->buckets, v[0]);
869 percpu_u64_set(&d->sectors, v[1]);
870 percpu_u64_set(&d->fragmented, v[2]);
871
872 if (k.dev_data_type.data_type == BCH_DATA_sb ||
873 k.dev_data_type.data_type == BCH_DATA_journal)
874 usage->hidden += v[0] * ca->mi.bucket_size;
875 }
876 rcu_read_unlock();
877 break;
878 }
879 }
880 preempt_enable();
881 fsck_err:
882 percpu_up_write(&c->mark_lock);
883 err:
884 printbuf_exit(&buf);
885 bch2_trans_put(trans);
886 bch_err_fn(c, ret);
887 return ret;
888 }
889
bch2_dev_usage_remove(struct bch_fs * c,unsigned dev)890 int bch2_dev_usage_remove(struct bch_fs *c, unsigned dev)
891 {
892 return bch2_trans_run(c,
893 bch2_btree_write_buffer_flush_sync(trans) ?:
894 for_each_btree_key_commit(trans, iter, BTREE_ID_accounting, POS_MIN,
895 BTREE_ITER_all_snapshots, k, NULL, NULL, 0, ({
896 struct disk_accounting_pos acc;
897 bpos_to_disk_accounting_pos(&acc, k.k->p);
898
899 acc.type == BCH_DISK_ACCOUNTING_dev_data_type &&
900 acc.dev_data_type.dev == dev
901 ? bch2_btree_bit_mod_buffered(trans, BTREE_ID_accounting, k.k->p, 0)
902 : 0;
903 })) ?:
904 bch2_btree_write_buffer_flush_sync(trans));
905 }
906
bch2_dev_usage_init(struct bch_dev * ca,bool gc)907 int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
908 {
909 struct bch_fs *c = ca->fs;
910 u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 };
911
912 int ret = bch2_trans_do(c, ({
913 bch2_disk_accounting_mod2(trans, gc,
914 v, dev_data_type,
915 .dev = ca->dev_idx,
916 .data_type = BCH_DATA_free) ?:
917 (!gc ? bch2_trans_commit(trans, NULL, NULL, 0) : 0);
918 }));
919 bch_err_fn(c, ret);
920 return ret;
921 }
922
bch2_verify_accounting_clean(struct bch_fs * c)923 void bch2_verify_accounting_clean(struct bch_fs *c)
924 {
925 bool mismatch = false;
926 struct bch_fs_usage_base base = {}, base_inmem = {};
927
928 bch2_trans_run(c,
929 for_each_btree_key(trans, iter,
930 BTREE_ID_accounting, POS_MIN,
931 BTREE_ITER_all_snapshots, k, ({
932 u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
933 struct bkey_s_c_accounting a = bkey_s_c_to_accounting(k);
934 unsigned nr = bch2_accounting_counters(k.k);
935
936 struct disk_accounting_pos acc_k;
937 bpos_to_disk_accounting_pos(&acc_k, k.k->p);
938
939 if (acc_k.type >= BCH_DISK_ACCOUNTING_TYPE_NR)
940 break;
941
942 if (!bch2_accounting_is_mem(acc_k)) {
943 struct disk_accounting_pos next;
944 memset(&next, 0, sizeof(next));
945 next.type = acc_k.type + 1;
946 bch2_btree_iter_set_pos(trans, &iter, disk_accounting_pos_to_bpos(&next));
947 continue;
948 }
949
950 bch2_accounting_mem_read(c, k.k->p, v, nr);
951
952 if (memcmp(a.v->d, v, nr * sizeof(u64))) {
953 struct printbuf buf = PRINTBUF;
954
955 bch2_bkey_val_to_text(&buf, c, k);
956 prt_str(&buf, " !=");
957 for (unsigned j = 0; j < nr; j++)
958 prt_printf(&buf, " %llu", v[j]);
959
960 pr_err("%s", buf.buf);
961 printbuf_exit(&buf);
962 mismatch = true;
963 }
964
965 switch (acc_k.type) {
966 case BCH_DISK_ACCOUNTING_persistent_reserved:
967 base.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0];
968 break;
969 case BCH_DISK_ACCOUNTING_replicas:
970 fs_usage_data_type_to_base(&base, acc_k.replicas.data_type, a.v->d[0]);
971 break;
972 case BCH_DISK_ACCOUNTING_dev_data_type: {
973 rcu_read_lock();
974 struct bch_dev *ca = bch2_dev_rcu_noerror(c, acc_k.dev_data_type.dev);
975 if (!ca) {
976 rcu_read_unlock();
977 continue;
978 }
979
980 v[0] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].buckets);
981 v[1] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].sectors);
982 v[2] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].fragmented);
983 rcu_read_unlock();
984
985 if (memcmp(a.v->d, v, 3 * sizeof(u64))) {
986 struct printbuf buf = PRINTBUF;
987
988 bch2_bkey_val_to_text(&buf, c, k);
989 prt_str(&buf, " in mem");
990 for (unsigned j = 0; j < nr; j++)
991 prt_printf(&buf, " %llu", v[j]);
992
993 pr_err("dev accounting mismatch: %s", buf.buf);
994 printbuf_exit(&buf);
995 mismatch = true;
996 }
997 }
998 }
999
1000 0;
1001 })));
1002
1003 acc_u64s_percpu(&base_inmem.hidden, &c->usage->hidden, sizeof(base_inmem) / sizeof(u64));
1004
1005 #define check(x) \
1006 if (base.x != base_inmem.x) { \
1007 pr_err("fs_usage_base.%s mismatch: %llu != %llu", #x, base.x, base_inmem.x); \
1008 mismatch = true; \
1009 }
1010
1011 //check(hidden);
1012 check(btree);
1013 check(data);
1014 check(cached);
1015 check(reserved);
1016 check(nr_inodes);
1017
1018 WARN_ON(mismatch);
1019 }
1020
bch2_accounting_gc_free(struct bch_fs * c)1021 void bch2_accounting_gc_free(struct bch_fs *c)
1022 {
1023 lockdep_assert_held(&c->mark_lock);
1024
1025 struct bch_accounting_mem *acc = &c->accounting;
1026
1027 bch2_accounting_free_counters(acc, true);
1028 acc->gc_running = false;
1029 }
1030
bch2_fs_accounting_exit(struct bch_fs * c)1031 void bch2_fs_accounting_exit(struct bch_fs *c)
1032 {
1033 struct bch_accounting_mem *acc = &c->accounting;
1034
1035 bch2_accounting_free_counters(acc, false);
1036 darray_exit(&acc->k);
1037 }
1038