Skip to contentSkip to conversation

writeback fixes for v3.9-rc1

GIT PULL Fengguang Wu 1 participant 1 message Feb 28, 2013

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

Hi Linus,

Here are 2 writeback fixes.

Please be prepared for a merge conflict in fs/btrfs/extent-tree.c as occured/resolved in linux-next's merge commit 6ae374247bfd8 ("Merge remote-tracking branch 'writeback/writeback-for-next'").

Thanks,
Fengguang
---

The following changes since commit 9931faca02c604c22335f5a935a501bb2ace6e20:

Linux 3.8-rc3 (2013-01-09 18:59:55 -0800)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux.git tags/writeback-fixes

for you to fetch changes up to ed84825b785ceb932af7dd5aa08614801721320b:

Negative (setpoint-dirty) in bdi_position_ratio() (2013-01-24 22:22:22 +0800)

----------------------------------------------------------------
2 writeback fixes
- fix negative (setpoint - dirty) in 32bit archs
- use down_read_trylock() in writeback_inodes_sb(_nr)_if_idle()

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

[email protected] (1):
Negative (setpoint-dirty) in bdi_position_ratio()

(Yeah I'm aware of that broken author name and tried to fix it, however just
found that the fixing commit lies in "* (no branch)" and now it's a bit late to update the "writeback-for-next" branch).

 fs/btrfs/extent-tree.c    |   20 +++-----------------
 fs/ext4/inode.c           |    8 ++------
 fs/fs-writeback.c         |   44 ++++++++++++++++++++------------------------
 include/linux/writeback.h |    6 +++---
 mm/page-writeback.c       |    2 +-
 5 files changed, 29 insertions(+), 51 deletions(-)
fs/btrfs/extent-tree.c +3 -17
index 521e9d4..f31abb1 100644
@@ -3689,20 +3689,6 @@ static int can_overcommit(struct btrfs_root *root,
 	return 0;
 }
 
-static int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb,
-					       unsigned long nr_pages,
-					       enum wb_reason reason)
-{
-	if (!writeback_in_progress(sb->s_bdi) &&
-	    down_read_trylock(&sb->s_umount)) {
-		writeback_inodes_sb_nr(sb, nr_pages, reason);
-		up_read(&sb->s_umount);
-		return 1;
-	}
-
-	return 0;
-}
-
 /*
  * shrink metadata reservation for delalloc
  */
@@ -3735,9 +3721,9 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
 	while (delalloc_bytes && loops < 3) {
 		max_reclaim = min(delalloc_bytes, to_reclaim);
 		nr_pages = max_reclaim >> PAGE_CACHE_SHIFT;
-		writeback_inodes_sb_nr_if_idle_safe(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);
 
 		/*
 		 * We need to wait for the async pages to actually start before
fs/ext4/inode.c +2 -6
index cbfe13b..5f6eef7 100644
@@ -2512,12 +2512,8 @@ static int ext4_nonda_switch(struct super_block *sb)
 	/*
 	 * Start pushing delalloc when 1/2 of free blocks are dirty.
 	 */
-	if (dirty_blocks && (free_blocks < 2 * dirty_blocks) &&
-	    !writeback_in_progress(sb->s_bdi) &&
-	    down_read_trylock(&sb->s_umount)) {
-		writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE);
-		up_read(&sb->s_umount);
-	}
+	if (dirty_blocks && (free_blocks < 2 * dirty_blocks))
+		try_to_writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE);
 
 	if (2 * free_blocks < 3 * dirty_blocks ||
 		free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) {
fs/fs-writeback.c +20 -24

67 lines not on this page · raw message

include/linux/writeback.h +3 -3
index b82a83a..9a9367c 100644
@@ -87,9 +87,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);
mm/page-writeback.c +1 -1
index 0713bfb..1534ebd 100644
@@ -692,7 +692,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi,
 	 *     => fast response on large errors; small oscillation near setpoint
 	 */
 	setpoint = (freerun + limit) / 2;
-	x = div_s64((setpoint - dirty) << RATELIMIT_CALC_SHIFT,
+	x = div_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT,
 		    limit - setpoint + 1);
 	pos_ratio = x;
 	pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT;