]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/alloc.h
5b58922344a8e2f60a587cb55cd84a784e3b4571
[bcachefs-tools-debian] / libbcachefs / alloc.h
1 #ifndef _BCACHEFS_ALLOC_H
2 #define _BCACHEFS_ALLOC_H
3
4 #include "bcachefs.h"
5 #include "alloc_types.h"
6
7 struct bkey;
8 struct bch_dev;
9 struct bch_fs;
10 struct bch_devs_List;
11
12 struct dev_alloc_list {
13         unsigned        nr;
14         u8              devs[BCH_SB_MEMBERS_MAX];
15 };
16
17 struct dev_alloc_list bch2_wp_alloc_list(struct bch_fs *,
18                                          struct write_point *,
19                                          struct bch_devs_mask *);
20 void bch2_wp_rescale(struct bch_fs *, struct bch_dev *,
21                      struct write_point *);
22
23 int bch2_alloc_read(struct bch_fs *, struct list_head *);
24 int bch2_alloc_replay_key(struct bch_fs *, struct bpos);
25
26 enum bucket_alloc_ret {
27         ALLOC_SUCCESS           = 0,
28         OPEN_BUCKETS_EMPTY      = -1,
29         FREELIST_EMPTY          = -2,   /* Allocator thread not keeping up */
30         NO_DEVICES              = -3,   /* -EROFS */
31 };
32
33 int bch2_bucket_alloc(struct bch_fs *, struct bch_dev *, enum alloc_reserve, bool,
34                       struct closure *);
35
36 void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
37
38 static inline void bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
39 {
40         if (atomic_dec_and_test(&ob->pin))
41                 __bch2_open_bucket_put(c, ob);
42 }
43
44 static inline void bch2_open_bucket_put_refs(struct bch_fs *c, u8 *nr, u8 *refs)
45 {
46         unsigned i;
47
48         for (i = 0; i < *nr; i++)
49                 bch2_open_bucket_put(c, c->open_buckets + refs[i]);
50
51         *nr = 0;
52 }
53
54 static inline void bch2_open_bucket_get(struct bch_fs *c,
55                                         struct write_point *wp,
56                                         u8 *nr, u8 *refs)
57 {
58         unsigned i;
59
60         for (i = 0; i < wp->nr_ptrs_can_use; i++) {
61                 struct open_bucket *ob = wp->ptrs[i];
62
63                 atomic_inc(&ob->pin);
64                 refs[(*nr)++] = ob - c->open_buckets;
65         }
66 }
67
68 struct write_point *bch2_alloc_sectors_start(struct bch_fs *,
69                                              unsigned,
70                                              struct write_point_specifier,
71                                              struct bch_devs_list *,
72                                              unsigned, unsigned,
73                                              enum alloc_reserve,
74                                              unsigned,
75                                              struct closure *);
76
77 void bch2_alloc_sectors_append_ptrs(struct bch_fs *, struct write_point *,
78                                     struct bkey_i_extent *, unsigned);
79 void bch2_alloc_sectors_done(struct bch_fs *, struct write_point *);
80
81 static inline void bch2_wake_allocator(struct bch_dev *ca)
82 {
83         struct task_struct *p;
84
85         rcu_read_lock();
86         if ((p = READ_ONCE(ca->alloc_thread)))
87                 wake_up_process(p);
88         rcu_read_unlock();
89 }
90
91 #define writepoint_for_each_ptr(_wp, _ob, _i)                           \
92         for ((_i) = 0;                                                  \
93              (_i) < (_wp)->nr_ptrs && ((_ob) = (_wp)->ptrs[_i], true);  \
94              (_i)++)
95
96 static inline struct write_point_specifier writepoint_hashed(unsigned long v)
97 {
98         return (struct write_point_specifier) { .v = v | 1 };
99 }
100
101 static inline struct write_point_specifier writepoint_ptr(struct write_point *wp)
102 {
103         return (struct write_point_specifier) { .v = (unsigned long) wp };
104 }
105
106 void bch2_recalc_capacity(struct bch_fs *);
107
108 void bch2_dev_allocator_remove(struct bch_fs *, struct bch_dev *);
109 void bch2_dev_allocator_add(struct bch_fs *, struct bch_dev *);
110
111 void bch2_dev_allocator_stop(struct bch_dev *);
112 int bch2_dev_allocator_start(struct bch_dev *);
113
114 static inline void writepoint_init(struct write_point *wp,
115                                    enum bch_data_type type)
116 {
117         mutex_init(&wp->lock);
118         wp->type = type;
119 }
120
121 int bch2_alloc_write(struct bch_fs *);
122 int bch2_fs_allocator_start(struct bch_fs *);
123 void bch2_fs_allocator_init(struct bch_fs *);
124
125 extern const struct bkey_ops bch2_bkey_alloc_ops;
126
127 #endif /* _BCACHEFS_ALLOC_H */