aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-11-04 12:29:37 -0400
committerChris Mason <chris.mason@oracle.com>2011-11-06 03:04:20 -0500
commitbf0da8c183a15656eee63c54f334c3794320872a (patch)
treedad92ff6ea5cba470d93664b9ea195ecab66b07b
parent663350ac38c67ca388acea6e876dc6d668c232b0 (diff)
Btrfs: ClearPageError during writepage and clean_tree_block
Failure testing was tripping up over stale PageError bits in metadata pages. If we have an io error on a block, and later on end up reusing it, nobody ever clears PageError on those pages. During commit, we'll find PageError and think we had trouble writing the block, which will lead to aborts and other problems. This changes clean_tree_block and the btrfs writepage code to clear the PageError bit. In both cases we're either completely done with the page or the page has good stuff and the error bit is no longer valid. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/extent_io.c4
-rw-r--r--fs/btrfs/transaction.c7
2 files changed, 10 insertions, 1 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index b40ba75f4483..cc3c58970d4e 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2334,6 +2334,9 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2334 trace___extent_writepage(page, inode, wbc); 2334 trace___extent_writepage(page, inode, wbc);
2335 2335
2336 WARN_ON(!PageLocked(page)); 2336 WARN_ON(!PageLocked(page));
2337
2338 ClearPageError(page);
2339
2337 pg_offset = i_size & (PAGE_CACHE_SIZE - 1); 2340 pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
2338 if (page->index > end_index || 2341 if (page->index > end_index ||
2339 (page->index == end_index && !pg_offset)) { 2342 (page->index == end_index && !pg_offset)) {
@@ -3402,6 +3405,7 @@ int clear_extent_buffer_dirty(struct extent_io_tree *tree,
3402 PAGECACHE_TAG_DIRTY); 3405 PAGECACHE_TAG_DIRTY);
3403 } 3406 }
3404 spin_unlock_irq(&page->mapping->tree_lock); 3407 spin_unlock_irq(&page->mapping->tree_lock);
3408 ClearPageError(page);
3405 unlock_page(page); 3409 unlock_page(page);
3406 } 3410 }
3407 return 0; 3411 return 0;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 373c7ec1a026..29f782cc2cc9 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -634,7 +634,12 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
634 634
635 ret = btrfs_write_marked_extents(root, dirty_pages, mark); 635 ret = btrfs_write_marked_extents(root, dirty_pages, mark);
636 ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); 636 ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
637 return ret || ret2; 637
638 if (ret)
639 return ret;
640 if (ret2)
641 return ret2;
642 return 0;
638} 643}
639 644
640int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 645int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,