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