Blame view

include/linux/backing-dev.h 13.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   * 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
cf0ca9fe5   Peter Zijlstra   mm: bdi: export B...
10
  #include <linux/kernel.h>
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
11
  #include <linux/fs.h>
03ba3782e   Jens Axboe   writeback: switch...
12
  #include <linux/sched.h>
a212b105b   Tejun Heo   bdi: make inode_t...
13
  #include <linux/blkdev.h>
03ba3782e   Jens Axboe   writeback: switch...
14
  #include <linux/writeback.h>
52ebea749   Tejun Heo   writeback: make b...
15
  #include <linux/blk-cgroup.h>
66114cad6   Tejun Heo   writeback: separa...
16
  #include <linux/backing-dev-defs.h>
a13f35e87   Tejun Heo   writeback: don't ...
17
  #include <linux/slab.h>
de1414a65   Christoph Hellwig   fs: export inode_...
18

8077c0d98   Mikulas Patocka   bdi: test bdi_ini...
19
  int __must_check bdi_init(struct backing_dev_info *bdi);
b02176f30   Tejun Heo   block: don't rele...
20
  void bdi_exit(struct backing_dev_info *bdi);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
21

d2cc4dde9   Joe Perches   bdi_register: add...
22
  __printf(3, 4)
cf0ca9fe5   Peter Zijlstra   mm: bdi: export B...
23
24
25
  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);
df08c32ce   Dan Williams   block: fix bdi vs...
26
  int bdi_register_owner(struct backing_dev_info *bdi, struct device *owner);
b02176f30   Tejun Heo   block: don't rele...
27
  void bdi_unregister(struct backing_dev_info *bdi);
b4caecd48   Christoph Hellwig   fs: introduce f_o...
28
  int __must_check bdi_setup_and_register(struct backing_dev_info *, char *);
b02176f30   Tejun Heo   block: don't rele...
29
  void bdi_destroy(struct backing_dev_info *bdi);
c00ddad39   Tejun Heo   writeback: remove...
30
31
  void wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
  			bool range_cyclic, enum wb_reason reason);
9ecf4866c   Tejun Heo   writeback: make b...
32
  void wb_start_background_writeback(struct bdi_writeback *wb);
f0054bb1e   Tejun Heo   writeback: move b...
33
  void wb_workfn(struct work_struct *work);
f0054bb1e   Tejun Heo   writeback: move b...
34
  void wb_wakeup_delayed(struct bdi_writeback *wb);
cf0ca9fe5   Peter Zijlstra   mm: bdi: export B...
35

03ba3782e   Jens Axboe   writeback: switch...
36
  extern spinlock_t bdi_lock;
66f3b8e2e   Jens Axboe   writeback: move d...
37
  extern struct list_head bdi_list;
839a8e866   Tejun Heo   writeback: replac...
38
  extern struct workqueue_struct *bdi_wq;
d6c10f1fc   Tejun Heo   writeback: implem...
39
  static inline bool wb_has_dirty_io(struct bdi_writeback *wb)
03ba3782e   Jens Axboe   writeback: switch...
40
  {
d6c10f1fc   Tejun Heo   writeback: implem...
41
  	return test_bit(WB_has_dirty_io, &wb->state);
03ba3782e   Jens Axboe   writeback: switch...
42
  }
95a46c65e   Tejun Heo   writeback: make b...
43
44
45
46
47
48
49
  static inline bool bdi_has_dirty_io(struct backing_dev_info *bdi)
  {
  	/*
  	 * @bdi->tot_write_bandwidth is guaranteed to be > 0 if there are
  	 * any dirty wbs.  See wb_update_write_bandwidth().
  	 */
  	return atomic_long_read(&bdi->tot_write_bandwidth);
03ba3782e   Jens Axboe   writeback: switch...
50
  }
93f78d882   Tejun Heo   writeback: move b...
51
52
  static inline void __add_wb_stat(struct bdi_writeback *wb,
  				 enum wb_stat_item item, s64 amount)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
53
  {
93f78d882   Tejun Heo   writeback: move b...
54
  	__percpu_counter_add(&wb->stat[item], amount, WB_STAT_BATCH);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
55
  }
93f78d882   Tejun Heo   writeback: move b...
56
57
  static inline void __inc_wb_stat(struct bdi_writeback *wb,
  				 enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
58
  {
93f78d882   Tejun Heo   writeback: move b...
59
  	__add_wb_stat(wb, item, 1);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
60
  }
93f78d882   Tejun Heo   writeback: move b...
61
  static inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
62
63
64
65
  {
  	unsigned long flags;
  
  	local_irq_save(flags);
93f78d882   Tejun Heo   writeback: move b...
66
  	__inc_wb_stat(wb, item);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
67
68
  	local_irq_restore(flags);
  }
93f78d882   Tejun Heo   writeback: move b...
69
70
  static inline void __dec_wb_stat(struct bdi_writeback *wb,
  				 enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
71
  {
93f78d882   Tejun Heo   writeback: move b...
72
  	__add_wb_stat(wb, item, -1);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
73
  }
93f78d882   Tejun Heo   writeback: move b...
74
  static inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
75
76
77
78
  {
  	unsigned long flags;
  
  	local_irq_save(flags);
93f78d882   Tejun Heo   writeback: move b...
79
  	__dec_wb_stat(wb, item);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
80
81
  	local_irq_restore(flags);
  }
93f78d882   Tejun Heo   writeback: move b...
82
  static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
83
  {
93f78d882   Tejun Heo   writeback: move b...
84
  	return percpu_counter_read_positive(&wb->stat[item]);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
85
  }
93f78d882   Tejun Heo   writeback: move b...
86
87
  static inline s64 __wb_stat_sum(struct bdi_writeback *wb,
  				enum wb_stat_item item)
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
88
  {
93f78d882   Tejun Heo   writeback: move b...
89
  	return percpu_counter_sum_positive(&wb->stat[item]);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
90
  }
93f78d882   Tejun Heo   writeback: move b...
91
  static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item)
e0bf68dde   Peter Zijlstra   mm: bdi init hooks
92
  {
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
93
94
95
96
  	s64 sum;
  	unsigned long flags;
  
  	local_irq_save(flags);
93f78d882   Tejun Heo   writeback: move b...
97
  	sum = __wb_stat_sum(wb, item);
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
98
99
100
  	local_irq_restore(flags);
  
  	return sum;
e0bf68dde   Peter Zijlstra   mm: bdi init hooks
101
  }
93f78d882   Tejun Heo   writeback: move b...
102
  extern void wb_writeout_inc(struct bdi_writeback *wb);
dd5656e59   Miklos Szeredi   mm: bdi: export b...
103

b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
104
105
106
  /*
   * maximal error of a stat counter.
   */
93f78d882   Tejun Heo   writeback: move b...
107
  static inline unsigned long wb_stat_error(struct bdi_writeback *wb)
e0bf68dde   Peter Zijlstra   mm: bdi init hooks
108
  {
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
109
  #ifdef CONFIG_SMP
93f78d882   Tejun Heo   writeback: move b...
110
  	return nr_cpu_ids * WB_STAT_BATCH;
b2e8fb6ef   Peter Zijlstra   mm: scalable bdi ...
111
112
113
  #else
  	return 1;
  #endif
e0bf68dde   Peter Zijlstra   mm: bdi init hooks
114
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115

189d3c4a9   Peter Zijlstra   mm: bdi: allow se...
116
  int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio);
a42dde041   Peter Zijlstra   mm: bdi: allow se...
117
  int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
189d3c4a9   Peter Zijlstra   mm: bdi: allow se...
118

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
  /*
   * Flags in backing_dev_info::capability
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
121
122
123
124
125
126
127
128
129
130
131
132
   *
   * 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
5a5374856   Maxim Patlasov   mm/page-writeback...
133
   * BDI_CAP_STRICTLIMIT:    Keep number of dirty pages below bdi threshold.
89e9b9e07   Tejun Heo   writeback: add {C...
134
135
   *
   * BDI_CAP_CGROUP_WRITEBACK: Supports cgroup-aware writeback.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
   */
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
137
138
  #define BDI_CAP_NO_ACCT_DIRTY	0x00000001
  #define BDI_CAP_NO_WRITEBACK	0x00000002
b4caecd48   Christoph Hellwig   fs: introduce f_o...
139
140
141
  #define BDI_CAP_NO_ACCT_WB	0x00000004
  #define BDI_CAP_STABLE_WRITES	0x00000008
  #define BDI_CAP_STRICTLIMIT	0x00000010
89e9b9e07   Tejun Heo   writeback: add {C...
142
  #define BDI_CAP_CGROUP_WRITEBACK 0x00000020
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143

e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
144
145
  #define BDI_CAP_NO_ACCT_AND_WRITEBACK \
  	(BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB)
5129a469a   Jörn Engel   Catch filesystems...
146
  extern struct backing_dev_info noop_backing_dev_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147

bc05873dc   Tejun Heo   writeback: make w...
148
149
150
151
152
153
154
155
  /**
   * writeback_in_progress - determine whether there is writeback in progress
   * @wb: bdi_writeback of interest
   *
   * Determine whether there is writeback waiting to be handled against a
   * bdi_writeback.
   */
  static inline bool writeback_in_progress(struct bdi_writeback *wb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  {
bc05873dc   Tejun Heo   writeback: make w...
157
  	return test_bit(WB_writeback_running, &wb->state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  }
a212b105b   Tejun Heo   bdi: make inode_t...
159
  static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  {
a212b105b   Tejun Heo   bdi: make inode_t...
161
  	struct super_block *sb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

a212b105b   Tejun Heo   bdi: make inode_t...
163
164
165
166
167
168
169
170
171
  	if (!inode)
  		return &noop_backing_dev_info;
  
  	sb = inode->i_sb;
  #ifdef CONFIG_BLOCK
  	if (sb_is_blkdev_sb(sb))
  		return blk_get_backing_dev_info(I_BDEV(inode));
  #endif
  	return sb->s_bdi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  }
ec8a6f264   Tejun Heo   writeback: make c...
173
  static inline int wb_congested(struct bdi_writeback *wb, int cong_bits)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  {
ec8a6f264   Tejun Heo   writeback: make c...
175
  	struct backing_dev_info *bdi = wb->bdi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176

ec8a6f264   Tejun Heo   writeback: make c...
177
178
179
  	if (bdi->congested_fn)
  		return bdi->congested_fn(bdi->congested_data, cong_bits);
  	return wb->congested->state & cong_bits;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
  }
373c0a7ed   Trond Myklebust   Fix compile error...
181

8aa7e847d   Jens Axboe   Fix congestion_wa...
182
  long congestion_wait(int sync, long timeout);
599d0c954   Mel Gorman   mm, vmscan: move ...
183
  long wait_iff_congested(struct pglist_data *pgdat, int sync, long timeout);
3965c9ae4   Wanpeng Li   mm: prepare for r...
184
185
  int pdflush_proc_obsolete(struct ctl_table *table, int write,
  		void __user *buffer, size_t *lenp, loff_t *ppos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186

7d311cdab   Darrick J. Wong   bdi: allow block ...
187
188
189
190
  static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi)
  {
  	return bdi->capabilities & BDI_CAP_STABLE_WRITES;
  }
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
191
192
193
194
195
196
197
198
199
  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);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200

e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
201
202
203
204
205
206
  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));
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207

e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
208
209
  static inline bool mapping_cap_writeback_dirty(struct address_space *mapping)
  {
de1414a65   Christoph Hellwig   fs: export inode_...
210
  	return bdi_cap_writeback_dirty(inode_to_bdi(mapping->host));
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
211
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212

e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
213
214
  static inline bool mapping_cap_account_dirty(struct address_space *mapping)
  {
de1414a65   Christoph Hellwig   fs: export inode_...
215
  	return bdi_cap_account_dirty(inode_to_bdi(mapping->host));
e4ad08fe6   Miklos Szeredi   mm: bdi: add sepa...
216
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217

03ba3782e   Jens Axboe   writeback: switch...
218
219
220
221
222
  static inline int bdi_sched_wait(void *word)
  {
  	schedule();
  	return 0;
  }
89e9b9e07   Tejun Heo   writeback: add {C...
223
  #ifdef CONFIG_CGROUP_WRITEBACK
52ebea749   Tejun Heo   writeback: make b...
224
225
226
227
228
229
  struct bdi_writeback_congested *
  wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp);
  void wb_congested_put(struct bdi_writeback_congested *congested);
  struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
  				    struct cgroup_subsys_state *memcg_css,
  				    gfp_t gfp);
52ebea749   Tejun Heo   writeback: make b...
230
231
  void wb_memcg_offline(struct mem_cgroup *memcg);
  void wb_blkcg_offline(struct blkcg *blkcg);
703c27088   Tejun Heo   writeback: implem...
232
  int inode_congested(struct inode *inode, int cong_bits);
52ebea749   Tejun Heo   writeback: make b...
233

89e9b9e07   Tejun Heo   writeback: add {C...
234
235
236
237
238
  /**
   * inode_cgwb_enabled - test whether cgroup writeback is enabled on an inode
   * @inode: inode of interest
   *
   * cgroup writeback requires support from both the bdi and filesystem.
9badce000   Tejun Heo   cgroup, writeback...
239
240
241
242
243
   * Also, both memcg and iocg have to be on the default hierarchy.  Test
   * whether all conditions are met.
   *
   * Note that the test result may change dynamically on the same inode
   * depending on how memcg and iocg are configured.
89e9b9e07   Tejun Heo   writeback: add {C...
244
245
246
247
   */
  static inline bool inode_cgwb_enabled(struct inode *inode)
  {
  	struct backing_dev_info *bdi = inode_to_bdi(inode);
c0522908d   Tejun Heo   cgroup: Merge bra...
248
249
  	return cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
  		cgroup_subsys_on_dfl(io_cgrp_subsys) &&
9badce000   Tejun Heo   cgroup, writeback...
250
  		bdi_cap_account_dirty(bdi) &&
89e9b9e07   Tejun Heo   writeback: add {C...
251
  		(bdi->capabilities & BDI_CAP_CGROUP_WRITEBACK) &&
46b15caa7   Tejun Heo   vfs, writeback: r...
252
  		(inode->i_sb->s_iflags & SB_I_CGROUPWB);
89e9b9e07   Tejun Heo   writeback: add {C...
253
  }
52ebea749   Tejun Heo   writeback: make b...
254
  /**
52ebea749   Tejun Heo   writeback: make b...
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
   * wb_find_current - find wb for %current on a bdi
   * @bdi: bdi of interest
   *
   * Find the wb of @bdi which matches both the memcg and blkcg of %current.
   * Must be called under rcu_read_lock() which protects the returend wb.
   * NULL if not found.
   */
  static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi)
  {
  	struct cgroup_subsys_state *memcg_css;
  	struct bdi_writeback *wb;
  
  	memcg_css = task_css(current, memory_cgrp_id);
  	if (!memcg_css->parent)
  		return &bdi->wb;
  
  	wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
  
  	/*
  	 * %current's blkcg equals the effective blkcg of its memcg.  No
  	 * need to use the relatively expensive cgroup_get_e_css().
  	 */
c165b3e3c   Tejun Heo   blkcg: rename sub...
277
  	if (likely(wb && wb->blkcg_css == task_css(current, io_cgrp_id)))
52ebea749   Tejun Heo   writeback: make b...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  		return wb;
  	return NULL;
  }
  
  /**
   * wb_get_create_current - get or create wb for %current on a bdi
   * @bdi: bdi of interest
   * @gfp: allocation mask
   *
   * Equivalent to wb_get_create() on %current's memcg.  This function is
   * called from a relatively hot path and optimizes the common cases using
   * wb_find_current().
   */
  static inline struct bdi_writeback *
  wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp)
  {
  	struct bdi_writeback *wb;
  
  	rcu_read_lock();
  	wb = wb_find_current(bdi);
  	if (wb && unlikely(!wb_tryget(wb)))
  		wb = NULL;
  	rcu_read_unlock();
  
  	if (unlikely(!wb)) {
  		struct cgroup_subsys_state *memcg_css;
  
  		memcg_css = task_get_css(current, memory_cgrp_id);
  		wb = wb_get_create(bdi, memcg_css, gfp);
  		css_put(memcg_css);
  	}
  	return wb;
  }
  
  /**
aaa2cacf8   Tejun Heo   writeback: add lo...
313
314
315
316
317
318
319
320
321
322
323
324
   * inode_to_wb_is_valid - test whether an inode has a wb associated
   * @inode: inode of interest
   *
   * Returns %true if @inode has a wb associated.  May be called without any
   * locking.
   */
  static inline bool inode_to_wb_is_valid(struct inode *inode)
  {
  	return inode->i_wb;
  }
  
  /**
52ebea749   Tejun Heo   writeback: make b...
325
326
327
   * inode_to_wb - determine the wb of an inode
   * @inode: inode of interest
   *
aaa2cacf8   Tejun Heo   writeback: add lo...
328
329
330
   * Returns the wb @inode is currently associated with.  The caller must be
   * holding either @inode->i_lock, @inode->i_mapping->tree_lock, or the
   * associated wb's list_lock.
52ebea749   Tejun Heo   writeback: make b...
331
332
333
   */
  static inline struct bdi_writeback *inode_to_wb(struct inode *inode)
  {
aaa2cacf8   Tejun Heo   writeback: add lo...
334
335
336
337
338
339
  #ifdef CONFIG_LOCKDEP
  	WARN_ON_ONCE(debug_locks &&
  		     (!lockdep_is_held(&inode->i_lock) &&
  		      !lockdep_is_held(&inode->i_mapping->tree_lock) &&
  		      !lockdep_is_held(&inode->i_wb->list_lock)));
  #endif
52ebea749   Tejun Heo   writeback: make b...
340
341
  	return inode->i_wb;
  }
682aa8e1a   Tejun Heo   writeback: implem...
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
  /**
   * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction
   * @inode: target inode
   * @lockedp: temp bool output param, to be passed to the end function
   *
   * The caller wants to access the wb associated with @inode but isn't
   * holding inode->i_lock, mapping->tree_lock or wb->list_lock.  This
   * function determines the wb associated with @inode and ensures that the
   * association doesn't change until the transaction is finished with
   * unlocked_inode_to_wb_end().
   *
   * The caller must call unlocked_inode_to_wb_end() with *@lockdep
   * afterwards and can't sleep during transaction.  IRQ may or may not be
   * disabled on return.
   */
  static inline struct bdi_writeback *
  unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
  {
  	rcu_read_lock();
  
  	/*
  	 * Paired with store_release in inode_switch_wb_work_fn() and
  	 * ensures that we see the new wb if we see cleared I_WB_SWITCH.
  	 */
  	*lockedp = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
  
  	if (unlikely(*lockedp))
  		spin_lock_irq(&inode->i_mapping->tree_lock);
aaa2cacf8   Tejun Heo   writeback: add lo...
370
371
372
373
374
375
  
  	/*
  	 * Protected by either !I_WB_SWITCH + rcu_read_lock() or tree_lock.
  	 * inode_to_wb() will bark.  Deref directly.
  	 */
  	return inode->i_wb;
682aa8e1a   Tejun Heo   writeback: implem...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
  }
  
  /**
   * unlocked_inode_to_wb_end - end inode wb access transaction
   * @inode: target inode
   * @locked: *@lockedp from unlocked_inode_to_wb_begin()
   */
  static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
  {
  	if (unlikely(locked))
  		spin_unlock_irq(&inode->i_mapping->tree_lock);
  
  	rcu_read_unlock();
  }
89e9b9e07   Tejun Heo   writeback: add {C...
390
391
392
393
394
395
  #else	/* CONFIG_CGROUP_WRITEBACK */
  
  static inline bool inode_cgwb_enabled(struct inode *inode)
  {
  	return false;
  }
52ebea749   Tejun Heo   writeback: make b...
396
397
398
  static inline struct bdi_writeback_congested *
  wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp)
  {
a13f35e87   Tejun Heo   writeback: don't ...
399
400
  	atomic_inc(&bdi->wb_congested->refcnt);
  	return bdi->wb_congested;
52ebea749   Tejun Heo   writeback: make b...
401
402
403
404
  }
  
  static inline void wb_congested_put(struct bdi_writeback_congested *congested)
  {
a13f35e87   Tejun Heo   writeback: don't ...
405
406
  	if (atomic_dec_and_test(&congested->refcnt))
  		kfree(congested);
52ebea749   Tejun Heo   writeback: make b...
407
  }
52ebea749   Tejun Heo   writeback: make b...
408
409
410
411
412
413
414
415
416
417
  static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi)
  {
  	return &bdi->wb;
  }
  
  static inline struct bdi_writeback *
  wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp)
  {
  	return &bdi->wb;
  }
aaa2cacf8   Tejun Heo   writeback: add lo...
418
419
420
421
  static inline bool inode_to_wb_is_valid(struct inode *inode)
  {
  	return true;
  }
52ebea749   Tejun Heo   writeback: make b...
422
423
424
425
  static inline struct bdi_writeback *inode_to_wb(struct inode *inode)
  {
  	return &inode_to_bdi(inode)->wb;
  }
682aa8e1a   Tejun Heo   writeback: implem...
426
427
428
429
430
431
432
433
434
  static inline struct bdi_writeback *
  unlocked_inode_to_wb_begin(struct inode *inode, bool *lockedp)
  {
  	return inode_to_wb(inode);
  }
  
  static inline void unlocked_inode_to_wb_end(struct inode *inode, bool locked)
  {
  }
52ebea749   Tejun Heo   writeback: make b...
435
436
437
438
439
440
441
  static inline void wb_memcg_offline(struct mem_cgroup *memcg)
  {
  }
  
  static inline void wb_blkcg_offline(struct blkcg *blkcg)
  {
  }
703c27088   Tejun Heo   writeback: implem...
442
443
444
445
  static inline int inode_congested(struct inode *inode, int cong_bits)
  {
  	return wb_congested(&inode_to_bdi(inode)->wb, cong_bits);
  }
89e9b9e07   Tejun Heo   writeback: add {C...
446
  #endif	/* CONFIG_CGROUP_WRITEBACK */
703c27088   Tejun Heo   writeback: implem...
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
  static inline int inode_read_congested(struct inode *inode)
  {
  	return inode_congested(inode, 1 << WB_sync_congested);
  }
  
  static inline int inode_write_congested(struct inode *inode)
  {
  	return inode_congested(inode, 1 << WB_async_congested);
  }
  
  static inline int inode_rw_congested(struct inode *inode)
  {
  	return inode_congested(inode, (1 << WB_sync_congested) |
  				      (1 << WB_async_congested));
  }
ec8a6f264   Tejun Heo   writeback: make c...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
  static inline int bdi_congested(struct backing_dev_info *bdi, int cong_bits)
  {
  	return wb_congested(&bdi->wb, cong_bits);
  }
  
  static inline int bdi_read_congested(struct backing_dev_info *bdi)
  {
  	return bdi_congested(bdi, 1 << WB_sync_congested);
  }
  
  static inline int bdi_write_congested(struct backing_dev_info *bdi)
  {
  	return bdi_congested(bdi, 1 << WB_async_congested);
  }
  
  static inline int bdi_rw_congested(struct backing_dev_info *bdi)
  {
  	return bdi_congested(bdi, (1 << WB_sync_congested) |
  				  (1 << WB_async_congested));
  }
89e9b9e07   Tejun Heo   writeback: add {C...
482
  #endif	/* _LINUX_BACKING_DEV_H */