1
2
3
4
5
6
7
8#ifndef _LINUX_BACKING_DEV_H
9#define _LINUX_BACKING_DEV_H
10
11#include <linux/percpu_counter.h>
12#include <linux/log2.h>
13#include <linux/flex_proportions.h>
14#include <linux/kernel.h>
15#include <linux/fs.h>
16#include <linux/sched.h>
17#include <linux/timer.h>
18#include <linux/writeback.h>
19#include <linux/atomic.h>
20#include <linux/sysctl.h>
21#include <linux/workqueue.h>
22
23struct page;
24struct device;
25struct dentry;
26
27
28
29
30enum bdi_state {
31 BDI_wb_alloc,
32 BDI_async_congested,
33 BDI_sync_congested,
34 BDI_registered,
35 BDI_writeback_running,
36 BDI_unused,
37};
38
39typedef int (congested_fn)(void *, int);
40
41enum bdi_stat_item {
42 BDI_RECLAIMABLE,
43 BDI_WRITEBACK,
44 BDI_DIRTIED,
45 BDI_WRITTEN,
46 NR_BDI_STAT_ITEMS
47};
48
49#define BDI_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
50
51struct bdi_writeback {
52 struct backing_dev_info *bdi;
53 unsigned int nr;
54
55 unsigned long last_old_flush;
56
57 struct delayed_work dwork;
58 struct list_head b_dirty;
59 struct list_head b_io;
60 struct list_head b_more_io;
61 spinlock_t list_lock;
62};
63
64struct backing_dev_info {
65 struct list_head bdi_list;
66 unsigned long ra_pages;
67 unsigned long state;
68 unsigned int capabilities;
69 congested_fn *congested_fn;
70 void *congested_data;
71
72 char *name;
73
74 struct percpu_counter bdi_stat[NR_BDI_STAT_ITEMS];
75
76 unsigned long bw_time_stamp;
77 unsigned long dirtied_stamp;
78 unsigned long written_stamp;
79 unsigned long write_bandwidth;
80 unsigned long avg_write_bandwidth;
81
82
83
84
85
86
87
88 unsigned long dirty_ratelimit;
89 unsigned long balanced_dirty_ratelimit;
90
91 struct fprop_local_percpu completions;
92 int dirty_exceeded;
93
94 unsigned int min_ratio;
95 unsigned int max_ratio, max_prop_frac;
96
97 struct bdi_writeback wb;
98 spinlock_t wb_lock;
99
100 struct list_head work_list;
101
102 struct device *dev;
103
104 struct timer_list laptop_mode_wb_timer;
105
106#ifdef CONFIG_DEBUG_FS
107 struct dentry *debug_dir;
108 struct dentry *debug_stats;
109#endif
110};
111
112int bdi_init(struct backing_dev_info *bdi);
113void bdi_destroy(struct backing_dev_info *bdi);
114
115__printf(3, 4)
116int bdi_register(struct backing_dev_info *bdi, struct device *parent,
117 const char *fmt, ...);
118int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
119void bdi_unregister(struct backing_dev_info *bdi);
120int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
121void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
122 enum wb_reason reason);
123void bdi_start_background_writeback(struct backing_dev_info *bdi);
124void bdi_writeback_workfn(struct work_struct *work);
125int bdi_has_dirty_io(struct backing_dev_info *bdi);
126void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi);
127
128extern spinlock_t bdi_lock;
129extern struct list_head bdi_list;
130
131extern struct workqueue_struct *bdi_wq;
132
133static inline int wb_has_dirty_io(struct bdi_writeback *wb)
134{
135 return !list_empty(&wb->b_dirty) ||
136 !list_empty(&wb->b_io) ||
137 !list_empty(&wb->b_more_io);
138}
139
140static inline void __add_bdi_stat(struct backing_dev_info *bdi,
141 enum bdi_stat_item item, s64 amount)
142{
143 __percpu_counter_add(&bdi->bdi_stat[item], amount, BDI_STAT_BATCH);
144}
145
146static inline void __inc_bdi_stat(struct backing_dev_info *bdi,
147 enum bdi_stat_item item)
148{
149 __add_bdi_stat(bdi, item, 1);
150}
151
152static inline void inc_bdi_stat(struct backing_dev_info *bdi,
153 enum bdi_stat_item item)
154{
155 unsigned long flags;
156
157 local_irq_save(flags);
158 __inc_bdi_stat(bdi, item);
159 local_irq_restore(flags);
160}
161
162static inline void __dec_bdi_stat(struct backing_dev_info *bdi,
163 enum bdi_stat_item item)
164{
165 __add_bdi_stat(bdi, item, -1);
166}
167
168static inline void dec_bdi_stat(struct backing_dev_info *bdi,
169 enum bdi_stat_item item)
170{
171 unsigned long flags;
172
173 local_irq_save(flags);
174 __dec_bdi_stat(bdi, item);
175 local_irq_restore(flags);
176}
177
178static inline s64 bdi_stat(struct backing_dev_info *bdi,
179 enum bdi_stat_item item)
180{
181 return percpu_counter_read_positive(&bdi->bdi_stat[item]);
182}
183
184static inline s64 __bdi_stat_sum(struct backing_dev_info *bdi,
185 enum bdi_stat_item item)
186{
187 return percpu_counter_sum_positive(&bdi->bdi_stat[item]);
188}
189
190static inline s64 bdi_stat_sum(struct backing_dev_info *bdi,
191 enum bdi_stat_item item)
192{
193 s64 sum;
194 unsigned long flags;
195
196 local_irq_save(flags);
197 sum = __bdi_stat_sum(bdi, item);
198 local_irq_restore(flags);
199
200 return sum;
201}
202
203extern void bdi_writeout_inc(struct backing_dev_info *bdi);
204
205
206
207
208static inline unsigned long bdi_stat_error(struct backing_dev_info *bdi)
209{
210#ifdef CONFIG_SMP
211 return nr_cpu_ids * BDI_STAT_BATCH;
212#else
213 return 1;
214#endif
215}
216
217int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio);
218int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248#define BDI_CAP_NO_ACCT_DIRTY 0x00000001
249#define BDI_CAP_NO_WRITEBACK 0x00000002
250#define BDI_CAP_MAP_COPY 0x00000004
251#define BDI_CAP_MAP_DIRECT 0x00000008
252#define BDI_CAP_READ_MAP 0x00000010
253#define BDI_CAP_WRITE_MAP 0x00000020
254#define BDI_CAP_EXEC_MAP 0x00000040
255#define BDI_CAP_NO_ACCT_WB 0x00000080
256#define BDI_CAP_SWAP_BACKED 0x00000100
257#define BDI_CAP_STABLE_WRITES 0x00000200
258#define BDI_CAP_STRICTLIMIT 0x00000400
259
260#define BDI_CAP_VMFLAGS \
261 (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
262
263#define BDI_CAP_NO_ACCT_AND_WRITEBACK \
264 (BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB)
265
266#if defined(VM_MAYREAD) && \
267 (BDI_CAP_READ_MAP != VM_MAYREAD || \
268 BDI_CAP_WRITE_MAP != VM_MAYWRITE || \
269 BDI_CAP_EXEC_MAP != VM_MAYEXEC)
270#error please change backing_dev_info::capabilities flags
271#endif
272
273extern struct backing_dev_info default_backing_dev_info;
274extern struct backing_dev_info noop_backing_dev_info;
275
276int writeback_in_progress(struct backing_dev_info *bdi);
277
278static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
279{
280 struct super_block *sb = inode->i_sb;
281
282 if (sb_is_blkdev_sb(sb))
283 return inode->i_mapping->backing_dev_info;
284
285 return sb->s_bdi;
286}
287
288static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
289{
290 if (bdi->congested_fn)
291 return bdi->congested_fn(bdi->congested_data, bdi_bits);
292 return (bdi->state & bdi_bits);
293}
294
295static inline int bdi_read_congested(struct backing_dev_info *bdi)
296{
297 return bdi_congested(bdi, 1 << BDI_sync_congested);
298}
299
300static inline int bdi_write_congested(struct backing_dev_info *bdi)
301{
302 return bdi_congested(bdi, 1 << BDI_async_congested);
303}
304
305static inline int bdi_rw_congested(struct backing_dev_info *bdi)
306{
307 return bdi_congested(bdi, (1 << BDI_sync_congested) |
308 (1 << BDI_async_congested));
309}
310
311enum {
312 BLK_RW_ASYNC = 0,
313 BLK_RW_SYNC = 1,
314};
315
316void clear_bdi_congested(struct backing_dev_info *bdi, int sync);
317void set_bdi_congested(struct backing_dev_info *bdi, int sync);
318long congestion_wait(int sync, long timeout);
319long wait_iff_congested(struct zone *zone, int sync, long timeout);
320int pdflush_proc_obsolete(struct ctl_table *table, int write,
321 void __user *buffer, size_t *lenp, loff_t *ppos);
322
323static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi)
324{
325 return bdi->capabilities & BDI_CAP_STABLE_WRITES;
326}
327
328static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi)
329{
330 return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK);
331}
332
333static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi)
334{
335 return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY);
336}
337
338static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi)
339{
340
341 return !(bdi->capabilities & (BDI_CAP_NO_ACCT_WB |
342 BDI_CAP_NO_WRITEBACK));
343}
344
345static inline bool bdi_cap_swap_backed(struct backing_dev_info *bdi)
346{
347 return bdi->capabilities & BDI_CAP_SWAP_BACKED;
348}
349
350static inline bool mapping_cap_writeback_dirty(struct address_space *mapping)
351{
352 return bdi_cap_writeback_dirty(mapping->backing_dev_info);
353}
354
355static inline bool mapping_cap_account_dirty(struct address_space *mapping)
356{
357 return bdi_cap_account_dirty(mapping->backing_dev_info);
358}
359
360static inline bool mapping_cap_swap_backed(struct address_space *mapping)
361{
362 return bdi_cap_swap_backed(mapping->backing_dev_info);
363}
364
365static inline int bdi_sched_wait(void *word)
366{
367 schedule();
368 return 0;
369}
370
371#endif
372