]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/alloc_background.h
Update bcachefs sources to bdf6d7c135 fixup! bcachefs: Kill journal buf bloom filter
[bcachefs-tools-debian] / libbcachefs / alloc_background.h
index 06539e036f13cacf127b6af17e3ebd86b3b01d1a..ff366e61ace51ea4af61b916c88ca88f24d05a1e 100644 (file)
 #include "debug.h"
 #include "super.h"
 
-struct bkey_alloc_unpacked {
-       u64             journal_seq;
-       u64             bucket;
-       u8              dev;
-       u8              gen;
-       u8              oldest_gen;
-       u8              data_type;
-       bool            need_discard:1;
-       bool            need_inc_gen:1;
-#define x(_name, _bits)        u##_bits _name;
-       BCH_ALLOC_FIELDS_V2()
-#undef  x
-};
-
 /* How out of date a pointer gen is allowed to be: */
 #define BUCKET_GC_GEN_MAX      96U
 
-static inline u8 alloc_gc_gen(struct bkey_alloc_unpacked a)
+static inline bool bch2_dev_bucket_exists(struct bch_fs *c, struct bpos pos)
 {
-       return a.gen - a.oldest_gen;
-}
+       struct bch_dev *ca;
 
-enum bucket_state {
-       BUCKET_free,
-       BUCKET_need_gc_gens,
-       BUCKET_need_discard,
-       BUCKET_cached,
-       BUCKET_dirty,
-};
+       if (!bch2_dev_exists2(c, pos.inode))
+               return false;
 
-extern const char * const bch2_bucket_states[];
+       ca = bch_dev_bkey_exists(c, pos.inode);
+       return pos.offset >= ca->mi.first_bucket &&
+               pos.offset < ca->mi.nbuckets;
+}
 
-static inline enum bucket_state bucket_state(struct bkey_alloc_unpacked a)
+static inline u8 alloc_gc_gen(struct bch_alloc_v4 a)
 {
-       if (a.dirty_sectors || a.stripe)
-               return BUCKET_dirty;
-       if (a.cached_sectors)
-               return BUCKET_cached;
-       BUG_ON(a.data_type);
-       if (a.need_discard)
-               return BUCKET_need_discard;
-       if (alloc_gc_gen(a) >= BUCKET_GC_GEN_MAX)
-               return BUCKET_need_gc_gens;
-       return BUCKET_free;
+       return a.gen - a.oldest_gen;
 }
 
-static inline u64 alloc_lru_idx(struct bkey_alloc_unpacked 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)
 {
-       return bucket_state(a) == BUCKET_cached ? a.read_time : 0;
+       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 BCH_DATA_need_discard;
+       if (alloc_gc_gen(a) >= BUCKET_GC_GEN_MAX)
+               return BCH_DATA_need_gc_gens;
+       return BCH_DATA_free;
 }
 
-static inline u64 alloc_freespace_genbits(struct bkey_alloc_unpacked a)
+static inline enum bch_data_type alloc_data_type(struct bch_alloc_v4 a,
+                                                enum bch_data_type data_type)
 {
-       return ((u64) alloc_gc_gen(a) >> 4) << 56;
+       return __alloc_data_type(a.dirty_sectors, a.cached_sectors,
+                                a.stripe, a, data_type);
 }
 
-static inline struct bpos alloc_freespace_pos(struct bkey_alloc_unpacked a)
+static inline u64 alloc_lru_idx(struct bch_alloc_v4 a)
 {
-       return POS(a.dev, a.bucket | alloc_freespace_genbits(a));
+       return a.data_type == BCH_DATA_cached ? a.io_time[READ] : 0;
 }
 
-/* returns true if not equal */
-static inline bool bkey_alloc_unpacked_cmp(struct bkey_alloc_unpacked l,
-                                          struct bkey_alloc_unpacked r)
+static inline u64 alloc_freespace_genbits(struct bch_alloc_v4 a)
 {
-       return  l.gen != r.gen                  ||
-               l.oldest_gen != r.oldest_gen    ||
-               l.data_type != r.data_type
-#define x(_name, ...)  || l._name != r._name
-       BCH_ALLOC_FIELDS_V2()
-#undef  x
-       ;
+       return ((u64) alloc_gc_gen(a) >> 4) << 56;
 }
 
-struct bkey_alloc_buf {
-       struct bkey_i   k;
-       struct bch_alloc_v3 v;
+static inline struct bpos alloc_freespace_pos(struct bpos pos, struct bch_alloc_v4 a)
+{
+       pos.offset |= alloc_freespace_genbits(a);
+       return pos;
+}
 
-#define x(_name,  _bits)               + _bits / 8
-       u8              _pad[0 + BCH_ALLOC_FIELDS_V2()];
-#undef  x
-} __attribute__((packed, aligned(8)));
+struct bkey_i_alloc_v4 *
+bch2_trans_start_alloc_update(struct btree_trans *, struct btree_iter *, struct bpos);
 
-struct bkey_alloc_unpacked bch2_alloc_unpack(struct bkey_s_c);
-struct bkey_alloc_buf *bch2_alloc_pack(struct btree_trans *,
-                                      const struct bkey_alloc_unpacked);
-int bch2_alloc_write(struct btree_trans *, struct btree_iter *,
-                    struct bkey_alloc_unpacked *, unsigned);
+void bch2_alloc_to_v4(struct bkey_s_c, struct bch_alloc_v4 *);
+struct bkey_i_alloc_v4 *bch2_alloc_to_v4_mut(struct btree_trans *, struct bkey_s_c);
 
 int bch2_bucket_io_time_reset(struct btree_trans *, unsigned, size_t, int);
 
 #define ALLOC_SCAN_BATCH(ca)           max_t(size_t, 1, (ca)->mi.nbuckets >> 9)
 
-const char *bch2_alloc_v1_invalid(const struct bch_fs *, struct bkey_s_c);
-const char *bch2_alloc_v2_invalid(const struct bch_fs *, struct bkey_s_c);
-const char *bch2_alloc_v3_invalid(const struct bch_fs *, struct bkey_s_c);
+int bch2_alloc_v1_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v2_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v3_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+int bch2_alloc_v4_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
+void bch2_alloc_v4_swab(struct bkey_s);
 void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
 
 #define bch2_bkey_ops_alloc (struct bkey_ops) {                \
@@ -127,6 +108,14 @@ void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
        .atomic_trigger = bch2_mark_alloc,              \
 }
 
+#define bch2_bkey_ops_alloc_v4 (struct bkey_ops) {     \
+       .key_invalid    = bch2_alloc_v4_invalid,        \
+       .val_to_text    = bch2_alloc_to_text,           \
+       .swab           = bch2_alloc_v4_swab,           \
+       .trans_trigger  = bch2_trans_mark_alloc,        \
+       .atomic_trigger = bch2_mark_alloc,              \
+}
+
 static inline bool bkey_is_alloc(const struct bkey *k)
 {
        return  k->type == KEY_TYPE_alloc ||
@@ -136,18 +125,20 @@ static inline bool bkey_is_alloc(const struct bkey *k)
 
 int bch2_alloc_read(struct bch_fs *);
 
-int bch2_trans_mark_alloc(struct btree_trans *, struct bkey_s_c,
-                         struct bkey_i *, unsigned);
-int bch2_check_alloc_info(struct bch_fs *, bool);
+int bch2_trans_mark_alloc(struct btree_trans *, enum btree_id, unsigned,
+                         struct bkey_s_c, struct bkey_i *, unsigned);
+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 *);