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

Merge tag 'writeback-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux

Pull writeback fixes from Wu Fengguang:
"Two writeback fixes

- fix negative (setpoint - dirty) in 32bit archs

- use down_read_trylock() in writeback_inodes_sb(_nr)_if_idle()"

* tag 'writeback-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/wfg/linux:
Negative (setpoint-dirty) in bdi_position_ratio()
vfs: re-implement writeback_inodes_sb(_nr)_if_idle() and rename them

+37 -59
+3 -17
fs/btrfs/extent-tree.c
··· 3689 3689 return 0; 3690 3690 } 3691 3691 3692 - static int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb, 3693 - unsigned long nr_pages, 3694 - enum wb_reason reason) 3695 - { 3696 - if (!writeback_in_progress(sb->s_bdi) && 3697 - down_read_trylock(&sb->s_umount)) { 3698 - writeback_inodes_sb_nr(sb, nr_pages, reason); 3699 - up_read(&sb->s_umount); 3700 - return 1; 3701 - } 3702 - 3703 - return 0; 3704 - } 3705 - 3706 3692 /* 3707 3693 * shrink metadata reservation for delalloc 3708 3694 */ ··· 3721 3735 while (delalloc_bytes && loops < 3) { 3722 3736 max_reclaim = min(delalloc_bytes, to_reclaim); 3723 3737 nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; 3724 - writeback_inodes_sb_nr_if_idle_safe(root->fs_info->sb, 3725 - nr_pages, 3726 - WB_REASON_FS_FREE_SPACE); 3738 + try_to_writeback_inodes_sb_nr(root->fs_info->sb, 3739 + nr_pages, 3740 + WB_REASON_FS_FREE_SPACE); 3727 3741 3728 3742 /* 3729 3743 * We need to wait for the async pages to actually start before
+2 -6
fs/ext4/inode.c
··· 2512 2512 /* 2513 2513 * Start pushing delalloc when 1/2 of free blocks are dirty. 2514 2514 */ 2515 - if (dirty_blocks && (free_blocks < 2 * dirty_blocks) && 2516 - !writeback_in_progress(sb->s_bdi) && 2517 - down_read_trylock(&sb->s_umount)) { 2518 - writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE); 2519 - up_read(&sb->s_umount); 2520 - } 2515 + if (dirty_blocks && (free_blocks < 2 * dirty_blocks)) 2516 + try_to_writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE); 2521 2517 2522 2518 if (2 * free_blocks < 3 * dirty_blocks || 2523 2519 free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) {
+28 -32
fs/fs-writeback.c
··· 1344 1344 EXPORT_SYMBOL(writeback_inodes_sb); 1345 1345 1346 1346 /** 1347 - * writeback_inodes_sb_if_idle - start writeback if none underway 1348 - * @sb: the superblock 1349 - * @reason: reason why some writeback work was initiated 1350 - * 1351 - * Invoke writeback_inodes_sb if no writeback is currently underway. 1352 - * Returns 1 if writeback was started, 0 if not. 1353 - */ 1354 - int writeback_inodes_sb_if_idle(struct super_block *sb, enum wb_reason reason) 1355 - { 1356 - if (!writeback_in_progress(sb->s_bdi)) { 1357 - down_read(&sb->s_umount); 1358 - writeback_inodes_sb(sb, reason); 1359 - up_read(&sb->s_umount); 1360 - return 1; 1361 - } else 1362 - return 0; 1363 - } 1364 - EXPORT_SYMBOL(writeback_inodes_sb_if_idle); 1365 - 1366 - /** 1367 - * writeback_inodes_sb_nr_if_idle - start writeback if none underway 1347 + * try_to_writeback_inodes_sb_nr - try to start writeback if none underway 1368 1348 * @sb: the superblock 1369 1349 * @nr: the number of pages to write 1370 - * @reason: reason why some writeback work was initiated 1350 + * @reason: the reason of writeback 1371 1351 * 1372 - * Invoke writeback_inodes_sb if no writeback is currently underway. 1352 + * Invoke writeback_inodes_sb_nr if no writeback is currently underway. 1373 1353 * Returns 1 if writeback was started, 0 if not. 1374 1354 */ 1375 - int writeback_inodes_sb_nr_if_idle(struct super_block *sb, 1376 - unsigned long nr, 1377 - enum wb_reason reason) 1355 + int try_to_writeback_inodes_sb_nr(struct super_block *sb, 1356 + unsigned long nr, 1357 + enum wb_reason reason) 1378 1358 { 1379 - if (!writeback_in_progress(sb->s_bdi)) { 1380 - down_read(&sb->s_umount); 1381 - writeback_inodes_sb_nr(sb, nr, reason); 1382 - up_read(&sb->s_umount); 1359 + if (writeback_in_progress(sb->s_bdi)) 1383 1360 return 1; 1384 - } else 1361 + 1362 + if (!down_read_trylock(&sb->s_umount)) 1385 1363 return 0; 1364 + 1365 + writeback_inodes_sb_nr(sb, nr, reason); 1366 + up_read(&sb->s_umount); 1367 + return 1; 1386 1368 } 1387 - EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle); 1369 + EXPORT_SYMBOL(try_to_writeback_inodes_sb_nr); 1370 + 1371 + /** 1372 + * try_to_writeback_inodes_sb - try to start writeback if none underway 1373 + * @sb: the superblock 1374 + * @reason: reason why some writeback work was initiated 1375 + * 1376 + * Implement by try_to_writeback_inodes_sb_nr() 1377 + * Returns 1 if writeback was started, 0 if not. 1378 + */ 1379 + int try_to_writeback_inodes_sb(struct super_block *sb, enum wb_reason reason) 1380 + { 1381 + return try_to_writeback_inodes_sb_nr(sb, get_nr_dirty_pages(), reason); 1382 + } 1383 + EXPORT_SYMBOL(try_to_writeback_inodes_sb); 1388 1384 1389 1385 /** 1390 1386 * sync_inodes_sb - sync sb inode pages
+3 -3
include/linux/writeback.h
··· 87 87 void writeback_inodes_sb(struct super_block *, enum wb_reason reason); 88 88 void writeback_inodes_sb_nr(struct super_block *, unsigned long nr, 89 89 enum wb_reason reason); 90 - int writeback_inodes_sb_if_idle(struct super_block *, enum wb_reason reason); 91 - int writeback_inodes_sb_nr_if_idle(struct super_block *, unsigned long nr, 92 - enum wb_reason reason); 90 + int try_to_writeback_inodes_sb(struct super_block *, enum wb_reason reason); 91 + int try_to_writeback_inodes_sb_nr(struct super_block *, unsigned long nr, 92 + enum wb_reason reason); 93 93 void sync_inodes_sb(struct super_block *); 94 94 long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, 95 95 enum wb_reason reason);
+1 -1
mm/page-writeback.c
··· 696 696 * => fast response on large errors; small oscillation near setpoint 697 697 */ 698 698 setpoint = (freerun + limit) / 2; 699 - x = div_s64((setpoint - dirty) << RATELIMIT_CALC_SHIFT, 699 + x = div_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT, 700 700 limit - setpoint + 1); 701 701 pos_ratio = x; 702 702 pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT;