diff options
author | Tejun Heo <tj@kernel.org> | 2017-12-12 08:38:30 -0800 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-01-22 14:39:38 -0700 |
commit | 7fc5854f8c6efae9e7624970ab49a1eac2faefb1 (patch) | |
tree | 7c9ac9ab43c0a47dbaefd155da89c8ba7f7923db /include/linux/backing-dev-defs.h | |
parent | 698cef173983b086977e633e46476e0f925ca01e (diff) | |
download | lwn-7fc5854f8c6efae9e7624970ab49a1eac2faefb1.tar.gz lwn-7fc5854f8c6efae9e7624970ab49a1eac2faefb1.zip |
writeback: synchronize sync(2) against cgroup writeback membership switches
sync_inodes_sb() can race against cgwb (cgroup writeback) membership
switches and fail to writeback some inodes. For example, if an inode
switches to another wb while sync_inodes_sb() is in progress, the new
wb might not be visible to bdi_split_work_to_wbs() at all or the inode
might jump from a wb which hasn't issued writebacks yet to one which
already has.
This patch adds backing_dev_info->wb_switch_rwsem to synchronize cgwb
switch path against sync_inodes_sb() so that sync_inodes_sb() is
guaranteed to see all the target wbs and inodes can't jump wbs to
escape syncing.
v2: Fixed misplaced rwsem init. Spotted by Jiufei.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Jiufei Xue <xuejiufei@gmail.com>
Link: http://lkml.kernel.org/r/dc694ae2-f07f-61e1-7097-7c8411cee12d@gmail.com
Acked-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/linux/backing-dev-defs.h')
-rw-r--r-- | include/linux/backing-dev-defs.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index c31157135598..07e02d6df5ad 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -190,6 +190,7 @@ struct backing_dev_info { struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */ struct rb_root cgwb_congested_tree; /* their congested states */ struct mutex cgwb_release_mutex; /* protect shutdown of wb structs */ + struct rw_semaphore wb_switch_rwsem; /* no cgwb switch while syncing */ #else struct bdi_writeback_congested *wb_congested; #endif |