Skip to content

Commit 49aa783

Browse files
author
Kent Overstreet
committed
bcachefs: Fix rebalance_work accounting
rebalance_work was keying off of the presence of rebelance_opts in the extent - but that was incorrect, we keep those around after rebalance for indirect extents since the inode's options are not directly available Fixes: 20ac515 ("bcachefs: bch_acct_rebalance_work") Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent d320461 commit 49aa783

File tree

5 files changed

+98
-27
lines changed

5 files changed

+98
-27
lines changed

fs/bcachefs/bcachefs_format.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,8 @@ struct bch_sb_field_ext {
677677
x(bucket_stripe_sectors, BCH_VERSION(1, 8)) \
678678
x(disk_accounting_v2, BCH_VERSION(1, 9)) \
679679
x(disk_accounting_v3, BCH_VERSION(1, 10)) \
680-
x(disk_accounting_inum, BCH_VERSION(1, 11))
680+
x(disk_accounting_inum, BCH_VERSION(1, 11)) \
681+
x(rebalance_work_acct_fix, BCH_VERSION(1, 12))
681682

682683
enum bcachefs_metadata_version {
683684
bcachefs_metadata_version_min = 9,

fs/bcachefs/buckets.c

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,8 @@ static int bch2_trigger_stripe_ptr(struct btree_trans *trans,
699699
static int __trigger_extent(struct btree_trans *trans,
700700
enum btree_id btree_id, unsigned level,
701701
struct bkey_s_c k,
702-
enum btree_iter_update_trigger_flags flags)
702+
enum btree_iter_update_trigger_flags flags,
703+
s64 *replicas_sectors)
703704
{
704705
bool gc = flags & BTREE_TRIGGER_gc;
705706
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
@@ -708,7 +709,6 @@ static int __trigger_extent(struct btree_trans *trans,
708709
enum bch_data_type data_type = bkey_is_btree_ptr(k.k)
709710
? BCH_DATA_btree
710711
: BCH_DATA_user;
711-
s64 replicas_sectors = 0;
712712
int ret = 0;
713713

714714
struct disk_accounting_pos acc_replicas_key = {
@@ -739,7 +739,7 @@ static int __trigger_extent(struct btree_trans *trans,
739739
if (ret)
740740
return ret;
741741
} else if (!p.has_ec) {
742-
replicas_sectors += disk_sectors;
742+
*replicas_sectors += disk_sectors;
743743
acc_replicas_key.replicas.devs[acc_replicas_key.replicas.nr_devs++] = p.ptr.dev;
744744
} else {
745745
ret = bch2_trigger_stripe_ptr(trans, k, p, data_type, disk_sectors, flags);
@@ -777,7 +777,7 @@ static int __trigger_extent(struct btree_trans *trans,
777777
}
778778

779779
if (acc_replicas_key.replicas.nr_devs) {
780-
ret = bch2_disk_accounting_mod(trans, &acc_replicas_key, &replicas_sectors, 1, gc);
780+
ret = bch2_disk_accounting_mod(trans, &acc_replicas_key, replicas_sectors, 1, gc);
781781
if (ret)
782782
return ret;
783783
}
@@ -787,7 +787,7 @@ static int __trigger_extent(struct btree_trans *trans,
787787
.type = BCH_DISK_ACCOUNTING_snapshot,
788788
.snapshot.id = k.k->p.snapshot,
789789
};
790-
ret = bch2_disk_accounting_mod(trans, &acc_snapshot_key, &replicas_sectors, 1, gc);
790+
ret = bch2_disk_accounting_mod(trans, &acc_snapshot_key, replicas_sectors, 1, gc);
791791
if (ret)
792792
return ret;
793793
}
@@ -807,7 +807,7 @@ static int __trigger_extent(struct btree_trans *trans,
807807
.type = BCH_DISK_ACCOUNTING_btree,
808808
.btree.id = btree_id,
809809
};
810-
ret = bch2_disk_accounting_mod(trans, &acc_btree_key, &replicas_sectors, 1, gc);
810+
ret = bch2_disk_accounting_mod(trans, &acc_btree_key, replicas_sectors, 1, gc);
811811
if (ret)
812812
return ret;
813813
} else {
@@ -819,22 +819,13 @@ static int __trigger_extent(struct btree_trans *trans,
819819
s64 v[3] = {
820820
insert ? 1 : -1,
821821
insert ? k.k->size : -((s64) k.k->size),
822-
replicas_sectors,
822+
*replicas_sectors,
823823
};
824824
ret = bch2_disk_accounting_mod(trans, &acc_inum_key, v, ARRAY_SIZE(v), gc);
825825
if (ret)
826826
return ret;
827827
}
828828

829-
if (bch2_bkey_rebalance_opts(k)) {
830-
struct disk_accounting_pos acc = {
831-
.type = BCH_DISK_ACCOUNTING_rebalance_work,
832-
};
833-
ret = bch2_disk_accounting_mod(trans, &acc, &replicas_sectors, 1, gc);
834-
if (ret)
835-
return ret;
836-
}
837-
838829
return 0;
839830
}
840831

@@ -843,6 +834,7 @@ int bch2_trigger_extent(struct btree_trans *trans,
843834
struct bkey_s_c old, struct bkey_s new,
844835
enum btree_iter_update_trigger_flags flags)
845836
{
837+
struct bch_fs *c = trans->c;
846838
struct bkey_ptrs_c new_ptrs = bch2_bkey_ptrs_c(new.s_c);
847839
struct bkey_ptrs_c old_ptrs = bch2_bkey_ptrs_c(old);
848840
unsigned new_ptrs_bytes = (void *) new_ptrs.end - (void *) new_ptrs.start;
@@ -858,21 +850,53 @@ int bch2_trigger_extent(struct btree_trans *trans,
858850
new_ptrs_bytes))
859851
return 0;
860852

861-
if (flags & BTREE_TRIGGER_transactional) {
862-
struct bch_fs *c = trans->c;
863-
int mod = (int) bch2_bkey_needs_rebalance(c, new.s_c) -
864-
(int) bch2_bkey_needs_rebalance(c, old);
853+
if (flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc)) {
854+
s64 old_replicas_sectors = 0, new_replicas_sectors = 0;
855+
856+
if (old.k->type) {
857+
int ret = __trigger_extent(trans, btree, level, old,
858+
flags & ~BTREE_TRIGGER_insert,
859+
&old_replicas_sectors);
860+
if (ret)
861+
return ret;
862+
}
863+
864+
if (new.k->type) {
865+
int ret = __trigger_extent(trans, btree, level, new.s_c,
866+
flags & ~BTREE_TRIGGER_overwrite,
867+
&new_replicas_sectors);
868+
if (ret)
869+
return ret;
870+
}
871+
872+
int need_rebalance_delta = 0;
873+
s64 need_rebalance_sectors_delta = 0;
874+
875+
s64 s = bch2_bkey_sectors_need_rebalance(c, old);
876+
need_rebalance_delta -= s != 0;
877+
need_rebalance_sectors_delta -= s;
865878

866-
if (mod) {
879+
s = bch2_bkey_sectors_need_rebalance(c, old);
880+
need_rebalance_delta += s != 0;
881+
need_rebalance_sectors_delta += s;
882+
883+
if ((flags & BTREE_TRIGGER_transactional) && need_rebalance_delta) {
867884
int ret = bch2_btree_bit_mod_buffered(trans, BTREE_ID_rebalance_work,
868-
new.k->p, mod > 0);
885+
new.k->p, need_rebalance_delta > 0);
869886
if (ret)
870887
return ret;
871888
}
872-
}
873889

874-
if (flags & (BTREE_TRIGGER_transactional|BTREE_TRIGGER_gc))
875-
return trigger_run_overwrite_then_insert(__trigger_extent, trans, btree, level, old, new, flags);
890+
if (need_rebalance_sectors_delta) {
891+
struct disk_accounting_pos acc = {
892+
.type = BCH_DISK_ACCOUNTING_rebalance_work,
893+
};
894+
int ret = bch2_disk_accounting_mod(trans, &acc, &need_rebalance_sectors_delta, 1,
895+
flags & BTREE_TRIGGER_gc);
896+
if (ret)
897+
return ret;
898+
}
899+
}
876900

877901
return 0;
878902
}

fs/bcachefs/extents.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,45 @@ bool bch2_bkey_needs_rebalance(struct bch_fs *c, struct bkey_s_c k)
13791379
return r != NULL;
13801380
}
13811381

1382+
static u64 __bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k,
1383+
unsigned target, unsigned compression)
1384+
{
1385+
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
1386+
const union bch_extent_entry *entry;
1387+
struct extent_ptr_decoded p;
1388+
u64 sectors = 0;
1389+
1390+
if (compression) {
1391+
unsigned compression_type = bch2_compression_opt_to_type(compression);
1392+
1393+
bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
1394+
if (p.crc.compression_type == BCH_COMPRESSION_TYPE_incompressible ||
1395+
p.ptr.unwritten) {
1396+
sectors = 0;
1397+
goto incompressible;
1398+
}
1399+
1400+
if (!p.ptr.cached && p.crc.compression_type != compression_type)
1401+
sectors += p.crc.compressed_size;
1402+
}
1403+
}
1404+
incompressible:
1405+
if (target && bch2_target_accepts_data(c, BCH_DATA_user, target)) {
1406+
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
1407+
if (!p.ptr.cached && !bch2_dev_in_target(c, p.ptr.dev, target))
1408+
sectors += p.crc.compressed_size;
1409+
}
1410+
1411+
return sectors;
1412+
}
1413+
1414+
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *c, struct bkey_s_c k)
1415+
{
1416+
const struct bch_extent_rebalance *r = bch2_bkey_rebalance_opts(k);
1417+
1418+
return r ? __bch2_bkey_sectors_need_rebalance(c, k, r->target, r->compression) : 0;
1419+
}
1420+
13821421
int bch2_bkey_set_needs_rebalance(struct bch_fs *c, struct bkey_i *_k,
13831422
struct bch_io_opts *opts)
13841423
{

fs/bcachefs/extents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ const struct bch_extent_rebalance *bch2_bkey_rebalance_opts(struct bkey_s_c);
692692
unsigned bch2_bkey_ptrs_need_rebalance(struct bch_fs *, struct bkey_s_c,
693693
unsigned, unsigned);
694694
bool bch2_bkey_needs_rebalance(struct bch_fs *, struct bkey_s_c);
695+
u64 bch2_bkey_sectors_need_rebalance(struct bch_fs *, struct bkey_s_c);
695696

696697
int bch2_bkey_set_needs_rebalance(struct bch_fs *, struct bkey_i *,
697698
struct bch_io_opts *);

fs/bcachefs/sb-downgrade.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@
7474
BCH_FSCK_ERR_accounting_key_replicas_devs_unsorted, \
7575
BCH_FSCK_ERR_accounting_key_junk_at_end) \
7676
x(disk_accounting_inum, \
77+
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
78+
BCH_FSCK_ERR_accounting_mismatch) \
79+
x(rebalance_work_acct_fix, \
7780
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
7881
BCH_FSCK_ERR_accounting_mismatch)
7982

@@ -108,7 +111,10 @@
108111
BCH_FSCK_ERR_fs_usage_persistent_reserved_wrong, \
109112
BCH_FSCK_ERR_fs_usage_replicas_wrong, \
110113
BCH_FSCK_ERR_accounting_replicas_not_marked, \
111-
BCH_FSCK_ERR_bkey_version_in_future)
114+
BCH_FSCK_ERR_bkey_version_in_future) \
115+
x(rebalance_work_acct_fix, \
116+
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
117+
BCH_FSCK_ERR_accounting_mismatch)
112118

113119
struct upgrade_downgrade_entry {
114120
u64 recovery_passes;

0 commit comments

Comments
 (0)