summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-08-12 13:49:09 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:43 -0400
commit142cbdff9b3d8e7fe8619d906f9eefd50b078f5f (patch)
treec381e9c66143a79a17415842308894fe459598d7
parent1421bea38ace65f167a73ae3f544205766c1778c (diff)
bcachefs: Change copygc to consider bucket fragmentation
When devices have different sized buckets this is more correct. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/buckets_types.h1
-rw-r--r--fs/bcachefs/movinggc.c20
2 files changed, 12 insertions, 9 deletions
diff --git a/fs/bcachefs/buckets_types.h b/fs/bcachefs/buckets_types.h
index 0f7fcfe29e0e..26779e94a189 100644
--- a/fs/bcachefs/buckets_types.h
+++ b/fs/bcachefs/buckets_types.h
@@ -123,6 +123,7 @@ struct disk_reservation {
struct copygc_heap_entry {
u8 dev;
u8 gen;
+ u16 fragmentation;
u32 sectors;
u64 offset;
};
diff --git a/fs/bcachefs/movinggc.c b/fs/bcachefs/movinggc.c
index 25ae4e195c15..5f96f619bee0 100644
--- a/fs/bcachefs/movinggc.c
+++ b/fs/bcachefs/movinggc.c
@@ -44,13 +44,6 @@
#define COPYGC_BUCKETS_PER_ITER(ca) \
((ca)->free[RESERVE_MOVINGGC].size / 2)
-static inline int sectors_used_cmp(copygc_heap *heap,
- struct copygc_heap_entry l,
- struct copygc_heap_entry r)
-{
- return cmp_int(l.sectors, r.sectors);
-}
-
static int bucket_offset_cmp(const void *_l, const void *_r, size_t size)
{
const struct copygc_heap_entry *l = _l;
@@ -123,6 +116,13 @@ static bool have_copygc_reserve(struct bch_dev *ca)
return ret;
}
+static inline int fragmentation_cmp(copygc_heap *heap,
+ struct copygc_heap_entry l,
+ struct copygc_heap_entry r)
+{
+ return cmp_int(l.fragmentation, r.fragmentation);
+}
+
static int bch2_copygc(struct bch_fs *c)
{
copygc_heap *h = &c->copygc_heap;
@@ -180,10 +180,12 @@ static int bch2_copygc(struct bch_fs *c)
e = (struct copygc_heap_entry) {
.dev = dev_idx,
.gen = m.gen,
+ .fragmentation = bucket_sectors_used(m) * (1U << 15)
+ / ca->mi.bucket_size,
.sectors = bucket_sectors_used(m),
.offset = bucket_to_sector(ca, b),
};
- heap_add_or_replace(h, e, -sectors_used_cmp, NULL);
+ heap_add_or_replace(h, e, -fragmentation_cmp, NULL);
}
up_read(&ca->bucket_lock);
}
@@ -197,7 +199,7 @@ static int bch2_copygc(struct bch_fs *c)
sectors_to_move += i->sectors;
while (sectors_to_move > sectors_reserved) {
- BUG_ON(!heap_pop(h, e, -sectors_used_cmp, NULL));
+ BUG_ON(!heap_pop(h, e, -fragmentation_cmp, NULL));
sectors_to_move -= e.sectors;
}