init: Initialize noop_backing_dev_info early
[ Upstream commit4bca7e80b6
] noop_backing_dev_info is used by superblocks of various pseudofilesystems such as kdevtmpfs. After commit10e1407310
("writeback: Fix inode->i_io_list not be protected by inode->i_lock error") this broke because __mark_inode_dirty() started to access more fields from noop_backing_dev_info and this led to crashes inside locked_inode_to_wb_and_lock_list() called from __mark_inode_dirty(). Fix the problem by initializing noop_backing_dev_info before the filesystems get mounted. Fixes:10e1407310
("writeback: Fix inode->i_io_list not be protected by inode->i_lock error") Reported-and-tested-by: Suzuki K Poulose <suzuki.poulose@arm.com> Reported-and-tested-by: Alexandru Elisei <alexandru.elisei@arm.com> Reported-and-tested-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
04cdec4186
Коммит
ca67881dce
|
@ -8,6 +8,7 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
|
#include <linux/backing-dev.h>
|
||||||
|
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
void __init driver_init(void)
|
void __init driver_init(void)
|
||||||
{
|
{
|
||||||
/* These are the core pieces */
|
/* These are the core pieces */
|
||||||
|
bdi_init(&noop_backing_dev_info);
|
||||||
devtmpfs_init();
|
devtmpfs_init();
|
||||||
devices_init();
|
devices_init();
|
||||||
buses_init();
|
buses_init();
|
||||||
|
|
|
@ -121,6 +121,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
|
||||||
|
|
||||||
extern struct backing_dev_info noop_backing_dev_info;
|
extern struct backing_dev_info noop_backing_dev_info;
|
||||||
|
|
||||||
|
int bdi_init(struct backing_dev_info *bdi);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* writeback_in_progress - determine whether there is writeback in progress
|
* writeback_in_progress - determine whether there is writeback in progress
|
||||||
* @wb: bdi_writeback of interest
|
* @wb: bdi_writeback of interest
|
||||||
|
|
|
@ -229,20 +229,13 @@ static __init int bdi_class_init(void)
|
||||||
}
|
}
|
||||||
postcore_initcall(bdi_class_init);
|
postcore_initcall(bdi_class_init);
|
||||||
|
|
||||||
static int bdi_init(struct backing_dev_info *bdi);
|
|
||||||
|
|
||||||
static int __init default_bdi_init(void)
|
static int __init default_bdi_init(void)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
|
|
||||||
bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND |
|
bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND |
|
||||||
WQ_SYSFS, 0);
|
WQ_SYSFS, 0);
|
||||||
if (!bdi_wq)
|
if (!bdi_wq)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
return 0;
|
||||||
err = bdi_init(&noop_backing_dev_info);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
subsys_initcall(default_bdi_init);
|
subsys_initcall(default_bdi_init);
|
||||||
|
|
||||||
|
@ -784,7 +777,7 @@ static void cgwb_remove_from_bdi_list(struct bdi_writeback *wb)
|
||||||
|
|
||||||
#endif /* CONFIG_CGROUP_WRITEBACK */
|
#endif /* CONFIG_CGROUP_WRITEBACK */
|
||||||
|
|
||||||
static int bdi_init(struct backing_dev_info *bdi)
|
int bdi_init(struct backing_dev_info *bdi)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче