xref: /linux/fs/bcachefs/disk_accounting.c (revision f879306834818ebd1722a4372079610cdd466fec)
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 
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 int bch2_disk_accounting_mod(struct btree_trans *trans,
83 			     struct disk_accounting_pos *k,
84 			     s64 *d, unsigned nr, bool gc)
85 {
86 	/* Normalize: */
87 	switch (k->type) {
88 	case BCH_DISK_ACCOUNTING_replicas:
89 		bubble_sort(k->replicas.devs, k->replicas.nr_devs, u8_cmp);
90 		break;
91 	}
92 
93 	BUG_ON(nr > BCH_ACCOUNTING_MAX_COUNTERS);
94 
95 	struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;
96 
97 	accounting_key_init(&k_i.k, k, d, nr);
98 
99 	return likely(!gc)
100 		? bch2_trans_update_buffered(trans, BTREE_ID_accounting, &k_i.k)
101 		: bch2_accounting_mem_add(trans, bkey_i_to_s_c_accounting(&k_i.k), true);
102 }
103 
104 int bch2_mod_dev_cached_sectors(struct btree_trans *trans,
105 				unsigned dev, s64 sectors,
106 				bool gc)
107 {
108 	struct disk_accounting_pos acc = {
109 		.type = BCH_DISK_ACCOUNTING_replicas,
110 	};
111 
112 	bch2_replicas_entry_cached(&acc.replicas, dev);
113 
114 	return bch2_disk_accounting_mod(trans, &acc, &sectors, 1, gc);
115 }
116 
117 int bch2_accounting_invalid(struct bch_fs *c, struct bkey_s_c k,
118 			    enum bch_validate_flags flags,
119 			    struct printbuf *err)
120 {
121 	return 0;
122 }
123 
124 void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k)
125 {
126 	if (k->type >= BCH_DISK_ACCOUNTING_TYPE_NR) {
127 		prt_printf(out, "unknown type %u", k->type);
128 		return;
129 	}
130 
131 	prt_str(out, disk_accounting_type_strs[k->type]);
132 	prt_str(out, " ");
133 
134 	switch (k->type) {
135 	case BCH_DISK_ACCOUNTING_nr_inodes:
136 		break;
137 	case BCH_DISK_ACCOUNTING_persistent_reserved:
138 		prt_printf(out, "replicas=%u", k->persistent_reserved.nr_replicas);
139 		break;
140 	case BCH_DISK_ACCOUNTING_replicas:
141 		bch2_replicas_entry_to_text(out, &k->replicas);
142 		break;
143 	case BCH_DISK_ACCOUNTING_dev_data_type:
144 		prt_printf(out, "dev=%u data_type=", k->dev_data_type.dev);
145 		bch2_prt_data_type(out, k->dev_data_type.data_type);
146 		break;
147 	case BCH_DISK_ACCOUNTING_compression:
148 		bch2_prt_compression_type(out, k->compression.type);
149 		break;
150 	case BCH_DISK_ACCOUNTING_snapshot:
151 		prt_printf(out, "id=%u", k->snapshot.id);
152 		break;
153 	case BCH_DISK_ACCOUNTING_btree:
154 		prt_printf(out, "btree=%s", bch2_btree_id_str(k->btree.id));
155 		break;
156 	}
157 }
158 
159 void bch2_accounting_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
160 {
161 	struct bkey_s_c_accounting acc = bkey_s_c_to_accounting(k);
162 	struct disk_accounting_pos acc_k;
163 	bpos_to_disk_accounting_pos(&acc_k, k.k->p);
164 
165 	bch2_accounting_key_to_text(out, &acc_k);
166 
167 	for (unsigned i = 0; i < bch2_accounting_counters(k.k); i++)
168 		prt_printf(out, " %lli", acc.v->d[i]);
169 }
170 
171 void bch2_accounting_swab(struct bkey_s k)
172 {
173 	for (u64 *p = (u64 *) k.v;
174 	     p < (u64 *) bkey_val_end(k);
175 	     p++)
176 		*p = swab64(*p);
177 }
178 
179 static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p)
180 {
181 	struct disk_accounting_pos acc_k;
182 	bpos_to_disk_accounting_pos(&acc_k, p);
183 
184 	switch (acc_k.type) {
185 	case BCH_DISK_ACCOUNTING_replicas:
186 		unsafe_memcpy(r, &acc_k.replicas,
187 			      replicas_entry_bytes(&acc_k.replicas),
188 			      "variable length struct");
189 		return true;
190 	default:
191 		return false;
192 	}
193 }
194 
195 static int bch2_accounting_update_sb_one(struct bch_fs *c, struct bpos p)
196 {
197 	struct bch_replicas_padded r;
198 	return accounting_to_replicas(&r.e, p)
199 		? bch2_mark_replicas(c, &r.e)
200 		: 0;
201 }
202 
203 /*
204  * Ensure accounting keys being updated are present in the superblock, when
205  * applicable (i.e. replicas updates)
206  */
207 int bch2_accounting_update_sb(struct btree_trans *trans)
208 {
209 	for (struct jset_entry *i = trans->journal_entries;
210 	     i != (void *) ((u64 *) trans->journal_entries + trans->journal_entries_u64s);
211 	     i = vstruct_next(i))
212 		if (jset_entry_is_key(i) && i->start->k.type == KEY_TYPE_accounting) {
213 			int ret = bch2_accounting_update_sb_one(trans->c, i->start->k.p);
214 			if (ret)
215 				return ret;
216 		}
217 
218 	return 0;
219 }
220 
221 static int __bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a)
222 {
223 	struct bch_accounting_mem *acc = &c->accounting;
224 
225 	/* raced with another insert, already present: */
226 	if (eytzinger0_find(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
227 			    accounting_pos_cmp, &a.k->p) < acc->k.nr)
228 		return 0;
229 
230 	struct accounting_mem_entry n = {
231 		.pos		= a.k->p,
232 		.version	= a.k->version,
233 		.nr_counters	= bch2_accounting_counters(a.k),
234 		.v[0]		= __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
235 						     sizeof(u64), GFP_KERNEL),
236 	};
237 
238 	if (!n.v[0])
239 		goto err;
240 
241 	if (acc->gc_running) {
242 		n.v[1] = __alloc_percpu_gfp(n.nr_counters * sizeof(u64),
243 					    sizeof(u64), GFP_KERNEL);
244 		if (!n.v[1])
245 			goto err;
246 	}
247 
248 	if (darray_push(&acc->k, n))
249 		goto err;
250 
251 	eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
252 			accounting_pos_cmp, NULL);
253 	return 0;
254 err:
255 	free_percpu(n.v[1]);
256 	free_percpu(n.v[0]);
257 	return -BCH_ERR_ENOMEM_disk_accounting;
258 }
259 
260 int bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a, bool gc)
261 {
262 	struct bch_replicas_padded r;
263 
264 	if (accounting_to_replicas(&r.e, a.k->p) &&
265 	    !bch2_replicas_marked_locked(c, &r.e))
266 		return -BCH_ERR_btree_insert_need_mark_replicas;
267 
268 	percpu_up_read(&c->mark_lock);
269 	percpu_down_write(&c->mark_lock);
270 	int ret = __bch2_accounting_mem_insert(c, a);
271 	percpu_up_write(&c->mark_lock);
272 	percpu_down_read(&c->mark_lock);
273 	return ret;
274 }
275 
276 static bool accounting_mem_entry_is_zero(struct accounting_mem_entry *e)
277 {
278 	for (unsigned i = 0; i < e->nr_counters; i++)
279 		if (percpu_u64_get(e->v[0] + i) ||
280 		    (e->v[1] &&
281 		     percpu_u64_get(e->v[1] + i)))
282 			return false;
283 	return true;
284 }
285 
286 void bch2_accounting_mem_gc(struct bch_fs *c)
287 {
288 	struct bch_accounting_mem *acc = &c->accounting;
289 
290 	percpu_down_write(&c->mark_lock);
291 	struct accounting_mem_entry *dst = acc->k.data;
292 
293 	darray_for_each(acc->k, src) {
294 		if (accounting_mem_entry_is_zero(src)) {
295 			free_percpu(src->v[0]);
296 			free_percpu(src->v[1]);
297 		} else {
298 			*dst++ = *src;
299 		}
300 	}
301 
302 	acc->k.nr = dst - acc->k.data;
303 	eytzinger0_sort(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
304 			accounting_pos_cmp, NULL);
305 	percpu_up_write(&c->mark_lock);
306 }
307 
308 /*
309  * Read out accounting keys for replicas entries, as an array of
310  * bch_replicas_usage entries.
311  *
312  * Note: this may be deprecated/removed at smoe point in the future and replaced
313  * with something more general, it exists to support the ioctl used by the
314  * 'bcachefs fs usage' command.
315  */
316 int bch2_fs_replicas_usage_read(struct bch_fs *c, darray_char *usage)
317 {
318 	struct bch_accounting_mem *acc = &c->accounting;
319 	int ret = 0;
320 
321 	darray_init(usage);
322 
323 	percpu_down_read(&c->mark_lock);
324 	darray_for_each(acc->k, i) {
325 		struct {
326 			struct bch_replicas_usage r;
327 			u8 pad[BCH_BKEY_PTRS_MAX];
328 		} u;
329 
330 		if (!accounting_to_replicas(&u.r.r, i->pos))
331 			continue;
332 
333 		u64 sectors;
334 		bch2_accounting_mem_read_counters(acc, i - acc->k.data, &sectors, 1, false);
335 		u.r.sectors = sectors;
336 
337 		ret = darray_make_room(usage, replicas_usage_bytes(&u.r));
338 		if (ret)
339 			break;
340 
341 		memcpy(&darray_top(*usage), &u.r, replicas_usage_bytes(&u.r));
342 		usage->nr += replicas_usage_bytes(&u.r);
343 	}
344 	percpu_up_read(&c->mark_lock);
345 
346 	if (ret)
347 		darray_exit(usage);
348 	return ret;
349 }
350 
351 int bch2_fs_accounting_read(struct bch_fs *c, darray_char *out_buf, unsigned accounting_types_mask)
352 {
353 
354 	struct bch_accounting_mem *acc = &c->accounting;
355 	int ret = 0;
356 
357 	darray_init(out_buf);
358 
359 	percpu_down_read(&c->mark_lock);
360 	darray_for_each(acc->k, i) {
361 		struct disk_accounting_pos a_p;
362 		bpos_to_disk_accounting_pos(&a_p, i->pos);
363 
364 		if (!(accounting_types_mask & BIT(a_p.type)))
365 			continue;
366 
367 		ret = darray_make_room(out_buf, sizeof(struct bkey_i_accounting) +
368 				       sizeof(u64) * i->nr_counters);
369 		if (ret)
370 			break;
371 
372 		struct bkey_i_accounting *a_out =
373 			bkey_accounting_init((void *) &darray_top(*out_buf));
374 		set_bkey_val_u64s(&a_out->k, i->nr_counters);
375 		a_out->k.p = i->pos;
376 		bch2_accounting_mem_read_counters(acc, i - acc->k.data,
377 						  a_out->v.d, i->nr_counters, false);
378 
379 		if (!bch2_accounting_key_is_zero(accounting_i_to_s_c(a_out)))
380 			out_buf->nr += bkey_bytes(&a_out->k);
381 	}
382 
383 	percpu_up_read(&c->mark_lock);
384 
385 	if (ret)
386 		darray_exit(out_buf);
387 	return ret;
388 }
389 
390 void bch2_fs_accounting_to_text(struct printbuf *out, struct bch_fs *c)
391 {
392 	struct bch_accounting_mem *acc = &c->accounting;
393 
394 	percpu_down_read(&c->mark_lock);
395 	out->atomic++;
396 
397 	eytzinger0_for_each(i, acc->k.nr) {
398 		struct disk_accounting_pos acc_k;
399 		bpos_to_disk_accounting_pos(&acc_k, acc->k.data[i].pos);
400 
401 		bch2_accounting_key_to_text(out, &acc_k);
402 
403 		u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
404 		bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);
405 
406 		prt_str(out, ":");
407 		for (unsigned j = 0; j < acc->k.data[i].nr_counters; j++)
408 			prt_printf(out, " %llu", v[j]);
409 		prt_newline(out);
410 	}
411 
412 	--out->atomic;
413 	percpu_up_read(&c->mark_lock);
414 }
415 
416 static void bch2_accounting_free_counters(struct bch_accounting_mem *acc, bool gc)
417 {
418 	darray_for_each(acc->k, e) {
419 		free_percpu(e->v[gc]);
420 		e->v[gc] = NULL;
421 	}
422 }
423 
424 int bch2_gc_accounting_start(struct bch_fs *c)
425 {
426 	struct bch_accounting_mem *acc = &c->accounting;
427 	int ret = 0;
428 
429 	percpu_down_write(&c->mark_lock);
430 	darray_for_each(acc->k, e) {
431 		e->v[1] = __alloc_percpu_gfp(e->nr_counters * sizeof(u64),
432 					     sizeof(u64), GFP_KERNEL);
433 		if (!e->v[1]) {
434 			bch2_accounting_free_counters(acc, true);
435 			ret = -BCH_ERR_ENOMEM_disk_accounting;
436 			break;
437 		}
438 	}
439 
440 	acc->gc_running = !ret;
441 	percpu_up_write(&c->mark_lock);
442 
443 	return ret;
444 }
445 
446 int bch2_gc_accounting_done(struct bch_fs *c)
447 {
448 	struct bch_accounting_mem *acc = &c->accounting;
449 	struct btree_trans *trans = bch2_trans_get(c);
450 	struct printbuf buf = PRINTBUF;
451 	struct bpos pos = POS_MIN;
452 	int ret = 0;
453 
454 	percpu_down_write(&c->mark_lock);
455 	while (1) {
456 		unsigned idx = eytzinger0_find_ge(acc->k.data, acc->k.nr, sizeof(acc->k.data[0]),
457 						  accounting_pos_cmp, &pos);
458 
459 		if (idx >= acc->k.nr)
460 			break;
461 
462 		struct accounting_mem_entry *e = acc->k.data + idx;
463 		pos = bpos_successor(e->pos);
464 
465 		struct disk_accounting_pos acc_k;
466 		bpos_to_disk_accounting_pos(&acc_k, e->pos);
467 
468 		u64 src_v[BCH_ACCOUNTING_MAX_COUNTERS];
469 		u64 dst_v[BCH_ACCOUNTING_MAX_COUNTERS];
470 
471 		unsigned nr = e->nr_counters;
472 		bch2_accounting_mem_read_counters(acc, idx, dst_v, nr, false);
473 		bch2_accounting_mem_read_counters(acc, idx, src_v, nr, true);
474 
475 		if (memcmp(dst_v, src_v, nr * sizeof(u64))) {
476 			printbuf_reset(&buf);
477 			prt_str(&buf, "accounting mismatch for ");
478 			bch2_accounting_key_to_text(&buf, &acc_k);
479 
480 			prt_str(&buf, ": got");
481 			for (unsigned j = 0; j < nr; j++)
482 				prt_printf(&buf, " %llu", dst_v[j]);
483 
484 			prt_str(&buf, " should be");
485 			for (unsigned j = 0; j < nr; j++)
486 				prt_printf(&buf, " %llu", src_v[j]);
487 
488 			for (unsigned j = 0; j < nr; j++)
489 				src_v[j] -= dst_v[j];
490 
491 			if (fsck_err(trans, accounting_mismatch, "%s", buf.buf)) {
492 				percpu_up_write(&c->mark_lock);
493 				ret = commit_do(trans, NULL, NULL, 0,
494 						bch2_disk_accounting_mod(trans, &acc_k, src_v, nr, false));
495 				percpu_down_write(&c->mark_lock);
496 				if (ret)
497 					goto err;
498 
499 				if (!test_bit(BCH_FS_may_go_rw, &c->flags)) {
500 					memset(&trans->fs_usage_delta, 0, sizeof(trans->fs_usage_delta));
501 					struct { __BKEY_PADDED(k, BCH_ACCOUNTING_MAX_COUNTERS); } k_i;
502 
503 					accounting_key_init(&k_i.k, &acc_k, src_v, nr);
504 					bch2_accounting_mem_mod_locked(trans, bkey_i_to_s_c_accounting(&k_i.k), false);
505 
506 					preempt_disable();
507 					struct bch_fs_usage_base *dst = this_cpu_ptr(c->usage);
508 					struct bch_fs_usage_base *src = &trans->fs_usage_delta;
509 					acc_u64s((u64 *) dst, (u64 *) src, sizeof(*src) / sizeof(u64));
510 					preempt_enable();
511 				}
512 			}
513 		}
514 	}
515 err:
516 fsck_err:
517 	percpu_up_write(&c->mark_lock);
518 	printbuf_exit(&buf);
519 	bch2_trans_put(trans);
520 	bch_err_fn(c, ret);
521 	return ret;
522 }
523 
524 static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
525 {
526 	struct bch_fs *c = trans->c;
527 	struct printbuf buf = PRINTBUF;
528 
529 	if (k.k->type != KEY_TYPE_accounting)
530 		return 0;
531 
532 	percpu_down_read(&c->mark_lock);
533 	int ret = __bch2_accounting_mem_mod(c, bkey_s_c_to_accounting(k), false);
534 	percpu_up_read(&c->mark_lock);
535 
536 	if (bch2_accounting_key_is_zero(bkey_s_c_to_accounting(k)) &&
537 	    ret == -BCH_ERR_btree_insert_need_mark_replicas)
538 		ret = 0;
539 
540 	struct disk_accounting_pos acc;
541 	bpos_to_disk_accounting_pos(&acc, k.k->p);
542 
543 	if (fsck_err_on(ret == -BCH_ERR_btree_insert_need_mark_replicas,
544 			trans, accounting_replicas_not_marked,
545 			"accounting not marked in superblock replicas\n  %s",
546 			(bch2_accounting_key_to_text(&buf, &acc),
547 			 buf.buf)))
548 		ret = bch2_accounting_update_sb_one(c, k.k->p);
549 fsck_err:
550 	printbuf_exit(&buf);
551 	return ret;
552 }
553 
554 /*
555  * At startup time, initialize the in memory accounting from the btree (and
556  * journal)
557  */
558 int bch2_accounting_read(struct bch_fs *c)
559 {
560 	struct bch_accounting_mem *acc = &c->accounting;
561 	struct btree_trans *trans = bch2_trans_get(c);
562 
563 	int ret = for_each_btree_key(trans, iter,
564 				BTREE_ID_accounting, POS_MIN,
565 				BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, ({
566 			struct bkey u;
567 			struct bkey_s_c k = bch2_btree_path_peek_slot_exact(btree_iter_path(trans, &iter), &u);
568 			accounting_read_key(trans, k);
569 		}));
570 	if (ret)
571 		goto err;
572 
573 	struct journal_keys *keys = &c->journal_keys;
574 	struct journal_key *dst = keys->data;
575 	move_gap(keys, keys->nr);
576 
577 	darray_for_each(*keys, i) {
578 		if (i->k->k.type == KEY_TYPE_accounting) {
579 			struct bkey_s_c k = bkey_i_to_s_c(i->k);
580 			unsigned idx = eytzinger0_find(acc->k.data, acc->k.nr,
581 						sizeof(acc->k.data[0]),
582 						accounting_pos_cmp, &k.k->p);
583 
584 			bool applied = idx < acc->k.nr &&
585 				bversion_cmp(acc->k.data[idx].version, k.k->version) >= 0;
586 
587 			if (applied)
588 				continue;
589 
590 			if (i + 1 < &darray_top(*keys) &&
591 			    i[1].k->k.type == KEY_TYPE_accounting &&
592 			    !journal_key_cmp(i, i + 1)) {
593 				BUG_ON(bversion_cmp(i[0].k->k.version, i[1].k->k.version) >= 0);
594 
595 				i[1].journal_seq = i[0].journal_seq;
596 
597 				bch2_accounting_accumulate(bkey_i_to_accounting(i[1].k),
598 							   bkey_s_c_to_accounting(k));
599 				continue;
600 			}
601 
602 			ret = accounting_read_key(trans, k);
603 			if (ret)
604 				goto err;
605 		}
606 
607 		*dst++ = *i;
608 	}
609 	keys->gap = keys->nr = dst - keys->data;
610 
611 	percpu_down_read(&c->mark_lock);
612 	preempt_disable();
613 	struct bch_fs_usage_base *usage = this_cpu_ptr(c->usage);
614 
615 	for (unsigned i = 0; i < acc->k.nr; i++) {
616 		struct disk_accounting_pos k;
617 		bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);
618 
619 		u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
620 		bch2_accounting_mem_read_counters(acc, i, v, ARRAY_SIZE(v), false);
621 
622 		switch (k.type) {
623 		case BCH_DISK_ACCOUNTING_persistent_reserved:
624 			usage->reserved += v[0] * k.persistent_reserved.nr_replicas;
625 			break;
626 		case BCH_DISK_ACCOUNTING_replicas:
627 			fs_usage_data_type_to_base(usage, k.replicas.data_type, v[0]);
628 			break;
629 		case BCH_DISK_ACCOUNTING_dev_data_type:
630 			rcu_read_lock();
631 			struct bch_dev *ca = bch2_dev_rcu(c, k.dev_data_type.dev);
632 			if (ca) {
633 				struct bch_dev_usage_type __percpu *d = &ca->usage->d[k.dev_data_type.data_type];
634 				percpu_u64_set(&d->buckets,	v[0]);
635 				percpu_u64_set(&d->sectors,	v[1]);
636 				percpu_u64_set(&d->fragmented,	v[2]);
637 
638 				if (k.dev_data_type.data_type == BCH_DATA_sb ||
639 				    k.dev_data_type.data_type == BCH_DATA_journal)
640 					usage->hidden += v[0] * ca->mi.bucket_size;
641 			}
642 			rcu_read_unlock();
643 			break;
644 		}
645 	}
646 	preempt_enable();
647 	percpu_up_read(&c->mark_lock);
648 err:
649 	bch2_trans_put(trans);
650 	bch_err_fn(c, ret);
651 	return ret;
652 }
653 
654 int bch2_dev_usage_remove(struct bch_fs *c, unsigned dev)
655 {
656 	return bch2_trans_run(c,
657 		bch2_btree_write_buffer_flush_sync(trans) ?:
658 		for_each_btree_key_commit(trans, iter, BTREE_ID_accounting, POS_MIN,
659 				BTREE_ITER_all_snapshots, k, NULL, NULL, 0, ({
660 			struct disk_accounting_pos acc;
661 			bpos_to_disk_accounting_pos(&acc, k.k->p);
662 
663 			acc.type == BCH_DISK_ACCOUNTING_dev_data_type &&
664 			acc.dev_data_type.dev == dev
665 				? bch2_btree_bit_mod_buffered(trans, BTREE_ID_accounting, k.k->p, 0)
666 				: 0;
667 		})) ?:
668 		bch2_btree_write_buffer_flush_sync(trans));
669 }
670 
671 int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
672 {
673 	struct bch_fs *c = ca->fs;
674 	struct disk_accounting_pos acc = {
675 		.type = BCH_DISK_ACCOUNTING_dev_data_type,
676 		.dev_data_type.dev = ca->dev_idx,
677 		.dev_data_type.data_type = BCH_DATA_free,
678 	};
679 	u64 v[3] = { ca->mi.nbuckets - ca->mi.first_bucket, 0, 0 };
680 
681 	int ret = bch2_trans_do(c, NULL, NULL, 0,
682 			bch2_disk_accounting_mod(trans, &acc, v, ARRAY_SIZE(v), gc));
683 	bch_err_fn(c, ret);
684 	return ret;
685 }
686 
687 void bch2_verify_accounting_clean(struct bch_fs *c)
688 {
689 	bool mismatch = false;
690 	struct bch_fs_usage_base base = {}, base_inmem = {};
691 
692 	bch2_trans_run(c,
693 		for_each_btree_key(trans, iter,
694 				   BTREE_ID_accounting, POS_MIN,
695 				   BTREE_ITER_all_snapshots, k, ({
696 			u64 v[BCH_ACCOUNTING_MAX_COUNTERS];
697 			struct bkey_s_c_accounting a = bkey_s_c_to_accounting(k);
698 			unsigned nr = bch2_accounting_counters(k.k);
699 
700 			bch2_accounting_mem_read(c, k.k->p, v, nr);
701 
702 			if (memcmp(a.v->d, v, nr * sizeof(u64))) {
703 				struct printbuf buf = PRINTBUF;
704 
705 				bch2_bkey_val_to_text(&buf, c, k);
706 				prt_str(&buf, " !=");
707 				for (unsigned j = 0; j < nr; j++)
708 					prt_printf(&buf, " %llu", v[j]);
709 
710 				pr_err("%s", buf.buf);
711 				printbuf_exit(&buf);
712 				mismatch = true;
713 			}
714 
715 			struct disk_accounting_pos acc_k;
716 			bpos_to_disk_accounting_pos(&acc_k, a.k->p);
717 
718 			switch (acc_k.type) {
719 			case BCH_DISK_ACCOUNTING_persistent_reserved:
720 				base.reserved += acc_k.persistent_reserved.nr_replicas * a.v->d[0];
721 				break;
722 			case BCH_DISK_ACCOUNTING_replicas:
723 				fs_usage_data_type_to_base(&base, acc_k.replicas.data_type, a.v->d[0]);
724 				break;
725 			case BCH_DISK_ACCOUNTING_dev_data_type: {
726 				rcu_read_lock();
727 				struct bch_dev *ca = bch2_dev_rcu(c, acc_k.dev_data_type.dev);
728 				if (!ca) {
729 					rcu_read_unlock();
730 					continue;
731 				}
732 
733 				v[0] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].buckets);
734 				v[1] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].sectors);
735 				v[2] = percpu_u64_get(&ca->usage->d[acc_k.dev_data_type.data_type].fragmented);
736 				rcu_read_unlock();
737 
738 				if (memcmp(a.v->d, v, 3 * sizeof(u64))) {
739 					struct printbuf buf = PRINTBUF;
740 
741 					bch2_bkey_val_to_text(&buf, c, k);
742 					prt_str(&buf, " in mem");
743 					for (unsigned j = 0; j < nr; j++)
744 						prt_printf(&buf, " %llu", v[j]);
745 
746 					pr_err("dev accounting mismatch: %s", buf.buf);
747 					printbuf_exit(&buf);
748 					mismatch = true;
749 				}
750 			}
751 			}
752 
753 			0;
754 		})));
755 
756 	acc_u64s_percpu(&base_inmem.hidden, &c->usage->hidden, sizeof(base_inmem) / sizeof(u64));
757 
758 #define check(x)										\
759 	if (base.x != base_inmem.x) {								\
760 		pr_err("fs_usage_base.%s mismatch: %llu != %llu", #x, base.x, base_inmem.x);	\
761 		mismatch = true;								\
762 	}
763 
764 	//check(hidden);
765 	check(btree);
766 	check(data);
767 	check(cached);
768 	check(reserved);
769 	check(nr_inodes);
770 
771 	WARN_ON(mismatch);
772 }
773 
774 void bch2_accounting_gc_free(struct bch_fs *c)
775 {
776 	lockdep_assert_held(&c->mark_lock);
777 
778 	struct bch_accounting_mem *acc = &c->accounting;
779 
780 	bch2_accounting_free_counters(acc, true);
781 	acc->gc_running = false;
782 }
783 
784 void bch2_fs_accounting_exit(struct bch_fs *c)
785 {
786 	struct bch_accounting_mem *acc = &c->accounting;
787 
788 	bch2_accounting_free_counters(acc, false);
789 	darray_exit(&acc->k);
790 }
791