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, §ors, 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, §ors, 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