Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

init: Initialize noop_backing_dev_info early

noop_backing_dev_info is used by superblocks of various
pseudofilesystems such as kdevtmpfs. After commit 10e14073107d
("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: 10e14073107d ("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>

Jan Kara 4bca7e80 27cfa258

+6 -9
+2
drivers/base/init.c
··· 8 8 #include <linux/init.h> 9 9 #include <linux/memory.h> 10 10 #include <linux/of.h> 11 + #include <linux/backing-dev.h> 11 12 12 13 #include "base.h" 13 14 ··· 21 20 void __init driver_init(void) 22 21 { 23 22 /* These are the core pieces */ 23 + bdi_init(&noop_backing_dev_info); 24 24 devtmpfs_init(); 25 25 devices_init(); 26 26 buses_init();
+2
include/linux/backing-dev.h
··· 119 119 120 120 extern struct backing_dev_info noop_backing_dev_info; 121 121 122 + int bdi_init(struct backing_dev_info *bdi); 123 + 122 124 /** 123 125 * writeback_in_progress - determine whether there is writeback in progress 124 126 * @wb: bdi_writeback of interest
+2 -9
mm/backing-dev.c
··· 231 231 } 232 232 postcore_initcall(bdi_class_init); 233 233 234 - static int bdi_init(struct backing_dev_info *bdi); 235 - 236 234 static int __init default_bdi_init(void) 237 235 { 238 - int err; 239 - 240 236 bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND | 241 237 WQ_SYSFS, 0); 242 238 if (!bdi_wq) 243 239 return -ENOMEM; 244 - 245 - err = bdi_init(&noop_backing_dev_info); 246 - 247 - return err; 240 + return 0; 248 241 } 249 242 subsys_initcall(default_bdi_init); 250 243 ··· 774 781 775 782 #endif /* CONFIG_CGROUP_WRITEBACK */ 776 783 777 - static int bdi_init(struct backing_dev_info *bdi) 784 + int bdi_init(struct backing_dev_info *bdi) 778 785 { 779 786 int ret; 780 787