18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * include/linux/backing-dev.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * low-level device information and state which is propagated up through 68c2ecf20Sopenharmony_ci * to high-level code. 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifndef _LINUX_BACKING_DEV_H 108c2ecf20Sopenharmony_ci#define _LINUX_BACKING_DEV_H 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/fs.h> 148c2ecf20Sopenharmony_ci#include <linux/sched.h> 158c2ecf20Sopenharmony_ci#include <linux/blkdev.h> 168c2ecf20Sopenharmony_ci#include <linux/device.h> 178c2ecf20Sopenharmony_ci#include <linux/writeback.h> 188c2ecf20Sopenharmony_ci#include <linux/blk-cgroup.h> 198c2ecf20Sopenharmony_ci#include <linux/backing-dev-defs.h> 208c2ecf20Sopenharmony_ci#include <linux/slab.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic inline struct backing_dev_info *bdi_get(struct backing_dev_info *bdi) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci kref_get(&bdi->refcnt); 258c2ecf20Sopenharmony_ci return bdi; 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistruct backing_dev_info *bdi_get_by_id(u64 id); 298c2ecf20Sopenharmony_civoid bdi_put(struct backing_dev_info *bdi); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci__printf(2, 3) 328c2ecf20Sopenharmony_ciint bdi_register(struct backing_dev_info *bdi, const char *fmt, ...); 338c2ecf20Sopenharmony_ci__printf(2, 0) 348c2ecf20Sopenharmony_ciint bdi_register_va(struct backing_dev_info *bdi, const char *fmt, 358c2ecf20Sopenharmony_ci va_list args); 368c2ecf20Sopenharmony_civoid bdi_set_owner(struct backing_dev_info *bdi, struct device *owner); 378c2ecf20Sopenharmony_civoid bdi_unregister(struct backing_dev_info *bdi); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistruct backing_dev_info *bdi_alloc(int node_id); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_civoid wb_start_background_writeback(struct bdi_writeback *wb); 428c2ecf20Sopenharmony_civoid wb_workfn(struct work_struct *work); 438c2ecf20Sopenharmony_civoid wb_wakeup_delayed(struct bdi_writeback *wb); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_civoid wb_wait_for_completion(struct wb_completion *done); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ciextern spinlock_t bdi_lock; 488c2ecf20Sopenharmony_ciextern struct list_head bdi_list; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciextern struct workqueue_struct *bdi_wq; 518c2ecf20Sopenharmony_ciextern struct workqueue_struct *bdi_async_bio_wq; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic inline bool wb_has_dirty_io(struct bdi_writeback *wb) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci return test_bit(WB_has_dirty_io, &wb->state); 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic inline bool bdi_has_dirty_io(struct backing_dev_info *bdi) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci /* 618c2ecf20Sopenharmony_ci * @bdi->tot_write_bandwidth is guaranteed to be > 0 if there are 628c2ecf20Sopenharmony_ci * any dirty wbs. See wb_update_write_bandwidth(). 638c2ecf20Sopenharmony_ci */ 648c2ecf20Sopenharmony_ci return atomic_long_read(&bdi->tot_write_bandwidth); 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic inline void __add_wb_stat(struct bdi_writeback *wb, 688c2ecf20Sopenharmony_ci enum wb_stat_item item, s64 amount) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci percpu_counter_add_batch(&wb->stat[item], amount, WB_STAT_BATCH); 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci __add_wb_stat(wb, item, 1); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci __add_wb_stat(wb, item, -1); 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci return percpu_counter_read_positive(&wb->stat[item]); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci return percpu_counter_sum_positive(&wb->stat[item]); 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ciextern void wb_writeout_inc(struct bdi_writeback *wb); 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci/* 968c2ecf20Sopenharmony_ci * maximal error of a stat counter. 978c2ecf20Sopenharmony_ci */ 988c2ecf20Sopenharmony_cistatic inline unsigned long wb_stat_error(void) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1018c2ecf20Sopenharmony_ci return nr_cpu_ids * WB_STAT_BATCH; 1028c2ecf20Sopenharmony_ci#else 1038c2ecf20Sopenharmony_ci return 1; 1048c2ecf20Sopenharmony_ci#endif 1058c2ecf20Sopenharmony_ci} 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ciint bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio); 1088c2ecf20Sopenharmony_ciint bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci/* 1118c2ecf20Sopenharmony_ci * Flags in backing_dev_info::capability 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * BDI_CAP_WRITEBACK: Supports dirty page writeback, and dirty pages 1148c2ecf20Sopenharmony_ci * should contribute to accounting 1158c2ecf20Sopenharmony_ci * BDI_CAP_WRITEBACK_ACCT: Automatically account writeback pages 1168c2ecf20Sopenharmony_ci * BDI_CAP_STRICTLIMIT: Keep number of dirty pages below bdi threshold 1178c2ecf20Sopenharmony_ci */ 1188c2ecf20Sopenharmony_ci#define BDI_CAP_WRITEBACK (1 << 0) 1198c2ecf20Sopenharmony_ci#define BDI_CAP_WRITEBACK_ACCT (1 << 1) 1208c2ecf20Sopenharmony_ci#define BDI_CAP_STRICTLIMIT (1 << 2) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ciextern struct backing_dev_info noop_backing_dev_info; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/** 1258c2ecf20Sopenharmony_ci * writeback_in_progress - determine whether there is writeback in progress 1268c2ecf20Sopenharmony_ci * @wb: bdi_writeback of interest 1278c2ecf20Sopenharmony_ci * 1288c2ecf20Sopenharmony_ci * Determine whether there is writeback waiting to be handled against a 1298c2ecf20Sopenharmony_ci * bdi_writeback. 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_cistatic inline bool writeback_in_progress(struct bdi_writeback *wb) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci return test_bit(WB_writeback_running, &wb->state); 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic inline struct backing_dev_info *inode_to_bdi(struct inode *inode) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci struct super_block *sb; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci if (!inode) 1418c2ecf20Sopenharmony_ci return &noop_backing_dev_info; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci sb = inode->i_sb; 1448c2ecf20Sopenharmony_ci#ifdef CONFIG_BLOCK 1458c2ecf20Sopenharmony_ci if (sb_is_blkdev_sb(sb)) 1468c2ecf20Sopenharmony_ci return I_BDEV(inode)->bd_bdi; 1478c2ecf20Sopenharmony_ci#endif 1488c2ecf20Sopenharmony_ci return sb->s_bdi; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic inline int wb_congested(struct bdi_writeback *wb, int cong_bits) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci return wb->congested & cong_bits; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cilong congestion_wait(int sync, long timeout); 1578c2ecf20Sopenharmony_cilong wait_iff_congested(int sync, long timeout); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic inline bool mapping_can_writeback(struct address_space *mapping) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci return inode_to_bdi(mapping->host)->capabilities & BDI_CAP_WRITEBACK; 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic inline int bdi_sched_wait(void *word) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci schedule(); 1678c2ecf20Sopenharmony_ci return 0; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#ifdef CONFIG_CGROUP_WRITEBACK 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistruct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi, 1738c2ecf20Sopenharmony_ci struct cgroup_subsys_state *memcg_css); 1748c2ecf20Sopenharmony_cistruct bdi_writeback *wb_get_create(struct backing_dev_info *bdi, 1758c2ecf20Sopenharmony_ci struct cgroup_subsys_state *memcg_css, 1768c2ecf20Sopenharmony_ci gfp_t gfp); 1778c2ecf20Sopenharmony_civoid wb_memcg_offline(struct mem_cgroup *memcg); 1788c2ecf20Sopenharmony_civoid wb_blkcg_offline(struct blkcg *blkcg); 1798c2ecf20Sopenharmony_ciint inode_congested(struct inode *inode, int cong_bits); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci/** 1828c2ecf20Sopenharmony_ci * inode_cgwb_enabled - test whether cgroup writeback is enabled on an inode 1838c2ecf20Sopenharmony_ci * @inode: inode of interest 1848c2ecf20Sopenharmony_ci * 1858c2ecf20Sopenharmony_ci * Cgroup writeback requires support from the filesystem. Also, both memcg and 1868c2ecf20Sopenharmony_ci * iocg have to be on the default hierarchy. Test whether all conditions are 1878c2ecf20Sopenharmony_ci * met. 1888c2ecf20Sopenharmony_ci * 1898c2ecf20Sopenharmony_ci * Note that the test result may change dynamically on the same inode 1908c2ecf20Sopenharmony_ci * depending on how memcg and iocg are configured. 1918c2ecf20Sopenharmony_ci */ 1928c2ecf20Sopenharmony_cistatic inline bool inode_cgwb_enabled(struct inode *inode) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci struct backing_dev_info *bdi = inode_to_bdi(inode); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci return cgroup_subsys_on_dfl(memory_cgrp_subsys) && 1978c2ecf20Sopenharmony_ci cgroup_subsys_on_dfl(io_cgrp_subsys) && 1988c2ecf20Sopenharmony_ci (bdi->capabilities & BDI_CAP_WRITEBACK) && 1998c2ecf20Sopenharmony_ci (inode->i_sb->s_iflags & SB_I_CGROUPWB); 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci/** 2038c2ecf20Sopenharmony_ci * wb_find_current - find wb for %current on a bdi 2048c2ecf20Sopenharmony_ci * @bdi: bdi of interest 2058c2ecf20Sopenharmony_ci * 2068c2ecf20Sopenharmony_ci * Find the wb of @bdi which matches both the memcg and blkcg of %current. 2078c2ecf20Sopenharmony_ci * Must be called under rcu_read_lock() which protects the returend wb. 2088c2ecf20Sopenharmony_ci * NULL if not found. 2098c2ecf20Sopenharmony_ci */ 2108c2ecf20Sopenharmony_cistatic inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci struct cgroup_subsys_state *memcg_css; 2138c2ecf20Sopenharmony_ci struct bdi_writeback *wb; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci memcg_css = task_css(current, memory_cgrp_id); 2168c2ecf20Sopenharmony_ci if (!memcg_css->parent) 2178c2ecf20Sopenharmony_ci return &bdi->wb; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci /* 2228c2ecf20Sopenharmony_ci * %current's blkcg equals the effective blkcg of its memcg. No 2238c2ecf20Sopenharmony_ci * need to use the relatively expensive cgroup_get_e_css(). 2248c2ecf20Sopenharmony_ci */ 2258c2ecf20Sopenharmony_ci if (likely(wb && wb->blkcg_css == task_css(current, io_cgrp_id))) 2268c2ecf20Sopenharmony_ci return wb; 2278c2ecf20Sopenharmony_ci return NULL; 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci/** 2318c2ecf20Sopenharmony_ci * wb_get_create_current - get or create wb for %current on a bdi 2328c2ecf20Sopenharmony_ci * @bdi: bdi of interest 2338c2ecf20Sopenharmony_ci * @gfp: allocation mask 2348c2ecf20Sopenharmony_ci * 2358c2ecf20Sopenharmony_ci * Equivalent to wb_get_create() on %current's memcg. This function is 2368c2ecf20Sopenharmony_ci * called from a relatively hot path and optimizes the common cases using 2378c2ecf20Sopenharmony_ci * wb_find_current(). 2388c2ecf20Sopenharmony_ci */ 2398c2ecf20Sopenharmony_cistatic inline struct bdi_writeback * 2408c2ecf20Sopenharmony_ciwb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci struct bdi_writeback *wb; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci rcu_read_lock(); 2458c2ecf20Sopenharmony_ci wb = wb_find_current(bdi); 2468c2ecf20Sopenharmony_ci if (wb && unlikely(!wb_tryget(wb))) 2478c2ecf20Sopenharmony_ci wb = NULL; 2488c2ecf20Sopenharmony_ci rcu_read_unlock(); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci if (unlikely(!wb)) { 2518c2ecf20Sopenharmony_ci struct cgroup_subsys_state *memcg_css; 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci memcg_css = task_get_css(current, memory_cgrp_id); 2548c2ecf20Sopenharmony_ci wb = wb_get_create(bdi, memcg_css, gfp); 2558c2ecf20Sopenharmony_ci css_put(memcg_css); 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci return wb; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci/** 2618c2ecf20Sopenharmony_ci * inode_to_wb_is_valid - test whether an inode has a wb associated 2628c2ecf20Sopenharmony_ci * @inode: inode of interest 2638c2ecf20Sopenharmony_ci * 2648c2ecf20Sopenharmony_ci * Returns %true if @inode has a wb associated. May be called without any 2658c2ecf20Sopenharmony_ci * locking. 2668c2ecf20Sopenharmony_ci */ 2678c2ecf20Sopenharmony_cistatic inline bool inode_to_wb_is_valid(struct inode *inode) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci return inode->i_wb; 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci/** 2738c2ecf20Sopenharmony_ci * inode_to_wb - determine the wb of an inode 2748c2ecf20Sopenharmony_ci * @inode: inode of interest 2758c2ecf20Sopenharmony_ci * 2768c2ecf20Sopenharmony_ci * Returns the wb @inode is currently associated with. The caller must be 2778c2ecf20Sopenharmony_ci * holding either @inode->i_lock, the i_pages lock, or the 2788c2ecf20Sopenharmony_ci * associated wb's list_lock. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_cistatic inline struct bdi_writeback *inode_to_wb(const struct inode *inode) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci#ifdef CONFIG_LOCKDEP 2838c2ecf20Sopenharmony_ci WARN_ON_ONCE(debug_locks && 2848c2ecf20Sopenharmony_ci (!lockdep_is_held(&inode->i_lock) && 2858c2ecf20Sopenharmony_ci !lockdep_is_held(&inode->i_mapping->i_pages.xa_lock) && 2868c2ecf20Sopenharmony_ci !lockdep_is_held(&inode->i_wb->list_lock))); 2878c2ecf20Sopenharmony_ci#endif 2888c2ecf20Sopenharmony_ci return inode->i_wb; 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci/** 2928c2ecf20Sopenharmony_ci * unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction 2938c2ecf20Sopenharmony_ci * @inode: target inode 2948c2ecf20Sopenharmony_ci * @cookie: output param, to be passed to the end function 2958c2ecf20Sopenharmony_ci * 2968c2ecf20Sopenharmony_ci * The caller wants to access the wb associated with @inode but isn't 2978c2ecf20Sopenharmony_ci * holding inode->i_lock, the i_pages lock or wb->list_lock. This 2988c2ecf20Sopenharmony_ci * function determines the wb associated with @inode and ensures that the 2998c2ecf20Sopenharmony_ci * association doesn't change until the transaction is finished with 3008c2ecf20Sopenharmony_ci * unlocked_inode_to_wb_end(). 3018c2ecf20Sopenharmony_ci * 3028c2ecf20Sopenharmony_ci * The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and 3038c2ecf20Sopenharmony_ci * can't sleep during the transaction. IRQs may or may not be disabled on 3048c2ecf20Sopenharmony_ci * return. 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_cistatic inline struct bdi_writeback * 3078c2ecf20Sopenharmony_ciunlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) 3088c2ecf20Sopenharmony_ci{ 3098c2ecf20Sopenharmony_ci rcu_read_lock(); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci /* 3128c2ecf20Sopenharmony_ci * Paired with store_release in inode_switch_wbs_work_fn() and 3138c2ecf20Sopenharmony_ci * ensures that we see the new wb if we see cleared I_WB_SWITCH. 3148c2ecf20Sopenharmony_ci */ 3158c2ecf20Sopenharmony_ci cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci if (unlikely(cookie->locked)) 3188c2ecf20Sopenharmony_ci xa_lock_irqsave(&inode->i_mapping->i_pages, cookie->flags); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci /* 3218c2ecf20Sopenharmony_ci * Protected by either !I_WB_SWITCH + rcu_read_lock() or the i_pages 3228c2ecf20Sopenharmony_ci * lock. inode_to_wb() will bark. Deref directly. 3238c2ecf20Sopenharmony_ci */ 3248c2ecf20Sopenharmony_ci return inode->i_wb; 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci/** 3288c2ecf20Sopenharmony_ci * unlocked_inode_to_wb_end - end inode wb access transaction 3298c2ecf20Sopenharmony_ci * @inode: target inode 3308c2ecf20Sopenharmony_ci * @cookie: @cookie from unlocked_inode_to_wb_begin() 3318c2ecf20Sopenharmony_ci */ 3328c2ecf20Sopenharmony_cistatic inline void unlocked_inode_to_wb_end(struct inode *inode, 3338c2ecf20Sopenharmony_ci struct wb_lock_cookie *cookie) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci if (unlikely(cookie->locked)) 3368c2ecf20Sopenharmony_ci xa_unlock_irqrestore(&inode->i_mapping->i_pages, cookie->flags); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci rcu_read_unlock(); 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci#else /* CONFIG_CGROUP_WRITEBACK */ 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic inline bool inode_cgwb_enabled(struct inode *inode) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci return false; 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci return &bdi->wb; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_cistatic inline struct bdi_writeback * 3548c2ecf20Sopenharmony_ciwb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci return &bdi->wb; 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic inline bool inode_to_wb_is_valid(struct inode *inode) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci return true; 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_cistatic inline struct bdi_writeback *inode_to_wb(struct inode *inode) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci return &inode_to_bdi(inode)->wb; 3678c2ecf20Sopenharmony_ci} 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_cistatic inline struct bdi_writeback * 3708c2ecf20Sopenharmony_ciunlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci return inode_to_wb(inode); 3738c2ecf20Sopenharmony_ci} 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cistatic inline void unlocked_inode_to_wb_end(struct inode *inode, 3768c2ecf20Sopenharmony_ci struct wb_lock_cookie *cookie) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci} 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_cistatic inline void wb_memcg_offline(struct mem_cgroup *memcg) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci} 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_cistatic inline void wb_blkcg_offline(struct blkcg *blkcg) 3858c2ecf20Sopenharmony_ci{ 3868c2ecf20Sopenharmony_ci} 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_cistatic inline int inode_congested(struct inode *inode, int cong_bits) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci return wb_congested(&inode_to_bdi(inode)->wb, cong_bits); 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci#endif /* CONFIG_CGROUP_WRITEBACK */ 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_cistatic inline int inode_read_congested(struct inode *inode) 3968c2ecf20Sopenharmony_ci{ 3978c2ecf20Sopenharmony_ci return inode_congested(inode, 1 << WB_sync_congested); 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistatic inline int inode_write_congested(struct inode *inode) 4018c2ecf20Sopenharmony_ci{ 4028c2ecf20Sopenharmony_ci return inode_congested(inode, 1 << WB_async_congested); 4038c2ecf20Sopenharmony_ci} 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_cistatic inline int inode_rw_congested(struct inode *inode) 4068c2ecf20Sopenharmony_ci{ 4078c2ecf20Sopenharmony_ci return inode_congested(inode, (1 << WB_sync_congested) | 4088c2ecf20Sopenharmony_ci (1 << WB_async_congested)); 4098c2ecf20Sopenharmony_ci} 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_cistatic inline int bdi_congested(struct backing_dev_info *bdi, int cong_bits) 4128c2ecf20Sopenharmony_ci{ 4138c2ecf20Sopenharmony_ci return wb_congested(&bdi->wb, cong_bits); 4148c2ecf20Sopenharmony_ci} 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_cistatic inline int bdi_read_congested(struct backing_dev_info *bdi) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci return bdi_congested(bdi, 1 << WB_sync_congested); 4198c2ecf20Sopenharmony_ci} 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_cistatic inline int bdi_write_congested(struct backing_dev_info *bdi) 4228c2ecf20Sopenharmony_ci{ 4238c2ecf20Sopenharmony_ci return bdi_congested(bdi, 1 << WB_async_congested); 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_cistatic inline int bdi_rw_congested(struct backing_dev_info *bdi) 4278c2ecf20Sopenharmony_ci{ 4288c2ecf20Sopenharmony_ci return bdi_congested(bdi, (1 << WB_sync_congested) | 4298c2ecf20Sopenharmony_ci (1 << WB_async_congested)); 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ciconst char *bdi_dev_name(struct backing_dev_info *bdi); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci#endif /* _LINUX_BACKING_DEV_H */ 435