|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | 2 |
|
3 | 3 | #include "bcachefs.h" |
| 4 | +#include "btree_cache.h" |
4 | 5 | #include "disk_groups.h" |
5 | 6 | #include "opts.h" |
6 | 7 | #include "replicas.h" |
@@ -426,3 +427,55 @@ void bch2_dev_errors_reset(struct bch_dev *ca) |
426 | 427 | bch2_write_super(c); |
427 | 428 | mutex_unlock(&c->sb_lock); |
428 | 429 | } |
| 430 | + |
| 431 | +/* |
| 432 | + * Per member "range has btree nodes" bitmap: |
| 433 | + * |
| 434 | + * This is so that if we ever have to run the btree node scan to repair we don't |
| 435 | + * have to scan full devices: |
| 436 | + */ |
| 437 | + |
| 438 | +bool bch2_dev_btree_bitmap_marked(struct bch_fs *c, struct bkey_s_c k) |
| 439 | +{ |
| 440 | + bkey_for_each_ptr(bch2_bkey_ptrs_c(k), ptr) |
| 441 | + if (!bch2_dev_btree_bitmap_marked_sectors(bch_dev_bkey_exists(c, ptr->dev), |
| 442 | + ptr->offset, btree_sectors(c))) |
| 443 | + return false; |
| 444 | + return true; |
| 445 | +} |
| 446 | + |
| 447 | +static void __bch2_dev_btree_bitmap_mark(struct bch_sb_field_members_v2 *mi, unsigned dev, |
| 448 | + u64 start, unsigned sectors) |
| 449 | +{ |
| 450 | + struct bch_member *m = __bch2_members_v2_get_mut(mi, dev); |
| 451 | + u64 bitmap = le64_to_cpu(m->btree_allocated_bitmap); |
| 452 | + |
| 453 | + u64 end = start + sectors; |
| 454 | + |
| 455 | + int resize = ilog2(roundup_pow_of_two(end)) - (m->btree_bitmap_shift + 6); |
| 456 | + if (resize > 0) { |
| 457 | + u64 new_bitmap = 0; |
| 458 | + |
| 459 | + for (unsigned i = 0; i < 64; i++) |
| 460 | + if (bitmap & BIT_ULL(i)) |
| 461 | + new_bitmap |= BIT_ULL(i >> resize); |
| 462 | + bitmap = new_bitmap; |
| 463 | + m->btree_bitmap_shift += resize; |
| 464 | + } |
| 465 | + |
| 466 | + for (unsigned bit = sectors >> m->btree_bitmap_shift; |
| 467 | + bit << m->btree_bitmap_shift < end; |
| 468 | + bit++) |
| 469 | + bitmap |= BIT_ULL(bit); |
| 470 | + |
| 471 | + m->btree_allocated_bitmap = cpu_to_le64(bitmap); |
| 472 | +} |
| 473 | + |
| 474 | +void bch2_dev_btree_bitmap_mark(struct bch_fs *c, struct bkey_s_c k) |
| 475 | +{ |
| 476 | + lockdep_assert_held(&c->sb_lock); |
| 477 | + |
| 478 | + struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2); |
| 479 | + bkey_for_each_ptr(bch2_bkey_ptrs_c(k), ptr) |
| 480 | + __bch2_dev_btree_bitmap_mark(mi, ptr->dev, ptr->offset, btree_sectors(c)); |
| 481 | +} |
0 commit comments