aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-09-12 14:19:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-12 14:19:01 -0400
commite1df8b0a1bb2ac8254616d6075e40f9ca447fa29 (patch)
treed8e6f12e4d10f6da02e6639973e8c4da29f13c31
parentdfb22fc5c0eb7645f47a752ce537bfb2c8a6aea6 (diff)
parent505a666ee3fc611518e85df203eb8c707995ceaa (diff)
Merge branch 'writeback-plugging'
Fix up the writeback plugging introduced in commit d353d7587d02 ("writeback: plug writeback at a high level") that then caused problems due to the unplug happening with a spinlock held. * writeback-plugging: writeback: plug writeback in wb_writeback() and writeback_inodes_wb() Revert "writeback: plug writeback at a high level"
-rw-r--r--fs/fs-writeback.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 24489126f8ca..587ac08eabb6 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1380,6 +1380,10 @@ static long writeback_chunk_size(struct bdi_writeback *wb,
1380 * Write a portion of b_io inodes which belong to @sb. 1380 * Write a portion of b_io inodes which belong to @sb.
1381 * 1381 *
1382 * Return the number of pages and/or inodes written. 1382 * Return the number of pages and/or inodes written.
1383 *
1384 * NOTE! This is called with wb->list_lock held, and will
1385 * unlock and relock that for each inode it ends up doing
1386 * IO for.
1383 */ 1387 */
1384static long writeback_sb_inodes(struct super_block *sb, 1388static long writeback_sb_inodes(struct super_block *sb,
1385 struct bdi_writeback *wb, 1389 struct bdi_writeback *wb,
@@ -1398,9 +1402,7 @@ static long writeback_sb_inodes(struct super_block *sb,
1398 unsigned long start_time = jiffies; 1402 unsigned long start_time = jiffies;
1399 long write_chunk; 1403 long write_chunk;
1400 long wrote = 0; /* count both pages and inodes */ 1404 long wrote = 0; /* count both pages and inodes */
1401 struct blk_plug plug;
1402 1405
1403 blk_start_plug(&plug);
1404 while (!list_empty(&wb->b_io)) { 1406 while (!list_empty(&wb->b_io)) {
1405 struct inode *inode = wb_inode(wb->b_io.prev); 1407 struct inode *inode = wb_inode(wb->b_io.prev);
1406 1408
@@ -1498,7 +1500,6 @@ static long writeback_sb_inodes(struct super_block *sb,
1498 break; 1500 break;
1499 } 1501 }
1500 } 1502 }
1501 blk_finish_plug(&plug);
1502 return wrote; 1503 return wrote;
1503} 1504}
1504 1505
@@ -1545,12 +1546,15 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
1545 .range_cyclic = 1, 1546 .range_cyclic = 1,
1546 .reason = reason, 1547 .reason = reason,
1547 }; 1548 };
1549 struct blk_plug plug;
1548 1550
1551 blk_start_plug(&plug);
1549 spin_lock(&wb->list_lock); 1552 spin_lock(&wb->list_lock);
1550 if (list_empty(&wb->b_io)) 1553 if (list_empty(&wb->b_io))
1551 queue_io(wb, &work); 1554 queue_io(wb, &work);
1552 __writeback_inodes_wb(wb, &work); 1555 __writeback_inodes_wb(wb, &work);
1553 spin_unlock(&wb->list_lock); 1556 spin_unlock(&wb->list_lock);
1557 blk_finish_plug(&plug);
1554 1558
1555 return nr_pages - work.nr_pages; 1559 return nr_pages - work.nr_pages;
1556} 1560}
@@ -1578,10 +1582,12 @@ static long wb_writeback(struct bdi_writeback *wb,
1578 unsigned long oldest_jif; 1582 unsigned long oldest_jif;
1579 struct inode *inode; 1583 struct inode *inode;
1580 long progress; 1584 long progress;
1585 struct blk_plug plug;
1581 1586
1582 oldest_jif = jiffies; 1587 oldest_jif = jiffies;
1583 work->older_than_this = &oldest_jif; 1588 work->older_than_this = &oldest_jif;
1584 1589
1590 blk_start_plug(&plug);
1585 spin_lock(&wb->list_lock); 1591 spin_lock(&wb->list_lock);
1586 for (;;) { 1592 for (;;) {
1587 /* 1593 /*
@@ -1661,6 +1667,7 @@ static long wb_writeback(struct bdi_writeback *wb,
1661 } 1667 }
1662 } 1668 }
1663 spin_unlock(&wb->list_lock); 1669 spin_unlock(&wb->list_lock);
1670 blk_finish_plug(&plug);
1664 1671
1665 return nr_pages - work->nr_pages; 1672 return nr_pages - work->nr_pages;
1666} 1673}