aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-06 22:02:51 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-06 22:02:51 -0500
commit771ed689d2cd53439e28e095bc38fbe40a71429e (patch)
tree518801f7141928e398d40c2b5955720d4346ce1a /fs/btrfs/disk-io.c
parent4a69a41009c4ac691f7d9c289f5f37fabeddce46 (diff)
Btrfs: Optimize compressed writeback and reads
When reading compressed extents, try to put pages into the page cache for any pages covered by the compressed extent that readpages didn't already preload. Add an async work queue to handle transformations at delayed allocation processing time. Right now this is just compression. The workflow is: 1) Find offsets in the file marked for delayed allocation 2) Lock the pages 3) Lock the state bits 4) Call the async delalloc code The async delalloc code clears the state lock bits and delalloc bits. It is important this happens before the range goes into the work queue because otherwise it might deadlock with other work queue items that try to lock those extent bits. The file pages are compressed, and if the compression doesn't work the pages are written back directly. An ordered work queue is used to make sure the inodes are written in the same order that pdflush or writepages sent them down. This changes extent_write_cache_pages to let the writepage function update the wbc nr_written count. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e0a28f705a64..8efc123d222b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -539,6 +539,13 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
539 (atomic_read(&fs_info->nr_async_bios) < limit), 539 (atomic_read(&fs_info->nr_async_bios) < limit),
540 HZ/10); 540 HZ/10);
541 } 541 }
542
543 while(atomic_read(&fs_info->async_submit_draining) &&
544 atomic_read(&fs_info->nr_async_submits)) {
545 wait_event(fs_info->async_submit_wait,
546 (atomic_read(&fs_info->nr_async_submits) == 0));
547 }
548
542 return 0; 549 return 0;
543} 550}
544 551
@@ -1437,6 +1444,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1437 INIT_LIST_HEAD(&fs_info->space_info); 1444 INIT_LIST_HEAD(&fs_info->space_info);
1438 btrfs_mapping_init(&fs_info->mapping_tree); 1445 btrfs_mapping_init(&fs_info->mapping_tree);
1439 atomic_set(&fs_info->nr_async_submits, 0); 1446 atomic_set(&fs_info->nr_async_submits, 0);
1447 atomic_set(&fs_info->async_delalloc_pages, 0);
1440 atomic_set(&fs_info->async_submit_draining, 0); 1448 atomic_set(&fs_info->async_submit_draining, 0);
1441 atomic_set(&fs_info->nr_async_bios, 0); 1449 atomic_set(&fs_info->nr_async_bios, 0);
1442 atomic_set(&fs_info->throttles, 0); 1450 atomic_set(&fs_info->throttles, 0);
@@ -1550,6 +1558,9 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1550 btrfs_init_workers(&fs_info->workers, "worker", 1558 btrfs_init_workers(&fs_info->workers, "worker",
1551 fs_info->thread_pool_size); 1559 fs_info->thread_pool_size);
1552 1560
1561 btrfs_init_workers(&fs_info->delalloc_workers, "delalloc",
1562 fs_info->thread_pool_size);
1563
1553 btrfs_init_workers(&fs_info->submit_workers, "submit", 1564 btrfs_init_workers(&fs_info->submit_workers, "submit",
1554 min_t(u64, fs_devices->num_devices, 1565 min_t(u64, fs_devices->num_devices,
1555 fs_info->thread_pool_size)); 1566 fs_info->thread_pool_size));
@@ -1560,15 +1571,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1560 */ 1571 */
1561 fs_info->submit_workers.idle_thresh = 64; 1572 fs_info->submit_workers.idle_thresh = 64;
1562 1573
1563 /* fs_info->workers is responsible for checksumming file data 1574 fs_info->workers.idle_thresh = 16;
1564 * blocks and metadata. Using a larger idle thresh allows each
1565 * worker thread to operate on things in roughly the order they
1566 * were sent by the writeback daemons, improving overall locality
1567 * of the IO going down the pipe.
1568 */
1569 fs_info->workers.idle_thresh = 8;
1570 fs_info->workers.ordered = 1; 1575 fs_info->workers.ordered = 1;
1571 1576
1577 fs_info->delalloc_workers.idle_thresh = 2;
1578 fs_info->delalloc_workers.ordered = 1;
1579
1572 btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1); 1580 btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1);
1573 btrfs_init_workers(&fs_info->endio_workers, "endio", 1581 btrfs_init_workers(&fs_info->endio_workers, "endio",
1574 fs_info->thread_pool_size); 1582 fs_info->thread_pool_size);
@@ -1584,6 +1592,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1584 1592
1585 btrfs_start_workers(&fs_info->workers, 1); 1593 btrfs_start_workers(&fs_info->workers, 1);
1586 btrfs_start_workers(&fs_info->submit_workers, 1); 1594 btrfs_start_workers(&fs_info->submit_workers, 1);
1595 btrfs_start_workers(&fs_info->delalloc_workers, 1);
1587 btrfs_start_workers(&fs_info->fixup_workers, 1); 1596 btrfs_start_workers(&fs_info->fixup_workers, 1);
1588 btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); 1597 btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size);
1589 btrfs_start_workers(&fs_info->endio_write_workers, 1598 btrfs_start_workers(&fs_info->endio_write_workers,
@@ -1732,6 +1741,7 @@ fail_tree_root:
1732fail_sys_array: 1741fail_sys_array:
1733fail_sb_buffer: 1742fail_sb_buffer:
1734 btrfs_stop_workers(&fs_info->fixup_workers); 1743 btrfs_stop_workers(&fs_info->fixup_workers);
1744 btrfs_stop_workers(&fs_info->delalloc_workers);
1735 btrfs_stop_workers(&fs_info->workers); 1745 btrfs_stop_workers(&fs_info->workers);
1736 btrfs_stop_workers(&fs_info->endio_workers); 1746 btrfs_stop_workers(&fs_info->endio_workers);
1737 btrfs_stop_workers(&fs_info->endio_write_workers); 1747 btrfs_stop_workers(&fs_info->endio_write_workers);
@@ -1988,6 +1998,7 @@ int close_ctree(struct btrfs_root *root)
1988 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); 1998 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
1989 1999
1990 btrfs_stop_workers(&fs_info->fixup_workers); 2000 btrfs_stop_workers(&fs_info->fixup_workers);
2001 btrfs_stop_workers(&fs_info->delalloc_workers);
1991 btrfs_stop_workers(&fs_info->workers); 2002 btrfs_stop_workers(&fs_info->workers);
1992 btrfs_stop_workers(&fs_info->endio_workers); 2003 btrfs_stop_workers(&fs_info->endio_workers);
1993 btrfs_stop_workers(&fs_info->endio_write_workers); 2004 btrfs_stop_workers(&fs_info->endio_write_workers);
@@ -2062,7 +2073,7 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
2062 struct extent_io_tree *tree; 2073 struct extent_io_tree *tree;
2063 u64 num_dirty; 2074 u64 num_dirty;
2064 u64 start = 0; 2075 u64 start = 0;
2065 unsigned long thresh = 96 * 1024 * 1024; 2076 unsigned long thresh = 32 * 1024 * 1024;
2066 tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; 2077 tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
2067 2078
2068 if (current_is_pdflush() || current->flags & PF_MEMALLOC) 2079 if (current_is_pdflush() || current->flags & PF_MEMALLOC)