diff options
Diffstat (limited to 'libbcachefs/buckets.h')
-rw-r--r-- | libbcachefs/buckets.h | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/libbcachefs/buckets.h b/libbcachefs/buckets.h index 141aa4ad..7d2b08cb 100644 --- a/libbcachefs/buckets.h +++ b/libbcachefs/buckets.h @@ -95,37 +95,39 @@ static inline bool bucket_unused(struct bucket_mark mark) /* Per device stats: */ struct bch_dev_usage __bch2_dev_usage_read(struct bch_dev *); -struct bch_dev_usage bch2_dev_usage_read(struct bch_dev *); +struct bch_dev_usage bch2_dev_usage_read(struct bch_fs *, struct bch_dev *); static inline u64 __dev_buckets_available(struct bch_dev *ca, struct bch_dev_usage stats) { - return max_t(s64, 0, - ca->mi.nbuckets - ca->mi.first_bucket - - stats.buckets[S_META] - - stats.buckets[S_DIRTY] - - stats.buckets_alloc); + u64 total = ca->mi.nbuckets - ca->mi.first_bucket; + + if (WARN_ONCE(stats.buckets_unavailable > total, + "buckets_unavailable overflow\n")) + return 0; + + return total - stats.buckets_unavailable; } /* * Number of reclaimable buckets - only for use by the allocator thread: */ -static inline u64 dev_buckets_available(struct bch_dev *ca) +static inline u64 dev_buckets_available(struct bch_fs *c, struct bch_dev *ca) { - return __dev_buckets_available(ca, bch2_dev_usage_read(ca)); + return __dev_buckets_available(ca, bch2_dev_usage_read(c, ca)); } static inline u64 __dev_buckets_free(struct bch_dev *ca, - struct bch_dev_usage stats) + struct bch_dev_usage stats) { return __dev_buckets_available(ca, stats) + fifo_used(&ca->free[RESERVE_NONE]) + fifo_used(&ca->free_inc); } -static inline u64 dev_buckets_free(struct bch_dev *ca) +static inline u64 dev_buckets_free(struct bch_fs *c, struct bch_dev *ca) { - return __dev_buckets_free(ca, bch2_dev_usage_read(ca)); + return __dev_buckets_free(ca, bch2_dev_usage_read(c, ca)); } /* Cache set stats: */ @@ -133,7 +135,7 @@ static inline u64 dev_buckets_free(struct bch_dev *ca) struct bch_fs_usage __bch2_fs_usage_read(struct bch_fs *); struct bch_fs_usage bch2_fs_usage_read(struct bch_fs *); void bch2_fs_usage_apply(struct bch_fs *, struct bch_fs_usage *, - struct disk_reservation *, struct gc_pos); + struct disk_reservation *, struct gc_pos); struct fs_usage_sum { u64 data; @@ -155,11 +157,18 @@ static inline struct fs_usage_sum __fs_usage_sum(struct bch_fs_usage stats) return sum; } +#define RESERVE_FACTOR 6 + +static u64 reserve_factor(u64 r) +{ + return r + (round_up(r, (1 << RESERVE_FACTOR)) >> RESERVE_FACTOR); +} + static inline u64 __bch2_fs_sectors_used(struct bch_fs *c) { struct fs_usage_sum sum = __fs_usage_sum(__bch2_fs_usage_read(c)); - return sum.data + sum.reserved + (sum.reserved >> 7); + return sum.data + reserve_factor(sum.reserved); } static inline u64 bch2_fs_sectors_used(struct bch_fs *c) @@ -184,30 +193,35 @@ static inline bool bucket_needs_journal_commit(struct bucket_mark m, void bch2_bucket_seq_cleanup(struct bch_fs *); -bool bch2_invalidate_bucket(struct bch_dev *, struct bucket *, - struct bucket_mark *); -bool bch2_mark_alloc_bucket_startup(struct bch_dev *, struct bucket *); -void bch2_mark_free_bucket(struct bch_dev *, struct bucket *); -void bch2_mark_alloc_bucket(struct bch_dev *, struct bucket *, bool); -void bch2_mark_metadata_bucket(struct bch_dev *, struct bucket *, - enum bucket_data_type, bool); +bool bch2_invalidate_bucket(struct bch_fs *, struct bch_dev *, + struct bucket *, struct bucket_mark *); +bool bch2_mark_alloc_bucket_startup(struct bch_fs *, struct bch_dev *, + struct bucket *); +void bch2_mark_alloc_bucket(struct bch_fs *, struct bch_dev *, + struct bucket *, bool, + struct gc_pos, unsigned); +void bch2_mark_metadata_bucket(struct bch_fs *, struct bch_dev *, + struct bucket *, enum bucket_data_type, + struct gc_pos, unsigned); #define BCH_BUCKET_MARK_NOATOMIC (1 << 0) -#define BCH_BUCKET_MARK_GC_WILL_VISIT (1 << 1) -#define BCH_BUCKET_MARK_MAY_MAKE_UNAVAILABLE (1 << 2) - -void __bch2_mark_key(struct bch_fs *, struct bkey_s_c, s64, bool, - struct bch_fs_usage *, u64, unsigned); +#define BCH_BUCKET_MARK_MAY_MAKE_UNAVAILABLE (1 << 1) +#define BCH_BUCKET_MARK_GC_WILL_VISIT (1 << 2) +#define BCH_BUCKET_MARK_GC_LOCK_HELD (1 << 3) -void bch2_gc_mark_key(struct bch_fs *, struct bkey_s_c, - s64, bool, unsigned); -void bch2_mark_key(struct bch_fs *, struct bkey_s_c, s64, bool, - struct gc_pos, struct bch_fs_usage *, u64); +void bch2_mark_key(struct bch_fs *, struct bkey_s_c, s64, bool, struct gc_pos, + struct bch_fs_usage *, u64, unsigned); void bch2_recalc_sectors_available(struct bch_fs *); -void bch2_disk_reservation_put(struct bch_fs *, - struct disk_reservation *); +void __bch2_disk_reservation_put(struct bch_fs *, struct disk_reservation *); + +static inline void bch2_disk_reservation_put(struct bch_fs *c, + struct disk_reservation *res) +{ + if (res->sectors) + __bch2_disk_reservation_put(c, res); +} #define BCH_DISK_RESERVATION_NOFAIL (1 << 0) #define BCH_DISK_RESERVATION_METADATA (1 << 1) |