aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-01-10 00:47:57 -0500
committerFengguang Wu <fengguang.wu@intel.com>2013-01-11 21:47:43 -0500
commit10ee27a06cc8eb57f83342a8eabcb75deb872d52 (patch)
treed14f69011b7aa1896f1aef37cb2b64f868bce459 /fs/fs-writeback.c
parent9931faca02c604c22335f5a935a501bb2ace6e20 (diff)
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. In order to fix the problem, ext4 and btrfs implemented their own writeback functions instead of writeback_inodes_sb(_nr)_if_idle(), but it introduced the redundant code, it is better to implement a new writeback_inodes_sb(_nr)_if_idle(). 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. Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 310972b72a66..ad3cc46a743a 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1332,47 +1332,43 @@ void writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)
1332EXPORT_SYMBOL(writeback_inodes_sb); 1332EXPORT_SYMBOL(writeback_inodes_sb);
1333 1333
1334/** 1334/**
1335 * writeback_inodes_sb_if_idle - start writeback if none underway 1335 * try_to_writeback_inodes_sb_nr - try to start writeback if none underway
1336 * @sb: the superblock 1336 * @sb: the superblock
1337 * @reason: reason why some writeback work was initiated 1337 * @nr: the number of pages to write
1338 * @reason: the reason of writeback
1338 * 1339 *
1339 * Invoke writeback_inodes_sb if no writeback is currently underway. 1340 * Invoke writeback_inodes_sb_nr if no writeback is currently underway.
1340 * Returns 1 if writeback was started, 0 if not. 1341 * Returns 1 if writeback was started, 0 if not.
1341 */ 1342 */
1342int writeback_inodes_sb_if_idle(struct super_block *sb, enum wb_reason reason) 1343int try_to_writeback_inodes_sb_nr(struct super_block *sb,
1344 unsigned long nr,
1345 enum wb_reason reason)
1343{ 1346{
1344 if (!writeback_in_progress(sb->s_bdi)) { 1347 if (writeback_in_progress(sb->s_bdi))
1345 down_read(&sb->s_umount);
1346 writeback_inodes_sb(sb, reason);
1347 up_read(&sb->s_umount);
1348 return 1; 1348 return 1;
1349 } else 1349
1350 if (!down_read_trylock(&sb->s_umount))
1350 return 0; 1351 return 0;
1352
1353 writeback_inodes_sb_nr(sb, nr, reason);
1354 up_read(&sb->s_umount);
1355 return 1;
1351} 1356}
1352EXPORT_SYMBOL(writeback_inodes_sb_if_idle); 1357EXPORT_SYMBOL(try_to_writeback_inodes_sb_nr);
1353 1358
1354/** 1359/**
1355 * writeback_inodes_sb_nr_if_idle - start writeback if none underway 1360 * try_to_writeback_inodes_sb - try to start writeback if none underway
1356 * @sb: the superblock 1361 * @sb: the superblock
1357 * @nr: the number of pages to write
1358 * @reason: reason why some writeback work was initiated 1362 * @reason: reason why some writeback work was initiated
1359 * 1363 *
1360 * Invoke writeback_inodes_sb if no writeback is currently underway. 1364 * Implement by try_to_writeback_inodes_sb_nr()
1361 * Returns 1 if writeback was started, 0 if not. 1365 * Returns 1 if writeback was started, 0 if not.
1362 */ 1366 */
1363int writeback_inodes_sb_nr_if_idle(struct super_block *sb, 1367int try_to_writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)
1364 unsigned long nr,
1365 enum wb_reason reason)
1366{ 1368{
1367 if (!writeback_in_progress(sb->s_bdi)) { 1369 return try_to_writeback_inodes_sb_nr(sb, get_nr_dirty_pages(), reason);
1368 down_read(&sb->s_umount);
1369 writeback_inodes_sb_nr(sb, nr, reason);
1370 up_read(&sb->s_umount);
1371 return 1;
1372 } else
1373 return 0;
1374} 1370}
1375EXPORT_SYMBOL(writeback_inodes_sb_nr_if_idle); 1371EXPORT_SYMBOL(try_to_writeback_inodes_sb);
1376 1372
1377/** 1373/**
1378 * sync_inodes_sb - sync sb inode pages 1374 * sync_inodes_sb - sync sb inode pages