summaryrefslogtreecommitdiff
path: root/libbcachefs/alloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/alloc.h')
-rw-r--r--libbcachefs/alloc.h87
1 files changed, 66 insertions, 21 deletions
diff --git a/libbcachefs/alloc.h b/libbcachefs/alloc.h
index 1ea747d2..8dffb864 100644
--- a/libbcachefs/alloc.h
+++ b/libbcachefs/alloc.h
@@ -8,7 +8,7 @@ struct bkey;
struct bucket;
struct bch_dev;
struct bch_fs;
-struct dev_group;
+struct bch_devs_List;
struct dev_alloc_list {
unsigned nr;
@@ -24,33 +24,61 @@ void bch2_wp_rescale(struct bch_fs *, struct bch_dev *,
int bch2_alloc_read(struct bch_fs *, struct list_head *);
int bch2_alloc_replay_key(struct bch_fs *, struct bpos);
-long bch2_bucket_alloc(struct bch_fs *, struct bch_dev *, enum alloc_reserve);
+enum bucket_alloc_ret {
+ ALLOC_SUCCESS = 0,
+ OPEN_BUCKETS_EMPTY = -1,
+ FREELIST_EMPTY = -2, /* Allocator thread not keeping up */
+ NO_DEVICES = -3, /* -EROFS */
+};
+
+int bch2_bucket_alloc(struct bch_fs *, struct bch_dev *, enum alloc_reserve, bool,
+ struct closure *);
+
+void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
+
+static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
+{
+ if (atomic_dec_and_test(&ob->pin))
+ __bch2_open_bucket_put(c, ob);
+}
+
+static inline void bch2_open_bucket_put_refs(struct bch_fs *c, u8 *nr, u8 *refs)
+{
+ unsigned i;
+
+ for (i = 0; i < *nr; i++)
+ bch2_open_bucket_put(c, c->open_buckets + refs[i]);
+
+ *nr = 0;
+}
+
+static inline void bch2_open_bucket_get(struct bch_fs *c,
+ struct write_point *wp,
+ u8 *nr, u8 *refs)
+{
+ unsigned i;
-void bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
+ for (i = 0; i < wp->nr_ptrs_can_use; i++) {
+ struct open_bucket *ob = wp->ptrs[i];
+
+ atomic_inc(&ob->pin);
+ refs[(*nr)++] = ob - c->open_buckets;
+ }
+}
struct write_point *bch2_alloc_sectors_start(struct bch_fs *,
- enum bch_data_type,
struct bch_devs_mask *,
- unsigned long,
+ struct write_point_specifier,
+ struct bch_devs_list *,
unsigned, unsigned,
enum alloc_reserve,
unsigned,
struct closure *);
-void bch2_alloc_sectors_append_ptrs(struct bch_fs *, struct bkey_i_extent *,
- unsigned, struct open_bucket *, unsigned);
+void bch2_alloc_sectors_append_ptrs(struct bch_fs *, struct write_point *,
+ struct bkey_i_extent *, unsigned);
void bch2_alloc_sectors_done(struct bch_fs *, struct write_point *);
-struct open_bucket *bch2_alloc_sectors(struct bch_fs *,
- enum bch_data_type,
- struct bch_devs_mask *,
- unsigned long,
- struct bkey_i_extent *,
- unsigned, unsigned,
- enum alloc_reserve,
- unsigned,
- struct closure *);
-
static inline void bch2_wake_allocator(struct bch_dev *ca)
{
struct task_struct *p;
@@ -61,10 +89,20 @@ static inline void bch2_wake_allocator(struct bch_dev *ca)
rcu_read_unlock();
}
-#define open_bucket_for_each_ptr(_ob, _ptr) \
- for ((_ptr) = (_ob)->ptrs; \
- (_ptr) < (_ob)->ptrs + (_ob)->nr_ptrs; \
- (_ptr)++)
+#define writepoint_for_each_ptr(_wp, _ob, _i) \
+ for ((_i) = 0; \
+ (_i) < (_wp)->nr_ptrs && ((_ob) = (_wp)->ptrs[_i], true); \
+ (_i)++)
+
+static inline struct write_point_specifier writepoint_hashed(unsigned long v)
+{
+ return (struct write_point_specifier) { .v = v | 1 };
+}
+
+static inline struct write_point_specifier writepoint_ptr(struct write_point *wp)
+{
+ return (struct write_point_specifier) { .v = (unsigned long) wp };
+}
void bch2_recalc_capacity(struct bch_fs *);
@@ -74,6 +112,13 @@ void bch2_dev_allocator_add(struct bch_fs *, struct bch_dev *);
void bch2_dev_allocator_stop(struct bch_dev *);
int bch2_dev_allocator_start(struct bch_dev *);
+static inline void writepoint_init(struct write_point *wp,
+ enum bch_data_type type)
+{
+ mutex_init(&wp->lock);
+ wp->type = type;
+}
+
void bch2_fs_allocator_init(struct bch_fs *);
extern const struct bkey_ops bch2_bkey_alloc_ops;