diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 86 |
1 files changed, 19 insertions, 67 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 7debbf396ef..45655793a2c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -572,50 +572,21 @@ int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans, | |||
572 | int btrfs_write_marked_extents(struct btrfs_root *root, | 572 | int btrfs_write_marked_extents(struct btrfs_root *root, |
573 | struct extent_io_tree *dirty_pages, int mark) | 573 | struct extent_io_tree *dirty_pages, int mark) |
574 | { | 574 | { |
575 | int ret; | ||
576 | int err = 0; | 575 | int err = 0; |
577 | int werr = 0; | 576 | int werr = 0; |
578 | struct page *page; | 577 | struct address_space *mapping = root->fs_info->btree_inode->i_mapping; |
579 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
580 | u64 start = 0; | 578 | u64 start = 0; |
581 | u64 end; | 579 | u64 end; |
582 | unsigned long index; | ||
583 | 580 | ||
584 | while (1) { | 581 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, |
585 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, | 582 | mark)) { |
586 | mark); | 583 | convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, mark, |
587 | if (ret) | 584 | GFP_NOFS); |
588 | break; | 585 | err = filemap_fdatawrite_range(mapping, start, end); |
589 | while (start <= end) { | 586 | if (err) |
590 | cond_resched(); | 587 | werr = err; |
591 | 588 | cond_resched(); | |
592 | index = start >> PAGE_CACHE_SHIFT; | 589 | start = end + 1; |
593 | start = (u64)(index + 1) << PAGE_CACHE_SHIFT; | ||
594 | page = find_get_page(btree_inode->i_mapping, index); | ||
595 | if (!page) | ||
596 | continue; | ||
597 | |||
598 | btree_lock_page_hook(page); | ||
599 | if (!page->mapping) { | ||
600 | unlock_page(page); | ||
601 | page_cache_release(page); | ||
602 | continue; | ||
603 | } | ||
604 | |||
605 | if (PageWriteback(page)) { | ||
606 | if (PageDirty(page)) | ||
607 | wait_on_page_writeback(page); | ||
608 | else { | ||
609 | unlock_page(page); | ||
610 | page_cache_release(page); | ||
611 | continue; | ||
612 | } | ||
613 | } | ||
614 | err = write_one_page(page, 0); | ||
615 | if (err) | ||
616 | werr = err; | ||
617 | page_cache_release(page); | ||
618 | } | ||
619 | } | 590 | } |
620 | if (err) | 591 | if (err) |
621 | werr = err; | 592 | werr = err; |
@@ -631,39 +602,20 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
631 | int btrfs_wait_marked_extents(struct btrfs_root *root, | 602 | int btrfs_wait_marked_extents(struct btrfs_root *root, |
632 | struct extent_io_tree *dirty_pages, int mark) | 603 | struct extent_io_tree *dirty_pages, int mark) |
633 | { | 604 | { |
634 | int ret; | ||
635 | int err = 0; | 605 | int err = 0; |
636 | int werr = 0; | 606 | int werr = 0; |
637 | struct page *page; | 607 | struct address_space *mapping = root->fs_info->btree_inode->i_mapping; |
638 | struct inode *btree_inode = root->fs_info->btree_inode; | ||
639 | u64 start = 0; | 608 | u64 start = 0; |
640 | u64 end; | 609 | u64 end; |
641 | unsigned long index; | ||
642 | 610 | ||
643 | while (1) { | 611 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, |
644 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, | 612 | EXTENT_NEED_WAIT)) { |
645 | mark); | 613 | clear_extent_bits(dirty_pages, start, end, EXTENT_NEED_WAIT, GFP_NOFS); |
646 | if (ret) | 614 | err = filemap_fdatawait_range(mapping, start, end); |
647 | break; | 615 | if (err) |
648 | 616 | werr = err; | |
649 | clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); | 617 | cond_resched(); |
650 | while (start <= end) { | 618 | start = end + 1; |
651 | index = start >> PAGE_CACHE_SHIFT; | ||
652 | start = (u64)(index + 1) << PAGE_CACHE_SHIFT; | ||
653 | page = find_get_page(btree_inode->i_mapping, index); | ||
654 | if (!page) | ||
655 | continue; | ||
656 | if (PageDirty(page)) { | ||
657 | btree_lock_page_hook(page); | ||
658 | wait_on_page_writeback(page); | ||
659 | err = write_one_page(page, 0); | ||
660 | if (err) | ||
661 | werr = err; | ||
662 | } | ||
663 | wait_on_page_writeback(page); | ||
664 | page_cache_release(page); | ||
665 | cond_resched(); | ||
666 | } | ||
667 | } | 619 | } |
668 | if (err) | 620 | if (err) |
669 | werr = err; | 621 | werr = err; |