#include <linux/blkdev.h>
#include <linux/wait.h>
#include <linux/rbtree.h>
#include <linux/kthread.h>
#include <linux/backing-dev.h>
#include <linux/blk-cgroup.h>
#include <linux/freezer.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/mm.h>
#include <linux/sched/mm.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/writeback.h>
#include <linux/device.h>
#include <trace/events/writeback.h>
#include "internal.h"
struct backing_dev_info noop_backing_dev_info;
EXPORT_SYMBOL_GPL(…);
static const char *bdi_unknown_name = …;
DEFINE_SPINLOCK(…);
static u64 bdi_id_cursor;
static struct rb_root bdi_tree = …;
LIST_HEAD(…);
struct workqueue_struct *bdi_wq;
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
struct wb_stats { … };
static struct dentry *bdi_debug_root;
static void bdi_debug_init(void)
{ … }
static void collect_wb_stats(struct wb_stats *stats,
struct bdi_writeback *wb)
{ … }
#ifdef CONFIG_CGROUP_WRITEBACK
static void bdi_collect_stats(struct backing_dev_info *bdi,
struct wb_stats *stats)
{ … }
#else
static void bdi_collect_stats(struct backing_dev_info *bdi,
struct wb_stats *stats)
{
collect_wb_stats(stats, &bdi->wb);
}
#endif
static int bdi_debug_stats_show(struct seq_file *m, void *v)
{ … }
DEFINE_SHOW_ATTRIBUTE(…);
static void wb_stats_show(struct seq_file *m, struct bdi_writeback *wb,
struct wb_stats *stats)
{ … }
static int cgwb_debug_stats_show(struct seq_file *m, void *v)
{ … }
DEFINE_SHOW_ATTRIBUTE(…);
static void bdi_debug_register(struct backing_dev_info *bdi, const char *name)
{ … }
static void bdi_debug_unregister(struct backing_dev_info *bdi)
{ … }
#else
static inline void bdi_debug_init(void)
{
}
static inline void bdi_debug_register(struct backing_dev_info *bdi,
const char *name)
{
}
static inline void bdi_debug_unregister(struct backing_dev_info *bdi)
{
}
#endif
static ssize_t read_ahead_kb_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{ … }
#define BDI_SHOW(name, expr) …
BDI_SHOW(…)
static ssize_t min_ratio_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
BDI_SHOW(…) …
static ssize_t min_ratio_fine_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
BDI_SHOW(…)
static ssize_t max_ratio_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
BDI_SHOW(…) …
static ssize_t max_ratio_fine_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
BDI_SHOW(…)
static ssize_t min_bytes_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t min_bytes_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
static DEVICE_ATTR_RW(min_bytes);
static ssize_t max_bytes_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static ssize_t max_bytes_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
static DEVICE_ATTR_RW(max_bytes);
static ssize_t stable_pages_required_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{ … }
static DEVICE_ATTR_RO(stable_pages_required);
static ssize_t strict_limit_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{ … }
static ssize_t strict_limit_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR_RW(strict_limit);
static struct attribute *bdi_dev_attrs[] = …;
ATTRIBUTE_GROUPS(…);
static const struct class bdi_class = …;
static __init int bdi_class_init(void)
{ … }
postcore_initcall(bdi_class_init);
static int __init default_bdi_init(void)
{ … }
subsys_initcall(default_bdi_init);
static void wb_update_bandwidth_workfn(struct work_struct *work)
{ … }
#define INIT_BW …
static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi,
gfp_t gfp)
{ … }
static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb);
static void wb_shutdown(struct bdi_writeback *wb)
{ … }
static void wb_exit(struct bdi_writeback *wb)
{ … }
#ifdef CONFIG_CGROUP_WRITEBACK
#include <linux/memcontrol.h>
static DEFINE_SPINLOCK(cgwb_lock);
static struct workqueue_struct *cgwb_release_wq;
static LIST_HEAD(offline_cgwbs);
static void cleanup_offline_cgwbs_workfn(struct work_struct *work);
static DECLARE_WORK(cleanup_offline_cgwbs_work, cleanup_offline_cgwbs_workfn);
static void cgwb_free_rcu(struct rcu_head *rcu_head)
{ … }
static void cgwb_release_workfn(struct work_struct *work)
{ … }
static void cgwb_release(struct percpu_ref *refcnt)
{ … }
static void cgwb_kill(struct bdi_writeback *wb)
{ … }
static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
{ … }
static int cgwb_create(struct backing_dev_info *bdi,
struct cgroup_subsys_state *memcg_css, gfp_t gfp)
{ … }
struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
struct cgroup_subsys_state *memcg_css)
{ … }
struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
struct cgroup_subsys_state *memcg_css,
gfp_t gfp)
{ … }
static int cgwb_bdi_init(struct backing_dev_info *bdi)
{ … }
static void cgwb_bdi_unregister(struct backing_dev_info *bdi)
{ … }
static void cleanup_offline_cgwbs_workfn(struct work_struct *work)
{ … }
void wb_memcg_offline(struct mem_cgroup *memcg)
{ … }
void wb_blkcg_offline(struct cgroup_subsys_state *css)
{ … }
static void cgwb_bdi_register(struct backing_dev_info *bdi)
{ … }
static int __init cgwb_init(void)
{ … }
subsys_initcall(cgwb_init);
#else
static int cgwb_bdi_init(struct backing_dev_info *bdi)
{
return wb_init(&bdi->wb, bdi, GFP_KERNEL);
}
static void cgwb_bdi_unregister(struct backing_dev_info *bdi) { }
static void cgwb_bdi_register(struct backing_dev_info *bdi)
{
list_add_tail_rcu(&bdi->wb.bdi_node, &bdi->wb_list);
}
static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
{
list_del_rcu(&wb->bdi_node);
}
#endif
int bdi_init(struct backing_dev_info *bdi)
{ … }
struct backing_dev_info *bdi_alloc(int node_id)
{ … }
EXPORT_SYMBOL(…);
static struct rb_node **bdi_lookup_rb_node(u64 id, struct rb_node **parentp)
{ … }
struct backing_dev_info *bdi_get_by_id(u64 id)
{ … }
int bdi_register_va(struct backing_dev_info *bdi, const char *fmt, va_list args)
{ … }
int bdi_register(struct backing_dev_info *bdi, const char *fmt, ...)
{ … }
EXPORT_SYMBOL(…);
void bdi_set_owner(struct backing_dev_info *bdi, struct device *owner)
{ … }
static void bdi_remove_from_list(struct backing_dev_info *bdi)
{ … }
void bdi_unregister(struct backing_dev_info *bdi)
{ … }
EXPORT_SYMBOL(…);
static void release_bdi(struct kref *ref)
{ … }
void bdi_put(struct backing_dev_info *bdi)
{ … }
EXPORT_SYMBOL(…);
struct backing_dev_info *inode_to_bdi(struct inode *inode)
{ … }
EXPORT_SYMBOL(…);
const char *bdi_dev_name(struct backing_dev_info *bdi)
{ … }
EXPORT_SYMBOL_GPL(…);