diff options
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r-- | fs/fs-writeback.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 24489126f8ca..091a36444972 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 | */ |
1384 | static long writeback_sb_inodes(struct super_block *sb, | 1388 | static 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 | ||
@@ -1479,6 +1481,21 @@ static long writeback_sb_inodes(struct super_block *sb, | |||
1479 | wbc_detach_inode(&wbc); | 1481 | wbc_detach_inode(&wbc); |
1480 | work->nr_pages -= write_chunk - wbc.nr_to_write; | 1482 | work->nr_pages -= write_chunk - wbc.nr_to_write; |
1481 | wrote += write_chunk - wbc.nr_to_write; | 1483 | wrote += write_chunk - wbc.nr_to_write; |
1484 | |||
1485 | if (need_resched()) { | ||
1486 | /* | ||
1487 | * We're trying to balance between building up a nice | ||
1488 | * long list of IOs to improve our merge rate, and | ||
1489 | * getting those IOs out quickly for anyone throttling | ||
1490 | * in balance_dirty_pages(). cond_resched() doesn't | ||
1491 | * unplug, so get our IOs out the door before we | ||
1492 | * give up the CPU. | ||
1493 | */ | ||
1494 | blk_flush_plug(current); | ||
1495 | cond_resched(); | ||
1496 | } | ||
1497 | |||
1498 | |||
1482 | spin_lock(&wb->list_lock); | 1499 | spin_lock(&wb->list_lock); |
1483 | spin_lock(&inode->i_lock); | 1500 | spin_lock(&inode->i_lock); |
1484 | if (!(inode->i_state & I_DIRTY_ALL)) | 1501 | if (!(inode->i_state & I_DIRTY_ALL)) |
@@ -1486,7 +1503,7 @@ static long writeback_sb_inodes(struct super_block *sb, | |||
1486 | requeue_inode(inode, wb, &wbc); | 1503 | requeue_inode(inode, wb, &wbc); |
1487 | inode_sync_complete(inode); | 1504 | inode_sync_complete(inode); |
1488 | spin_unlock(&inode->i_lock); | 1505 | spin_unlock(&inode->i_lock); |
1489 | cond_resched_lock(&wb->list_lock); | 1506 | |
1490 | /* | 1507 | /* |
1491 | * bail out to wb_writeback() often enough to check | 1508 | * bail out to wb_writeback() often enough to check |
1492 | * background threshold and other termination conditions. | 1509 | * background threshold and other termination conditions. |
@@ -1498,7 +1515,6 @@ static long writeback_sb_inodes(struct super_block *sb, | |||
1498 | break; | 1515 | break; |
1499 | } | 1516 | } |
1500 | } | 1517 | } |
1501 | blk_finish_plug(&plug); | ||
1502 | return wrote; | 1518 | return wrote; |
1503 | } | 1519 | } |
1504 | 1520 | ||
@@ -1545,12 +1561,15 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, | |||
1545 | .range_cyclic = 1, | 1561 | .range_cyclic = 1, |
1546 | .reason = reason, | 1562 | .reason = reason, |
1547 | }; | 1563 | }; |
1564 | struct blk_plug plug; | ||
1548 | 1565 | ||
1566 | blk_start_plug(&plug); | ||
1549 | spin_lock(&wb->list_lock); | 1567 | spin_lock(&wb->list_lock); |
1550 | if (list_empty(&wb->b_io)) | 1568 | if (list_empty(&wb->b_io)) |
1551 | queue_io(wb, &work); | 1569 | queue_io(wb, &work); |
1552 | __writeback_inodes_wb(wb, &work); | 1570 | __writeback_inodes_wb(wb, &work); |
1553 | spin_unlock(&wb->list_lock); | 1571 | spin_unlock(&wb->list_lock); |
1572 | blk_finish_plug(&plug); | ||
1554 | 1573 | ||
1555 | return nr_pages - work.nr_pages; | 1574 | return nr_pages - work.nr_pages; |
1556 | } | 1575 | } |
@@ -1578,10 +1597,12 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
1578 | unsigned long oldest_jif; | 1597 | unsigned long oldest_jif; |
1579 | struct inode *inode; | 1598 | struct inode *inode; |
1580 | long progress; | 1599 | long progress; |
1600 | struct blk_plug plug; | ||
1581 | 1601 | ||
1582 | oldest_jif = jiffies; | 1602 | oldest_jif = jiffies; |
1583 | work->older_than_this = &oldest_jif; | 1603 | work->older_than_this = &oldest_jif; |
1584 | 1604 | ||
1605 | blk_start_plug(&plug); | ||
1585 | spin_lock(&wb->list_lock); | 1606 | spin_lock(&wb->list_lock); |
1586 | for (;;) { | 1607 | for (;;) { |
1587 | /* | 1608 | /* |
@@ -1661,6 +1682,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
1661 | } | 1682 | } |
1662 | } | 1683 | } |
1663 | spin_unlock(&wb->list_lock); | 1684 | spin_unlock(&wb->list_lock); |
1685 | blk_finish_plug(&plug); | ||
1664 | 1686 | ||
1665 | return nr_pages - work->nr_pages; | 1687 | return nr_pages - work->nr_pages; |
1666 | } | 1688 | } |