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