backing-dev.h 6.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10
/*
 * include/linux/backing-dev.h
 *
 * low-level device information and state which is propagated up through
 * to high-level code.
 */

#ifndef _LINUX_BACKING_DEV_H
#define _LINUX_BACKING_DEV_H

11
#include <linux/kernel.h>
12
#include <linux/fs.h>
13 14
#include <linux/sched.h>
#include <linux/writeback.h>
15
#include <linux/backing-dev-defs.h>
L
Linus Torvalds 已提交
16

17 18
struct backing_dev_info *inode_to_bdi(struct inode *inode);

M
Mikulas Patocka 已提交
19
int __must_check bdi_init(struct backing_dev_info *bdi);
20 21
void bdi_destroy(struct backing_dev_info *bdi);

22
__printf(3, 4)
23 24 25 26
int bdi_register(struct backing_dev_info *bdi, struct device *parent,
		const char *fmt, ...);
int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
void bdi_unregister(struct backing_dev_info *bdi);
27
int __must_check bdi_setup_and_register(struct backing_dev_info *, char *);
28 29
void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
			enum wb_reason reason);
30
void bdi_start_background_writeback(struct backing_dev_info *bdi);
31
void wb_workfn(struct work_struct *work);
32
int bdi_has_dirty_io(struct backing_dev_info *bdi);
33
void wb_wakeup_delayed(struct bdi_writeback *wb);
34

35
extern spinlock_t bdi_lock;
36 37
extern struct list_head bdi_list;

38 39
extern struct workqueue_struct *bdi_wq;

40 41 42 43 44 45 46
static inline int wb_has_dirty_io(struct bdi_writeback *wb)
{
	return !list_empty(&wb->b_dirty) ||
	       !list_empty(&wb->b_io) ||
	       !list_empty(&wb->b_more_io);
}

47 48
static inline void __add_wb_stat(struct bdi_writeback *wb,
				 enum wb_stat_item item, s64 amount)
49
{
50
	__percpu_counter_add(&wb->stat[item], amount, WB_STAT_BATCH);
51 52
}

53 54
static inline void __inc_wb_stat(struct bdi_writeback *wb,
				 enum wb_stat_item item)
55
{
56
	__add_wb_stat(wb, item, 1);
57 58
}

59
static inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
60 61 62 63
{
	unsigned long flags;

	local_irq_save(flags);
64
	__inc_wb_stat(wb, item);
65 66 67
	local_irq_restore(flags);
}

68 69
static inline void __dec_wb_stat(struct bdi_writeback *wb,
				 enum wb_stat_item item)
70
{
71
	__add_wb_stat(wb, item, -1);
72 73
}

74
static inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
75 76 77 78
{
	unsigned long flags;

	local_irq_save(flags);
79
	__dec_wb_stat(wb, item);
80 81 82
	local_irq_restore(flags);
}

83
static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
84
{
85
	return percpu_counter_read_positive(&wb->stat[item]);
86 87
}

88 89
static inline s64 __wb_stat_sum(struct bdi_writeback *wb,
				enum wb_stat_item item)
90
{
91
	return percpu_counter_sum_positive(&wb->stat[item]);
92 93
}

94
static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item)
P
Peter Zijlstra 已提交
95
{
96 97 98 99
	s64 sum;
	unsigned long flags;

	local_irq_save(flags);
100
	sum = __wb_stat_sum(wb, item);
101 102 103
	local_irq_restore(flags);

	return sum;
P
Peter Zijlstra 已提交
104 105
}

106
extern void wb_writeout_inc(struct bdi_writeback *wb);
107

108 109 110
/*
 * maximal error of a stat counter.
 */
111
static inline unsigned long wb_stat_error(struct bdi_writeback *wb)
P
Peter Zijlstra 已提交
112
{
113
#ifdef CONFIG_SMP
114
	return nr_cpu_ids * WB_STAT_BATCH;
115 116 117
#else
	return 1;
#endif
P
Peter Zijlstra 已提交
118
}
L
Linus Torvalds 已提交
119

120
int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio);
121
int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
122

L
Linus Torvalds 已提交
123 124
/*
 * Flags in backing_dev_info::capability
125 126 127 128 129 130 131 132 133 134 135 136
 *
 * The first three flags control whether dirty pages will contribute to the
 * VM's accounting and whether writepages() should be called for dirty pages
 * (something that would not, for example, be appropriate for ramfs)
 *
 * WARNING: these flags are closely related and should not normally be
 * used separately.  The BDI_CAP_NO_ACCT_AND_WRITEBACK combines these
 * three flags into a single convenience macro.
 *
 * BDI_CAP_NO_ACCT_DIRTY:  Dirty pages shouldn't contribute to accounting
 * BDI_CAP_NO_WRITEBACK:   Don't write pages back
 * BDI_CAP_NO_ACCT_WB:     Don't automatically account writeback pages
137
 * BDI_CAP_STRICTLIMIT:    Keep number of dirty pages below bdi threshold.
L
Linus Torvalds 已提交
138
 */
139 140
#define BDI_CAP_NO_ACCT_DIRTY	0x00000001
#define BDI_CAP_NO_WRITEBACK	0x00000002
141 142 143
#define BDI_CAP_NO_ACCT_WB	0x00000004
#define BDI_CAP_STABLE_WRITES	0x00000008
#define BDI_CAP_STRICTLIMIT	0x00000010
L
Linus Torvalds 已提交
144

145 146 147
#define BDI_CAP_NO_ACCT_AND_WRITEBACK \
	(BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB)

J
Jörn Engel 已提交
148
extern struct backing_dev_info noop_backing_dev_info;
L
Linus Torvalds 已提交
149 150 151 152 153 154 155

int writeback_in_progress(struct backing_dev_info *bdi);

static inline int bdi_congested(struct backing_dev_info *bdi, int bdi_bits)
{
	if (bdi->congested_fn)
		return bdi->congested_fn(bdi->congested_data, bdi_bits);
156
	return (bdi->wb.state & bdi_bits);
L
Linus Torvalds 已提交
157 158 159 160
}

static inline int bdi_read_congested(struct backing_dev_info *bdi)
{
161
	return bdi_congested(bdi, 1 << WB_sync_congested);
L
Linus Torvalds 已提交
162 163 164 165
}

static inline int bdi_write_congested(struct backing_dev_info *bdi)
{
166
	return bdi_congested(bdi, 1 << WB_async_congested);
L
Linus Torvalds 已提交
167 168 169 170
}

static inline int bdi_rw_congested(struct backing_dev_info *bdi)
{
171 172
	return bdi_congested(bdi, (1 << WB_sync_congested) |
				  (1 << WB_async_congested));
L
Linus Torvalds 已提交
173 174
}

175
long congestion_wait(int sync, long timeout);
176
long wait_iff_congested(struct zone *zone, int sync, long timeout);
177 178
int pdflush_proc_obsolete(struct ctl_table *table, int write,
		void __user *buffer, size_t *lenp, loff_t *ppos);
L
Linus Torvalds 已提交
179

180 181 182 183 184
static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi)
{
	return bdi->capabilities & BDI_CAP_STABLE_WRITES;
}

185 186 187 188 189 190 191 192 193
static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi)
{
	return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK);
}

static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi)
{
	return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY);
}
L
Linus Torvalds 已提交
194

195 196 197 198 199 200
static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi)
{
	/* Paranoia: BDI_CAP_NO_WRITEBACK implies BDI_CAP_NO_ACCT_WB */
	return !(bdi->capabilities & (BDI_CAP_NO_ACCT_WB |
				      BDI_CAP_NO_WRITEBACK));
}
L
Linus Torvalds 已提交
201

202 203
static inline bool mapping_cap_writeback_dirty(struct address_space *mapping)
{
204
	return bdi_cap_writeback_dirty(inode_to_bdi(mapping->host));
205
}
L
Linus Torvalds 已提交
206

207 208
static inline bool mapping_cap_account_dirty(struct address_space *mapping)
{
209
	return bdi_cap_account_dirty(inode_to_bdi(mapping->host));
210
}
L
Linus Torvalds 已提交
211

212 213 214 215 216 217
static inline int bdi_sched_wait(void *word)
{
	schedule();
	return 0;
}

L
Linus Torvalds 已提交
218
#endif		/* _LINUX_BACKING_DEV_H */