Skip to content

Commit e0fb0dc

Browse files
Brian FosterKent Overstreet
authored andcommitted
bcachefs: update alloc cursor in early bucket allocator
A recent bug report uncovered a scenario where a filesystem never runs with freespace_initialized, and therefore the user observes significantly degraded write performance by virtue of running the early bucket allocator. The associated bug aside, the primary cause of the performance drop in this particular instance is that the early bucket allocator does not update the allocation cursor. This means that every allocation walks the alloc btree from the first bucket of the associated device looking for a bucket marked as free space. Update the early allocator code to set the alloc cursor to the last processed position in the tree, similar to how the freelist allocator behaves. With the alloc_cursor being updated, the retry logic also needs to be updated to restart from the beginning of the device when a free bucket is not available between the cursor and the end of the device. Track the restart position in a first_bucket variable to make the code a bit more easily readable and consistent with the freelist allocator. Signed-off-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 385a82f commit e0fb0dc

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

fs/bcachefs/alloc_foreground.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,9 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
402402
struct btree_iter iter, citer;
403403
struct bkey_s_c k, ck;
404404
struct open_bucket *ob = NULL;
405-
u64 alloc_start = max_t(u64, ca->mi.first_bucket, ca->new_fs_bucket_idx);
406-
u64 alloc_cursor = max(alloc_start, READ_ONCE(ca->alloc_cursor));
405+
u64 first_bucket = max_t(u64, ca->mi.first_bucket, ca->new_fs_bucket_idx);
406+
u64 alloc_start = max(first_bucket, READ_ONCE(ca->alloc_cursor));
407+
u64 alloc_cursor = alloc_start;
407408
int ret;
408409

409410
/*
@@ -453,13 +454,14 @@ bch2_bucket_alloc_early(struct btree_trans *trans,
453454
}
454455
bch2_trans_iter_exit(trans, &iter);
455456

457+
alloc_cursor = iter.pos.offset;
456458
ca->alloc_cursor = alloc_cursor;
457459

458460
if (!ob && ret)
459461
ob = ERR_PTR(ret);
460462

461-
if (!ob && alloc_cursor > alloc_start) {
462-
alloc_cursor = alloc_start;
463+
if (!ob && alloc_start > first_bucket) {
464+
alloc_cursor = alloc_start = first_bucket;
463465
goto again;
464466
}
465467

0 commit comments

Comments
 (0)