summaryrefslogtreecommitdiff
path: root/fs/bcachefs/alloc_background.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-04-01 08:29:59 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:30 +0300
commit822835ffeae411bbc8af104da9331fdf63a7bc12 (patch)
tree57d2b7fd487fc05d58464ea179d435ff4d149bc9 /fs/bcachefs/alloc_background.h
parent8058ea64c31c8700eaab48c38a143d1c3817f1de (diff)
downloadlinux-822835ffeae411bbc8af104da9331fdf63a7bc12.tar.xz
bcachefs: Fold bucket_state in to BCH_DATA_TYPES()
Previously, we were missing accounting for buckets in need_gc_gens and need_discard states. This matters because buckets in those states need other btree operations done before they can be used, so they can't be conuted when checking current number of free buckets against the allocation watermark. Also, we weren't directly counting free buckets at all. Now, data type 0 == BCH_DATA_free, and free buckets are counted; this means we can get rid of the separate (poorly defined) count of unavailable buckets. This is a new on disk format version, with upgrade and fsck required for the accounting changes. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/alloc_background.h')
-rw-r--r--fs/bcachefs/alloc_background.h52
1 files changed, 28 insertions, 24 deletions
diff --git a/fs/bcachefs/alloc_background.h b/fs/bcachefs/alloc_background.h
index 11e0bca3e7f2..2bc622b305c2 100644
--- a/fs/bcachefs/alloc_background.h
+++ b/fs/bcachefs/alloc_background.h
@@ -28,32 +28,35 @@ static inline u8 alloc_gc_gen(struct bch_alloc_v4 a)
return a.gen - a.oldest_gen;
}
-enum bucket_state {
- BUCKET_free,
- BUCKET_need_gc_gens,
- BUCKET_need_discard,
- BUCKET_cached,
- BUCKET_dirty,
-};
-
-extern const char * const bch2_bucket_states[];
-
-static inline enum bucket_state bucket_state(struct bch_alloc_v4 a)
+static inline enum bch_data_type __alloc_data_type(u32 dirty_sectors,
+ u32 cached_sectors,
+ u32 stripe,
+ struct bch_alloc_v4 a,
+ enum bch_data_type data_type)
{
- if (a.dirty_sectors || a.stripe)
- return BUCKET_dirty;
- if (a.cached_sectors)
- return BUCKET_cached;
+ if (dirty_sectors)
+ return data_type;
+ if (stripe)
+ return BCH_DATA_stripe;
+ if (cached_sectors)
+ return BCH_DATA_cached;
if (BCH_ALLOC_V4_NEED_DISCARD(&a))
- return BUCKET_need_discard;
+ return BCH_DATA_need_discard;
if (alloc_gc_gen(a) >= BUCKET_GC_GEN_MAX)
- return BUCKET_need_gc_gens;
- return BUCKET_free;
+ return BCH_DATA_need_gc_gens;
+ return BCH_DATA_free;
+}
+
+static inline enum bch_data_type alloc_data_type(struct bch_alloc_v4 a,
+ enum bch_data_type data_type)
+{
+ return __alloc_data_type(a.dirty_sectors, a.cached_sectors,
+ a.stripe, a, data_type);
}
static inline u64 alloc_lru_idx(struct bch_alloc_v4 a)
{
- return bucket_state(a) == BUCKET_cached ? a.io_time[READ] : 0;
+ return a.data_type == BCH_DATA_cached ? a.io_time[READ] : 0;
}
static inline u64 alloc_freespace_genbits(struct bch_alloc_v4 a)
@@ -128,13 +131,14 @@ int bch2_check_alloc_info(struct bch_fs *);
int bch2_check_alloc_to_lru_refs(struct bch_fs *);
void bch2_do_discards(struct bch_fs *);
-static inline bool should_invalidate_buckets(struct bch_dev *ca)
+static inline u64 should_invalidate_buckets(struct bch_dev *ca,
+ struct bch_dev_usage u)
{
- struct bch_dev_usage u = bch2_dev_usage_read(ca);
+ u64 free = u.d[BCH_DATA_free].buckets +
+ u.d[BCH_DATA_need_discard].buckets;
- return u.d[BCH_DATA_cached].buckets &&
- u.buckets_unavailable + u.d[BCH_DATA_cached].buckets <
- ca->mi.nbuckets >> 7;
+ return clamp_t(s64, (ca->mi.nbuckets >> 7) - free,
+ 0, u.d[BCH_DATA_cached].buckets);
}
void bch2_do_invalidates(struct bch_fs *);