Skip to contentSkip to conversation

vfs: re-implement writeback_inodes_sb(_nr)_if_idle() and rename them

PATCH New Miao Xie 1 participant 1 message Apr 29, 2012

Subsystems (4)
lore
Share & tools
lore

Miao Xie

author
#0 lore raw

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.

---
 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
index 2b35f8d..deb2577 100644
@@ -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
index c77b0bd..2dccb4d 100644
@@ -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
index a2b84f5..0552d1a 100644
@@ -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