Skip to content

Commit 50a7b89

Browse files
author
Kent Overstreet
committed
bcachefs: Ensure proper write alignment
There was a buggy version of bcachefs-tools which picked misaligned bucket sizes when formatting, and we're also about to do dynamic block sizes - which will allow picking logical block size or physical block size of the device per-write, allowing for better compression ratios at the cost of slightly worse write performance (i.e. forcing the device to do RMW or extra buffering). To account for this, tweak bch2_alloc_sectors_start() to properly align open_buckets to the blocksize of the write we're about to do. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 844f766 commit 50a7b89

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

fs/bcachefs/alloc_foreground.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1422,11 +1422,31 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
14221422

14231423
wp->sectors_free = UINT_MAX;
14241424

1425-
open_bucket_for_each(c, &wp->ptrs, ob, i)
1425+
open_bucket_for_each(c, &wp->ptrs, ob, i) {
1426+
/*
1427+
* Ensure proper write alignment - either due to misaligned
1428+
* bucket sizes (from buggy bcachefs-tools), or writes that mix
1429+
* logical/physical alignment:
1430+
*/
1431+
struct bch_dev *ca = ob_dev(c, ob);
1432+
u64 offset = bucket_to_sector(ca, ob->bucket) +
1433+
ca->mi.bucket_size -
1434+
ob->sectors_free;
1435+
unsigned align = round_up(offset, block_sectors(c)) - offset;
1436+
1437+
ob->sectors_free = max_t(int, 0, ob->sectors_free - align);
1438+
14261439
wp->sectors_free = min(wp->sectors_free, ob->sectors_free);
1440+
}
14271441

14281442
wp->sectors_free = rounddown(wp->sectors_free, block_sectors(c));
14291443

1444+
/* Did alignment use up space in an open_bucket? */
1445+
if (unlikely(!wp->sectors_free)) {
1446+
bch2_alloc_sectors_done(c, wp);
1447+
goto retry;
1448+
}
1449+
14301450
BUG_ON(!wp->sectors_free || wp->sectors_free == UINT_MAX);
14311451

14321452
return 0;

0 commit comments

Comments
 (0)