1#ifndef __LINUX_BACKING_DEV_DEFS_H
2#define __LINUX_BACKING_DEV_DEFS_H
3
4#include <linux/list.h>
5#include <linux/radix-tree.h>
6#include <linux/rbtree.h>
7#include <linux/spinlock.h>
8#include <linux/percpu_counter.h>
9#include <linux/percpu-refcount.h>
10#include <linux/flex_proportions.h>
11#include <linux/timer.h>
12#include <linux/workqueue.h>
13
14struct page;
15struct device;
16struct dentry;
17
18
19
20
21enum wb_state {
22 WB_registered,
23 WB_writeback_running,
24 WB_has_dirty_io,
25};
26
27enum wb_congested_state {
28 WB_async_congested,
29 WB_sync_congested,
30};
31
32typedef int (congested_fn)(void *, int);
33
34enum wb_stat_item {
35 WB_RECLAIMABLE,
36 WB_WRITEBACK,
37 WB_DIRTIED,
38 WB_WRITTEN,
39 NR_WB_STAT_ITEMS
40};
41
42#define WB_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
43
44
45
46
47
48
49
50
51struct bdi_writeback_congested {
52 unsigned long state;
53 atomic_t refcnt;
54
55#ifdef CONFIG_CGROUP_WRITEBACK
56 struct backing_dev_info *bdi;
57 int blkcg_id;
58 struct rb_node rb_node;
59#endif
60};
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81struct bdi_writeback {
82 struct backing_dev_info *bdi;
83
84 unsigned long state;
85 unsigned long last_old_flush;
86
87 struct list_head b_dirty;
88 struct list_head b_io;
89 struct list_head b_more_io;
90 struct list_head b_dirty_time;
91 spinlock_t list_lock;
92
93 struct percpu_counter stat[NR_WB_STAT_ITEMS];
94
95 struct bdi_writeback_congested *congested;
96
97 unsigned long bw_time_stamp;
98 unsigned long dirtied_stamp;
99 unsigned long written_stamp;
100 unsigned long write_bandwidth;
101 unsigned long avg_write_bandwidth;
102
103
104
105
106
107
108
109 unsigned long dirty_ratelimit;
110 unsigned long balanced_dirty_ratelimit;
111
112 struct fprop_local_percpu completions;
113 int dirty_exceeded;
114
115 spinlock_t work_lock;
116 struct list_head work_list;
117 struct delayed_work dwork;
118
119 struct list_head bdi_node;
120
121#ifdef CONFIG_CGROUP_WRITEBACK
122 struct percpu_ref refcnt;
123 struct fprop_local_percpu memcg_completions;
124 struct cgroup_subsys_state *memcg_css;
125 struct cgroup_subsys_state *blkcg_css;
126 struct list_head memcg_node;
127 struct list_head blkcg_node;
128
129 union {
130 struct work_struct release_work;
131 struct rcu_head rcu;
132 };
133#endif
134};
135
136struct backing_dev_info {
137 struct list_head bdi_list;
138 unsigned long ra_pages;
139 unsigned int capabilities;
140 congested_fn *congested_fn;
141 void *congested_data;
142
143 char *name;
144
145 unsigned int min_ratio;
146 unsigned int max_ratio, max_prop_frac;
147
148
149
150
151
152 atomic_long_t tot_write_bandwidth;
153
154 struct bdi_writeback wb;
155 struct list_head wb_list;
156#ifdef CONFIG_CGROUP_WRITEBACK
157 struct radix_tree_root cgwb_tree;
158 struct rb_root cgwb_congested_tree;
159 atomic_t usage_cnt;
160#else
161 struct bdi_writeback_congested *wb_congested;
162#endif
163 wait_queue_head_t wb_waitq;
164
165 struct device *dev;
166 struct device *owner;
167
168 struct timer_list laptop_mode_wb_timer;
169
170#ifdef CONFIG_DEBUG_FS
171 struct dentry *debug_dir;
172 struct dentry *debug_stats;
173#endif
174};
175
176enum {
177 BLK_RW_ASYNC = 0,
178 BLK_RW_SYNC = 1,
179};
180
181void clear_wb_congested(struct bdi_writeback_congested *congested, int sync);
182void set_wb_congested(struct bdi_writeback_congested *congested, int sync);
183
184static inline void clear_bdi_congested(struct backing_dev_info *bdi, int sync)
185{
186 clear_wb_congested(bdi->wb.congested, sync);
187}
188
189static inline void set_bdi_congested(struct backing_dev_info *bdi, int sync)
190{
191 set_wb_congested(bdi->wb.congested, sync);
192}
193
194#ifdef CONFIG_CGROUP_WRITEBACK
195
196
197
198
199
200static inline bool wb_tryget(struct bdi_writeback *wb)
201{
202 if (wb != &wb->bdi->wb)
203 return percpu_ref_tryget(&wb->refcnt);
204 return true;
205}
206
207
208
209
210
211static inline void wb_get(struct bdi_writeback *wb)
212{
213 if (wb != &wb->bdi->wb)
214 percpu_ref_get(&wb->refcnt);
215}
216
217
218
219
220
221static inline void wb_put(struct bdi_writeback *wb)
222{
223 if (wb != &wb->bdi->wb)
224 percpu_ref_put(&wb->refcnt);
225}
226
227
228
229
230
231
232
233static inline bool wb_dying(struct bdi_writeback *wb)
234{
235 return percpu_ref_is_dying(&wb->refcnt);
236}
237
238#else
239
240static inline bool wb_tryget(struct bdi_writeback *wb)
241{
242 return true;
243}
244
245static inline void wb_get(struct bdi_writeback *wb)
246{
247}
248
249static inline void wb_put(struct bdi_writeback *wb)
250{
251}
252
253static inline bool wb_dying(struct bdi_writeback *wb)
254{
255 return false;
256}
257
258#endif
259
260#endif
261