diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-09-11 16:17:57 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:07 -0400 |
commit | d0c803c4049c5ca322d4795d8b74f28768603e0e (patch) | |
tree | b4c4f11b2f5938ad183a1771cd0b9e122709e2ff /fs/btrfs/transaction.c | |
parent | 31ff1cd25d376e8f499d450de177dffadc9e1c56 (diff) |
Btrfs: Record dirty pages tree-log pages in an extent_io tree
This is the same way the transaction code makes sure that all the
other tree blocks are safely on disk. There's an extent_io tree
for each root, and any blocks allocated to the tree logs are
recorded in that tree.
At tree-log sync, the extent_io tree is walked to flush down the
dirty pages and wait for them.
The main benefit is less time spent walking the tree log and skipping
clean pages, and getting sequential IO down to the drive.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 61a377bcb2fb..151b00d52593 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -302,23 +302,18 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, | |||
302 | } | 302 | } |
303 | 303 | ||
304 | 304 | ||
305 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 305 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, |
306 | struct btrfs_root *root) | 306 | struct extent_io_tree *dirty_pages) |
307 | { | 307 | { |
308 | int ret; | 308 | int ret; |
309 | int err = 0; | 309 | int err = 0; |
310 | int werr = 0; | 310 | int werr = 0; |
311 | struct extent_io_tree *dirty_pages; | ||
312 | struct page *page; | 311 | struct page *page; |
313 | struct inode *btree_inode = root->fs_info->btree_inode; | 312 | struct inode *btree_inode = root->fs_info->btree_inode; |
314 | u64 start = 0; | 313 | u64 start = 0; |
315 | u64 end; | 314 | u64 end; |
316 | unsigned long index; | 315 | unsigned long index; |
317 | 316 | ||
318 | if (!trans || !trans->transaction) { | ||
319 | return filemap_write_and_wait(btree_inode->i_mapping); | ||
320 | } | ||
321 | dirty_pages = &trans->transaction->dirty_pages; | ||
322 | while(1) { | 317 | while(1) { |
323 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, | 318 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, |
324 | EXTENT_DIRTY); | 319 | EXTENT_DIRTY); |
@@ -385,6 +380,18 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | |||
385 | return werr; | 380 | return werr; |
386 | } | 381 | } |
387 | 382 | ||
383 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | ||
384 | struct btrfs_root *root) | ||
385 | { | ||
386 | if (!trans || !trans->transaction) { | ||
387 | struct inode *btree_inode; | ||
388 | btree_inode = root->fs_info->btree_inode; | ||
389 | return filemap_write_and_wait(btree_inode->i_mapping); | ||
390 | } | ||
391 | return btrfs_write_and_wait_marked_extents(root, | ||
392 | &trans->transaction->dirty_pages); | ||
393 | } | ||
394 | |||
388 | static int update_cowonly_root(struct btrfs_trans_handle *trans, | 395 | static int update_cowonly_root(struct btrfs_trans_handle *trans, |
389 | struct btrfs_root *root) | 396 | struct btrfs_root *root) |
390 | { | 397 | { |