summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/alloc_types.h
blob: 9e00afb175592294c2ff88d5d3f5d01e4cce3f7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCACHEFS_ALLOC_TYPES_H
#define _BCACHEFS_ALLOC_TYPES_H

#include <linux/mutex.h>
#include <linux/spinlock.h>

#include "clock_types.h"
#include "fifo.h"

struct ec_bucket_buf;

#define ALLOC_THREAD_STATES()		\
	x(stopped)			\
	x(running)			\
	x(blocked)			\
	x(blocked_full)

enum allocator_states {
#define x(n)	ALLOCATOR_##n,
	ALLOC_THREAD_STATES()
#undef x
};

#define BCH_ALLOC_RESERVES()		\
	x(btree_movinggc)		\
	x(btree)			\
	x(movinggc)			\
	x(none)

enum alloc_reserve {
#define x(name)	RESERVE_##name,
	BCH_ALLOC_RESERVES()
#undef x
	RESERVE_NR
};

typedef FIFO(long)	alloc_fifo;

#define OPEN_BUCKETS_COUNT	1024

#define WRITE_POINT_HASH_NR	32
#define WRITE_POINT_MAX		32

/*
 * 0 is never a valid open_bucket_idx_t:
 */
typedef u16			open_bucket_idx_t;

struct open_bucket {
	spinlock_t		lock;
	atomic_t		pin;
	open_bucket_idx_t	freelist;
	open_bucket_idx_t	hash;

	/*
	 * When an open bucket has an ec_stripe attached, this is the index of
	 * the block in the stripe this open_bucket corresponds to:
	 */
	u8			ec_idx;
	enum bch_data_type	data_type:3;
	unsigned		valid:1;
	unsigned		on_partial_list:1;
	int			alloc_reserve:3;

	unsigned		sectors_free;
	u8			dev;
	u8			gen;
	u64			bucket;
	struct ec_stripe_new	*ec;
};

#define OPEN_BUCKET_LIST_MAX	15

struct open_buckets {
	open_bucket_idx_t	nr;
	open_bucket_idx_t	v[OPEN_BUCKET_LIST_MAX];
};

struct dev_stripe_state {
	u64			next_alloc[BCH_SB_MEMBERS_MAX];
};

#define WRITE_POINT_STATES()		\
	x(stopped)			\
	x(waiting_io)			\
	x(waiting_work)			\
	x(running)

enum write_point_state {
#define x(n)	WRITE_POINT_##n,
	WRITE_POINT_STATES()
#undef x
	WRITE_POINT_STATE_NR
};

struct write_point {
	struct {
		struct hlist_node	node;
		struct mutex		lock;
		u64			last_used;
		unsigned long		write_point;
		enum bch_data_type	data_type;

		/* calculated based on how many pointers we're actually going to use: */
		unsigned		sectors_free;

		struct open_buckets	ptrs;
		struct dev_stripe_state	stripe;

		u64			sectors_allocated;
	} __attribute__((__aligned__(SMP_CACHE_BYTES)));

	struct {
		struct work_struct	index_update_work;

		struct list_head	writes;
		spinlock_t		writes_lock;

		enum write_point_state	state;
		u64			last_state_change;
		u64			time[WRITE_POINT_STATE_NR];
	} __attribute__((__aligned__(SMP_CACHE_BYTES)));
};

struct write_point_specifier {
	unsigned long		v;
};

struct alloc_heap_entry {
	size_t			bucket;
	size_t			nr;
	unsigned long		key;
};

typedef HEAP(struct alloc_heap_entry) alloc_heap;

#endif /* _BCACHEFS_ALLOC_TYPES_H */