11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * include/linux/backing-dev.h 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * low-level device information and state which is propagated up through 51da177e4SLinus Torvalds * to high-level code. 61da177e4SLinus Torvalds */ 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #ifndef _LINUX_BACKING_DEV_H 91da177e4SLinus Torvalds #define _LINUX_BACKING_DEV_H 101da177e4SLinus Torvalds 11cf0ca9feSPeter Zijlstra #include <linux/kernel.h> 12e4ad08feSMiklos Szeredi #include <linux/fs.h> 1303ba3782SJens Axboe #include <linux/sched.h> 14a212b105STejun Heo #include <linux/blkdev.h> 1503ba3782SJens Axboe #include <linux/writeback.h> 1652ebea74STejun Heo #include <linux/blk-cgroup.h> 1766114cadSTejun Heo #include <linux/backing-dev-defs.h> 181da177e4SLinus Torvalds 198077c0d9SMikulas Patocka int __must_check bdi_init(struct backing_dev_info *bdi); 20b2e8fb6eSPeter Zijlstra void bdi_destroy(struct backing_dev_info *bdi); 21b2e8fb6eSPeter Zijlstra 22d2cc4ddeSJoe Perches __printf(3, 4) 23cf0ca9feSPeter Zijlstra int bdi_register(struct backing_dev_info *bdi, struct device *parent, 24cf0ca9feSPeter Zijlstra const char *fmt, ...); 25cf0ca9feSPeter Zijlstra int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); 26cf0ca9feSPeter Zijlstra void bdi_unregister(struct backing_dev_info *bdi); 27b4caecd4SChristoph Hellwig int __must_check bdi_setup_and_register(struct backing_dev_info *, char *); 280e175a18SCurt Wohlgemuth void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, 290e175a18SCurt Wohlgemuth enum wb_reason reason); 30c5444198SChristoph Hellwig void bdi_start_background_writeback(struct backing_dev_info *bdi); 31f0054bb1STejun Heo void wb_workfn(struct work_struct *work); 3203ba3782SJens Axboe int bdi_has_dirty_io(struct backing_dev_info *bdi); 33f0054bb1STejun Heo void wb_wakeup_delayed(struct bdi_writeback *wb); 34cf0ca9feSPeter Zijlstra 3503ba3782SJens Axboe extern spinlock_t bdi_lock; 3666f3b8e2SJens Axboe extern struct list_head bdi_list; 3766f3b8e2SJens Axboe 38839a8e86STejun Heo extern struct workqueue_struct *bdi_wq; 39839a8e86STejun Heo 4003ba3782SJens Axboe static inline int wb_has_dirty_io(struct bdi_writeback *wb) 4103ba3782SJens Axboe { 4203ba3782SJens Axboe return !list_empty(&wb->b_dirty) || 4303ba3782SJens Axboe !list_empty(&wb->b_io) || 4403ba3782SJens Axboe !list_empty(&wb->b_more_io); 4503ba3782SJens Axboe } 4603ba3782SJens Axboe 4793f78d88STejun Heo static inline void __add_wb_stat(struct bdi_writeback *wb, 4893f78d88STejun Heo enum wb_stat_item item, s64 amount) 49e0bf68ddSPeter Zijlstra { 5093f78d88STejun Heo __percpu_counter_add(&wb->stat[item], amount, WB_STAT_BATCH); 51e0bf68ddSPeter Zijlstra } 52e0bf68ddSPeter Zijlstra 5393f78d88STejun Heo static inline void __inc_wb_stat(struct bdi_writeback *wb, 5493f78d88STejun Heo enum wb_stat_item item) 55e0bf68ddSPeter Zijlstra { 5693f78d88STejun Heo __add_wb_stat(wb, item, 1); 57b2e8fb6eSPeter Zijlstra } 58b2e8fb6eSPeter Zijlstra 5993f78d88STejun Heo static inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 60b2e8fb6eSPeter Zijlstra { 61b2e8fb6eSPeter Zijlstra unsigned long flags; 62b2e8fb6eSPeter Zijlstra 63b2e8fb6eSPeter Zijlstra local_irq_save(flags); 6493f78d88STejun Heo __inc_wb_stat(wb, item); 65b2e8fb6eSPeter Zijlstra local_irq_restore(flags); 66b2e8fb6eSPeter Zijlstra } 67b2e8fb6eSPeter Zijlstra 6893f78d88STejun Heo static inline void __dec_wb_stat(struct bdi_writeback *wb, 6993f78d88STejun Heo enum wb_stat_item item) 70b2e8fb6eSPeter Zijlstra { 7193f78d88STejun Heo __add_wb_stat(wb, item, -1); 72b2e8fb6eSPeter Zijlstra } 73b2e8fb6eSPeter Zijlstra 7493f78d88STejun Heo static inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 75b2e8fb6eSPeter Zijlstra { 76b2e8fb6eSPeter Zijlstra unsigned long flags; 77b2e8fb6eSPeter Zijlstra 78b2e8fb6eSPeter Zijlstra local_irq_save(flags); 7993f78d88STejun Heo __dec_wb_stat(wb, item); 80b2e8fb6eSPeter Zijlstra local_irq_restore(flags); 81b2e8fb6eSPeter Zijlstra } 82b2e8fb6eSPeter Zijlstra 8393f78d88STejun Heo static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 84b2e8fb6eSPeter Zijlstra { 8593f78d88STejun Heo return percpu_counter_read_positive(&wb->stat[item]); 86b2e8fb6eSPeter Zijlstra } 87b2e8fb6eSPeter Zijlstra 8893f78d88STejun Heo static inline s64 __wb_stat_sum(struct bdi_writeback *wb, 8993f78d88STejun Heo enum wb_stat_item item) 90b2e8fb6eSPeter Zijlstra { 9193f78d88STejun Heo return percpu_counter_sum_positive(&wb->stat[item]); 92b2e8fb6eSPeter Zijlstra } 93b2e8fb6eSPeter Zijlstra 9493f78d88STejun Heo static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item) 95b2e8fb6eSPeter Zijlstra { 96b2e8fb6eSPeter Zijlstra s64 sum; 97b2e8fb6eSPeter Zijlstra unsigned long flags; 98b2e8fb6eSPeter Zijlstra 99b2e8fb6eSPeter Zijlstra local_irq_save(flags); 10093f78d88STejun Heo sum = __wb_stat_sum(wb, item); 101b2e8fb6eSPeter Zijlstra local_irq_restore(flags); 102b2e8fb6eSPeter Zijlstra 103b2e8fb6eSPeter Zijlstra return sum; 104b2e8fb6eSPeter Zijlstra } 105b2e8fb6eSPeter Zijlstra 10693f78d88STejun Heo extern void wb_writeout_inc(struct bdi_writeback *wb); 107dd5656e5SMiklos Szeredi 108b2e8fb6eSPeter Zijlstra /* 109b2e8fb6eSPeter Zijlstra * maximal error of a stat counter. 110b2e8fb6eSPeter Zijlstra */ 11193f78d88STejun Heo static inline unsigned long wb_stat_error(struct bdi_writeback *wb) 112b2e8fb6eSPeter Zijlstra { 113b2e8fb6eSPeter Zijlstra #ifdef CONFIG_SMP 11493f78d88STejun Heo return nr_cpu_ids * WB_STAT_BATCH; 115b2e8fb6eSPeter Zijlstra #else 116b2e8fb6eSPeter Zijlstra return 1; 117b2e8fb6eSPeter Zijlstra #endif 118e0bf68ddSPeter Zijlstra } 1191da177e4SLinus Torvalds 120189d3c4aSPeter Zijlstra int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio); 121a42dde04SPeter Zijlstra int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); 122189d3c4aSPeter Zijlstra 1231da177e4SLinus Torvalds /* 1241da177e4SLinus Torvalds * Flags in backing_dev_info::capability 125e4ad08feSMiklos Szeredi * 126e4ad08feSMiklos Szeredi * The first three flags control whether dirty pages will contribute to the 1271da177e4SLinus Torvalds * VM's accounting and whether writepages() should be called for dirty pages 1281da177e4SLinus Torvalds * (something that would not, for example, be appropriate for ramfs) 129e4ad08feSMiklos Szeredi * 130e4ad08feSMiklos Szeredi * WARNING: these flags are closely related and should not normally be 131e4ad08feSMiklos Szeredi * used separately. The BDI_CAP_NO_ACCT_AND_WRITEBACK combines these 132e4ad08feSMiklos Szeredi * three flags into a single convenience macro. 133e4ad08feSMiklos Szeredi * 134e4ad08feSMiklos Szeredi * BDI_CAP_NO_ACCT_DIRTY: Dirty pages shouldn't contribute to accounting 135e4ad08feSMiklos Szeredi * BDI_CAP_NO_WRITEBACK: Don't write pages back 136e4ad08feSMiklos Szeredi * BDI_CAP_NO_ACCT_WB: Don't automatically account writeback pages 1375a537485SMaxim Patlasov * BDI_CAP_STRICTLIMIT: Keep number of dirty pages below bdi threshold. 13889e9b9e0STejun Heo * 13989e9b9e0STejun Heo * BDI_CAP_CGROUP_WRITEBACK: Supports cgroup-aware writeback. 1401da177e4SLinus Torvalds */ 141e4ad08feSMiklos Szeredi #define BDI_CAP_NO_ACCT_DIRTY 0x00000001 142e4ad08feSMiklos Szeredi #define BDI_CAP_NO_WRITEBACK 0x00000002 143b4caecd4SChristoph Hellwig #define BDI_CAP_NO_ACCT_WB 0x00000004 144b4caecd4SChristoph Hellwig #define BDI_CAP_STABLE_WRITES 0x00000008 145b4caecd4SChristoph Hellwig #define BDI_CAP_STRICTLIMIT 0x00000010 14689e9b9e0STejun Heo #define BDI_CAP_CGROUP_WRITEBACK 0x00000020 1471da177e4SLinus Torvalds 148e4ad08feSMiklos Szeredi #define BDI_CAP_NO_ACCT_AND_WRITEBACK \ 149e4ad08feSMiklos Szeredi (BDI_CAP_NO_WRITEBACK | BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_ACCT_WB) 150e4ad08feSMiklos Szeredi 1515129a469SJörn Engel extern struct backing_dev_info noop_backing_dev_info; 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds int writeback_in_progress(struct backing_dev_info *bdi); 1541da177e4SLinus Torvalds 155a212b105STejun Heo static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) 156a212b105STejun Heo { 157a212b105STejun Heo struct super_block *sb; 158a212b105STejun Heo 159a212b105STejun Heo if (!inode) 160a212b105STejun Heo return &noop_backing_dev_info; 161a212b105STejun Heo 162a212b105STejun Heo sb = inode->i_sb; 163a212b105STejun Heo #ifdef CONFIG_BLOCK 164a212b105STejun Heo if (sb_is_blkdev_sb(sb)) 165a212b105STejun Heo return blk_get_backing_dev_info(I_BDEV(inode)); 166a212b105STejun Heo #endif 167a212b105STejun Heo return sb->s_bdi; 168a212b105STejun Heo } 169a212b105STejun Heo 170*ec8a6f26STejun Heo static inline int wb_congested(struct bdi_writeback *wb, int cong_bits) 1711da177e4SLinus Torvalds { 172*ec8a6f26STejun Heo struct backing_dev_info *bdi = wb->bdi; 173*ec8a6f26STejun Heo 1741da177e4SLinus Torvalds if (bdi->congested_fn) 175*ec8a6f26STejun Heo return bdi->congested_fn(bdi->congested_data, cong_bits); 176*ec8a6f26STejun Heo return wb->congested->state & cong_bits; 1771da177e4SLinus Torvalds } 1781da177e4SLinus Torvalds 1798aa7e847SJens Axboe long congestion_wait(int sync, long timeout); 1800e093d99SMel Gorman long wait_iff_congested(struct zone *zone, int sync, long timeout); 1813965c9aeSWanpeng Li int pdflush_proc_obsolete(struct ctl_table *table, int write, 1823965c9aeSWanpeng Li void __user *buffer, size_t *lenp, loff_t *ppos); 1831da177e4SLinus Torvalds 1847d311cdaSDarrick J. Wong static inline bool bdi_cap_stable_pages_required(struct backing_dev_info *bdi) 1857d311cdaSDarrick J. Wong { 1867d311cdaSDarrick J. Wong return bdi->capabilities & BDI_CAP_STABLE_WRITES; 1877d311cdaSDarrick J. Wong } 1887d311cdaSDarrick J. Wong 189e4ad08feSMiklos Szeredi static inline bool bdi_cap_writeback_dirty(struct backing_dev_info *bdi) 190e4ad08feSMiklos Szeredi { 191e4ad08feSMiklos Szeredi return !(bdi->capabilities & BDI_CAP_NO_WRITEBACK); 192e4ad08feSMiklos Szeredi } 1931da177e4SLinus Torvalds 194e4ad08feSMiklos Szeredi static inline bool bdi_cap_account_dirty(struct backing_dev_info *bdi) 195e4ad08feSMiklos Szeredi { 196e4ad08feSMiklos Szeredi return !(bdi->capabilities & BDI_CAP_NO_ACCT_DIRTY); 197e4ad08feSMiklos Szeredi } 1981da177e4SLinus Torvalds 199e4ad08feSMiklos Szeredi static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi) 200e4ad08feSMiklos Szeredi { 201e4ad08feSMiklos Szeredi /* Paranoia: BDI_CAP_NO_WRITEBACK implies BDI_CAP_NO_ACCT_WB */ 202e4ad08feSMiklos Szeredi return !(bdi->capabilities & (BDI_CAP_NO_ACCT_WB | 203e4ad08feSMiklos Szeredi BDI_CAP_NO_WRITEBACK)); 204e4ad08feSMiklos Szeredi } 2051da177e4SLinus Torvalds 206e4ad08feSMiklos Szeredi static inline bool mapping_cap_writeback_dirty(struct address_space *mapping) 207e4ad08feSMiklos Szeredi { 208de1414a6SChristoph Hellwig return bdi_cap_writeback_dirty(inode_to_bdi(mapping->host)); 209e4ad08feSMiklos Szeredi } 210e4ad08feSMiklos Szeredi 211e4ad08feSMiklos Szeredi static inline bool mapping_cap_account_dirty(struct address_space *mapping) 212e4ad08feSMiklos Szeredi { 213de1414a6SChristoph Hellwig return bdi_cap_account_dirty(inode_to_bdi(mapping->host)); 214e4ad08feSMiklos Szeredi } 2151da177e4SLinus Torvalds 21603ba3782SJens Axboe static inline int bdi_sched_wait(void *word) 21703ba3782SJens Axboe { 21803ba3782SJens Axboe schedule(); 21903ba3782SJens Axboe return 0; 22003ba3782SJens Axboe } 22103ba3782SJens Axboe 22289e9b9e0STejun Heo #ifdef CONFIG_CGROUP_WRITEBACK 22389e9b9e0STejun Heo 22452ebea74STejun Heo struct bdi_writeback_congested * 22552ebea74STejun Heo wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp); 22652ebea74STejun Heo void wb_congested_put(struct bdi_writeback_congested *congested); 22752ebea74STejun Heo struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, 22852ebea74STejun Heo struct cgroup_subsys_state *memcg_css, 22952ebea74STejun Heo gfp_t gfp); 23052ebea74STejun Heo void __inode_attach_wb(struct inode *inode, struct page *page); 23152ebea74STejun Heo void wb_memcg_offline(struct mem_cgroup *memcg); 23252ebea74STejun Heo void wb_blkcg_offline(struct blkcg *blkcg); 23352ebea74STejun Heo 23489e9b9e0STejun Heo /** 23589e9b9e0STejun Heo * inode_cgwb_enabled - test whether cgroup writeback is enabled on an inode 23689e9b9e0STejun Heo * @inode: inode of interest 23789e9b9e0STejun Heo * 23889e9b9e0STejun Heo * cgroup writeback requires support from both the bdi and filesystem. 23989e9b9e0STejun Heo * Test whether @inode has both. 24089e9b9e0STejun Heo */ 24189e9b9e0STejun Heo static inline bool inode_cgwb_enabled(struct inode *inode) 24289e9b9e0STejun Heo { 24389e9b9e0STejun Heo struct backing_dev_info *bdi = inode_to_bdi(inode); 24489e9b9e0STejun Heo 24589e9b9e0STejun Heo return bdi_cap_account_dirty(bdi) && 24689e9b9e0STejun Heo (bdi->capabilities & BDI_CAP_CGROUP_WRITEBACK) && 24789e9b9e0STejun Heo (inode->i_sb->s_type->fs_flags & FS_CGROUP_WRITEBACK); 24889e9b9e0STejun Heo } 24989e9b9e0STejun Heo 25052ebea74STejun Heo /** 25152ebea74STejun Heo * wb_tryget - try to increment a wb's refcount 25252ebea74STejun Heo * @wb: bdi_writeback to get 25352ebea74STejun Heo */ 25452ebea74STejun Heo static inline bool wb_tryget(struct bdi_writeback *wb) 25552ebea74STejun Heo { 25652ebea74STejun Heo if (wb != &wb->bdi->wb) 25752ebea74STejun Heo return percpu_ref_tryget(&wb->refcnt); 25852ebea74STejun Heo return true; 25952ebea74STejun Heo } 26052ebea74STejun Heo 26152ebea74STejun Heo /** 26252ebea74STejun Heo * wb_get - increment a wb's refcount 26352ebea74STejun Heo * @wb: bdi_writeback to get 26452ebea74STejun Heo */ 26552ebea74STejun Heo static inline void wb_get(struct bdi_writeback *wb) 26652ebea74STejun Heo { 26752ebea74STejun Heo if (wb != &wb->bdi->wb) 26852ebea74STejun Heo percpu_ref_get(&wb->refcnt); 26952ebea74STejun Heo } 27052ebea74STejun Heo 27152ebea74STejun Heo /** 27252ebea74STejun Heo * wb_put - decrement a wb's refcount 27352ebea74STejun Heo * @wb: bdi_writeback to put 27452ebea74STejun Heo */ 27552ebea74STejun Heo static inline void wb_put(struct bdi_writeback *wb) 27652ebea74STejun Heo { 27752ebea74STejun Heo if (wb != &wb->bdi->wb) 27852ebea74STejun Heo percpu_ref_put(&wb->refcnt); 27952ebea74STejun Heo } 28052ebea74STejun Heo 28152ebea74STejun Heo /** 28252ebea74STejun Heo * wb_find_current - find wb for %current on a bdi 28352ebea74STejun Heo * @bdi: bdi of interest 28452ebea74STejun Heo * 28552ebea74STejun Heo * Find the wb of @bdi which matches both the memcg and blkcg of %current. 28652ebea74STejun Heo * Must be called under rcu_read_lock() which protects the returend wb. 28752ebea74STejun Heo * NULL if not found. 28852ebea74STejun Heo */ 28952ebea74STejun Heo static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi) 29052ebea74STejun Heo { 29152ebea74STejun Heo struct cgroup_subsys_state *memcg_css; 29252ebea74STejun Heo struct bdi_writeback *wb; 29352ebea74STejun Heo 29452ebea74STejun Heo memcg_css = task_css(current, memory_cgrp_id); 29552ebea74STejun Heo if (!memcg_css->parent) 29652ebea74STejun Heo return &bdi->wb; 29752ebea74STejun Heo 29852ebea74STejun Heo wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id); 29952ebea74STejun Heo 30052ebea74STejun Heo /* 30152ebea74STejun Heo * %current's blkcg equals the effective blkcg of its memcg. No 30252ebea74STejun Heo * need to use the relatively expensive cgroup_get_e_css(). 30352ebea74STejun Heo */ 30452ebea74STejun Heo if (likely(wb && wb->blkcg_css == task_css(current, blkio_cgrp_id))) 30552ebea74STejun Heo return wb; 30652ebea74STejun Heo return NULL; 30752ebea74STejun Heo } 30852ebea74STejun Heo 30952ebea74STejun Heo /** 31052ebea74STejun Heo * wb_get_create_current - get or create wb for %current on a bdi 31152ebea74STejun Heo * @bdi: bdi of interest 31252ebea74STejun Heo * @gfp: allocation mask 31352ebea74STejun Heo * 31452ebea74STejun Heo * Equivalent to wb_get_create() on %current's memcg. This function is 31552ebea74STejun Heo * called from a relatively hot path and optimizes the common cases using 31652ebea74STejun Heo * wb_find_current(). 31752ebea74STejun Heo */ 31852ebea74STejun Heo static inline struct bdi_writeback * 31952ebea74STejun Heo wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp) 32052ebea74STejun Heo { 32152ebea74STejun Heo struct bdi_writeback *wb; 32252ebea74STejun Heo 32352ebea74STejun Heo rcu_read_lock(); 32452ebea74STejun Heo wb = wb_find_current(bdi); 32552ebea74STejun Heo if (wb && unlikely(!wb_tryget(wb))) 32652ebea74STejun Heo wb = NULL; 32752ebea74STejun Heo rcu_read_unlock(); 32852ebea74STejun Heo 32952ebea74STejun Heo if (unlikely(!wb)) { 33052ebea74STejun Heo struct cgroup_subsys_state *memcg_css; 33152ebea74STejun Heo 33252ebea74STejun Heo memcg_css = task_get_css(current, memory_cgrp_id); 33352ebea74STejun Heo wb = wb_get_create(bdi, memcg_css, gfp); 33452ebea74STejun Heo css_put(memcg_css); 33552ebea74STejun Heo } 33652ebea74STejun Heo return wb; 33752ebea74STejun Heo } 33852ebea74STejun Heo 33952ebea74STejun Heo /** 34052ebea74STejun Heo * inode_attach_wb - associate an inode with its wb 34152ebea74STejun Heo * @inode: inode of interest 34252ebea74STejun Heo * @page: page being dirtied (may be NULL) 34352ebea74STejun Heo * 34452ebea74STejun Heo * If @inode doesn't have its wb, associate it with the wb matching the 34552ebea74STejun Heo * memcg of @page or, if @page is NULL, %current. May be called w/ or w/o 34652ebea74STejun Heo * @inode->i_lock. 34752ebea74STejun Heo */ 34852ebea74STejun Heo static inline void inode_attach_wb(struct inode *inode, struct page *page) 34952ebea74STejun Heo { 35052ebea74STejun Heo if (!inode->i_wb) 35152ebea74STejun Heo __inode_attach_wb(inode, page); 35252ebea74STejun Heo } 35352ebea74STejun Heo 35452ebea74STejun Heo /** 35552ebea74STejun Heo * inode_detach_wb - disassociate an inode from its wb 35652ebea74STejun Heo * @inode: inode of interest 35752ebea74STejun Heo * 35852ebea74STejun Heo * @inode is being freed. Detach from its wb. 35952ebea74STejun Heo */ 36052ebea74STejun Heo static inline void inode_detach_wb(struct inode *inode) 36152ebea74STejun Heo { 36252ebea74STejun Heo if (inode->i_wb) { 36352ebea74STejun Heo wb_put(inode->i_wb); 36452ebea74STejun Heo inode->i_wb = NULL; 36552ebea74STejun Heo } 36652ebea74STejun Heo } 36752ebea74STejun Heo 36852ebea74STejun Heo /** 36952ebea74STejun Heo * inode_to_wb - determine the wb of an inode 37052ebea74STejun Heo * @inode: inode of interest 37152ebea74STejun Heo * 37252ebea74STejun Heo * Returns the wb @inode is currently associated with. 37352ebea74STejun Heo */ 37452ebea74STejun Heo static inline struct bdi_writeback *inode_to_wb(struct inode *inode) 37552ebea74STejun Heo { 37652ebea74STejun Heo return inode->i_wb; 37752ebea74STejun Heo } 37852ebea74STejun Heo 37989e9b9e0STejun Heo #else /* CONFIG_CGROUP_WRITEBACK */ 38089e9b9e0STejun Heo 38189e9b9e0STejun Heo static inline bool inode_cgwb_enabled(struct inode *inode) 38289e9b9e0STejun Heo { 38389e9b9e0STejun Heo return false; 38489e9b9e0STejun Heo } 38589e9b9e0STejun Heo 38652ebea74STejun Heo static inline struct bdi_writeback_congested * 38752ebea74STejun Heo wb_congested_get_create(struct backing_dev_info *bdi, int blkcg_id, gfp_t gfp) 38852ebea74STejun Heo { 38952ebea74STejun Heo return bdi->wb.congested; 39052ebea74STejun Heo } 39152ebea74STejun Heo 39252ebea74STejun Heo static inline void wb_congested_put(struct bdi_writeback_congested *congested) 39352ebea74STejun Heo { 39452ebea74STejun Heo } 39552ebea74STejun Heo 39652ebea74STejun Heo static inline bool wb_tryget(struct bdi_writeback *wb) 39752ebea74STejun Heo { 39852ebea74STejun Heo return true; 39952ebea74STejun Heo } 40052ebea74STejun Heo 40152ebea74STejun Heo static inline void wb_get(struct bdi_writeback *wb) 40252ebea74STejun Heo { 40352ebea74STejun Heo } 40452ebea74STejun Heo 40552ebea74STejun Heo static inline void wb_put(struct bdi_writeback *wb) 40652ebea74STejun Heo { 40752ebea74STejun Heo } 40852ebea74STejun Heo 40952ebea74STejun Heo static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi) 41052ebea74STejun Heo { 41152ebea74STejun Heo return &bdi->wb; 41252ebea74STejun Heo } 41352ebea74STejun Heo 41452ebea74STejun Heo static inline struct bdi_writeback * 41552ebea74STejun Heo wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp) 41652ebea74STejun Heo { 41752ebea74STejun Heo return &bdi->wb; 41852ebea74STejun Heo } 41952ebea74STejun Heo 42052ebea74STejun Heo static inline void inode_attach_wb(struct inode *inode, struct page *page) 42152ebea74STejun Heo { 42252ebea74STejun Heo } 42352ebea74STejun Heo 42452ebea74STejun Heo static inline void inode_detach_wb(struct inode *inode) 42552ebea74STejun Heo { 42652ebea74STejun Heo } 42752ebea74STejun Heo 42852ebea74STejun Heo static inline struct bdi_writeback *inode_to_wb(struct inode *inode) 42952ebea74STejun Heo { 43052ebea74STejun Heo return &inode_to_bdi(inode)->wb; 43152ebea74STejun Heo } 43252ebea74STejun Heo 43352ebea74STejun Heo static inline void wb_memcg_offline(struct mem_cgroup *memcg) 43452ebea74STejun Heo { 43552ebea74STejun Heo } 43652ebea74STejun Heo 43752ebea74STejun Heo static inline void wb_blkcg_offline(struct blkcg *blkcg) 43852ebea74STejun Heo { 43952ebea74STejun Heo } 44052ebea74STejun Heo 44189e9b9e0STejun Heo #endif /* CONFIG_CGROUP_WRITEBACK */ 44289e9b9e0STejun Heo 443*ec8a6f26STejun Heo static inline int bdi_congested(struct backing_dev_info *bdi, int cong_bits) 444*ec8a6f26STejun Heo { 445*ec8a6f26STejun Heo return wb_congested(&bdi->wb, cong_bits); 446*ec8a6f26STejun Heo } 447*ec8a6f26STejun Heo 448*ec8a6f26STejun Heo static inline int bdi_read_congested(struct backing_dev_info *bdi) 449*ec8a6f26STejun Heo { 450*ec8a6f26STejun Heo return bdi_congested(bdi, 1 << WB_sync_congested); 451*ec8a6f26STejun Heo } 452*ec8a6f26STejun Heo 453*ec8a6f26STejun Heo static inline int bdi_write_congested(struct backing_dev_info *bdi) 454*ec8a6f26STejun Heo { 455*ec8a6f26STejun Heo return bdi_congested(bdi, 1 << WB_async_congested); 456*ec8a6f26STejun Heo } 457*ec8a6f26STejun Heo 458*ec8a6f26STejun Heo static inline int bdi_rw_congested(struct backing_dev_info *bdi) 459*ec8a6f26STejun Heo { 460*ec8a6f26STejun Heo return bdi_congested(bdi, (1 << WB_sync_congested) | 461*ec8a6f26STejun Heo (1 << WB_async_congested)); 462*ec8a6f26STejun Heo } 463*ec8a6f26STejun Heo 4641da177e4SLinus Torvalds #endif /* _LINUX_BACKING_DEV_H */ 465