vfs: re-implement writeback_inodes_sb(_nr)_if_idle() and rename them
Subsystems (4)
PATCH 1/2 vfs: re-implement writeback_inodes_sb(_nr)_if_idle() and rename them
writeback_inodes_sb(_nr)_if_idle() is re-implemented by replacing down_read() with down_read_trylock() because
- If ->s_umount is write locked, then the sb is not idle. That is writeback_inodes_sb(_nr)_if_idle() needn't wait for the lock.
- writeback_inodes_sb(_nr)_if_idle() grabs s_umount lock when it want to start writeback, it may bring us deadlock problem when doing umount. (Ex. Btrfs has such a problem, see the following URL
http://marc.info/?l=linux-btrfs&m=133540923510561&w=2)
The name of these two functions is cumbersome, so rename them to try_to_writeback_inodes_sb(_nr).
This idea came from Christoph Hellwig.
Some code is from the patch of Kamal Mostafa.
Signed-off-by Miao Xie <[email protected]>
--- fs/btrfs/extent-tree.c | 4 ++-- fs/ext4/inode.c | 2 +- fs/fs-writeback.c | 45 ++++++++++++++++++++------------------------- include/linux/writeback.h | 6 +++--- 4 files changed, 26 insertions(+), 31 deletions(-)
fs/btrfs/extent-tree.c +2 -2
@@ -3624,8 +3624,8 @@ static int shrink_delalloc(struct btrfs_root *root, u64 to_reclaim,smp_mb (); nr_pages = min_t(unsigned long, nr_pages, root->fs_info->delalloc_bytes >>PAGE_CACHE_SHIFT ); -writeback_inodes_sb_nr_if_idle (root->fs_info->sb, nr_pages, -WB_REASON_FS_FREE_SPACE ); +try_to_writeback_inodes_sb_nr (root->fs_info->sb, nr_pages, +WB_REASON_FS_FREE_SPACE );spin_lock (&space_info->lock);if (reserved > space_info->bytes_may_use)
fs/ext4/inode.c +1 -1
@@ -2380,7 +2380,7 @@ static int ext4_nonda_switch(struct super_block *sb)* start pushing delalloc when 1/2 of free blocks are dirty. */ if (free_blocks <2 * dirty_blocks) -writeback_inodes_sb_if_idle (sb,WB_REASON_FS_FREE_SPACE ); +try_to_writeback_inodes_sb (sb,WB_REASON_FS_FREE_SPACE );return 0 ; }
fs/fs-writeback.c +20 -25
74 lines not on this page · raw message
include/linux/writeback.h +3 -3
@@ -86,9 +86,9 @@ int inode_wait(void *);void writeback_inodes_sb (struct super_block *,enum wb_reason reason);void writeback_inodes_sb_nr (struct super_block *,unsigned long nr,enum wb_reason reason); -int writeback_inodes_sb_if_idle (struct super_block *,enum wb_reason reason); -int writeback_inodes_sb_nr_if_idle (struct super_block *,unsigned long nr, -enum wb_reason reason); +int try_to_writeback_inodes_sb (struct super_block *,enum wb_reason reason); +int try_to_writeback_inodes_sb_nr (struct super_block *,unsigned long nr, +enum wb_reason reason);void sync_inodes_sb (struct super_block *);long writeback_inodes_wb (struct bdi_writeback *wb,long nr_pages,enum wb_reason reason);
Signature · 1 line
1.7.6.5