]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/alloc_types.h
20705460bb0aa10ef24dc1910716ea78493e7074
[bcachefs-tools-debian] / libbcachefs / alloc_types.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_ALLOC_TYPES_H
3 #define _BCACHEFS_ALLOC_TYPES_H
4
5 #include <linux/mutex.h>
6 #include <linux/spinlock.h>
7
8 #include "clock_types.h"
9 #include "fifo.h"
10
11 struct ec_bucket_buf;
12
13 /* There's two of these clocks, one for reads and one for writes: */
14 struct bucket_clock {
15         /*
16          * "now" in (read/write) IO time - incremented whenever we do X amount
17          * of reads or writes.
18          *
19          * Goes with the bucket read/write prios: when we read or write to a
20          * bucket we reset the bucket's prio to the current hand; thus hand -
21          * prio = time since bucket was last read/written.
22          *
23          * The units are some amount (bytes/sectors) of data read/written, and
24          * the units can change on the fly if we need to rescale to fit
25          * everything in a u16 - your only guarantee is that the units are
26          * consistent.
27          */
28         u16                     hand;
29         u16                     max_last_io;
30
31         int                     rw;
32
33         struct io_timer         rescale;
34         struct mutex            lock;
35 };
36
37 /* There is one reserve for each type of btree, one for prios and gens
38  * and one for moving GC */
39 enum alloc_reserve {
40         RESERVE_ALLOC           = -1,
41         RESERVE_BTREE           = 0,
42         RESERVE_MOVINGGC        = 1,
43         RESERVE_NONE            = 2,
44         RESERVE_NR              = 3,
45 };
46
47 typedef FIFO(long)      alloc_fifo;
48
49 #define OPEN_BUCKETS_COUNT      1024
50
51 #define WRITE_POINT_HASH_NR     32
52 #define WRITE_POINT_MAX         32
53
54 typedef u16                     open_bucket_idx_t;
55
56 struct open_bucket {
57         spinlock_t              lock;
58         atomic_t                pin;
59         open_bucket_idx_t       freelist;
60
61         /*
62          * When an open bucket has an ec_stripe attached, this is the index of
63          * the block in the stripe this open_bucket corresponds to:
64          */
65         u8                      ec_idx;
66         u8                      type;
67         unsigned                valid:1;
68         unsigned                on_partial_list:1;
69         int                     alloc_reserve:3;
70         unsigned                sectors_free;
71         struct bch_extent_ptr   ptr;
72         struct ec_stripe_new    *ec;
73 };
74
75 #define OPEN_BUCKET_LIST_MAX    15
76
77 struct open_buckets {
78         open_bucket_idx_t       nr;
79         open_bucket_idx_t       v[OPEN_BUCKET_LIST_MAX];
80 };
81
82 struct dev_stripe_state {
83         u64                     next_alloc[BCH_SB_MEMBERS_MAX];
84 };
85
86 struct write_point {
87         struct hlist_node       node;
88         struct mutex            lock;
89         u64                     last_used;
90         unsigned long           write_point;
91         enum bch_data_type      type;
92         bool                    is_ec;
93
94         /* calculated based on how many pointers we're actually going to use: */
95         unsigned                sectors_free;
96
97         struct open_buckets     ptrs;
98         struct dev_stripe_state stripe;
99 };
100
101 struct write_point_specifier {
102         unsigned long           v;
103 };
104
105 struct alloc_heap_entry {
106         size_t                  bucket;
107         size_t                  nr;
108         unsigned long           key;
109 };
110
111 typedef HEAP(struct alloc_heap_entry) alloc_heap;
112
113 #endif /* _BCACHEFS_ALLOC_TYPES_H */