aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-12 13:39:03 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commit1259ab75c62462b8ffad90067b5e1f6312786a18 (patch)
treeccc6b795e524a74b3fb9666409ca2f7f33bf98dd /fs/btrfs/extent_io.c
parentca7a79ad8dbe24669a8ced01f9fc0126b872745d (diff)
Btrfs: Handle write errors on raid1 and raid10
When duplicate copies exist, writes are allowed to fail to one of those copies. This changeset includes a few changes that allow the FS to continue even when some IOs fail. It also adds verification of the parent generation number for btree blocks. This generation is stored in the pointer to a block, and it ensures that missed writes to are detected. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r--fs/btrfs/extent_io.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index dd403b426ff5..2a3624adc0cf 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1366,7 +1366,7 @@ static int end_bio_extent_writepage(struct bio *bio,
1366 unsigned int bytes_done, int err) 1366 unsigned int bytes_done, int err)
1367#endif 1367#endif
1368{ 1368{
1369 const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 1369 int uptodate = err == 0;
1370 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; 1370 struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
1371 struct extent_state *state = bio->bi_private; 1371 struct extent_state *state = bio->bi_private;
1372 struct extent_io_tree *tree = state->tree; 1372 struct extent_io_tree *tree = state->tree;
@@ -1375,6 +1375,7 @@ static int end_bio_extent_writepage(struct bio *bio,
1375 u64 end; 1375 u64 end;
1376 u64 cur; 1376 u64 cur;
1377 int whole_page; 1377 int whole_page;
1378 int ret;
1378 unsigned long flags; 1379 unsigned long flags;
1379 1380
1380#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) 1381#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
@@ -1395,17 +1396,30 @@ static int end_bio_extent_writepage(struct bio *bio,
1395 if (--bvec >= bio->bi_io_vec) 1396 if (--bvec >= bio->bi_io_vec)
1396 prefetchw(&bvec->bv_page->flags); 1397 prefetchw(&bvec->bv_page->flags);
1397 1398
1399 if (tree->ops && tree->ops->writepage_end_io_hook) {
1400 ret = tree->ops->writepage_end_io_hook(page, start,
1401 end, state);
1402 if (ret)
1403 uptodate = 0;
1404 }
1405
1406 if (!uptodate && tree->ops &&
1407 tree->ops->writepage_io_failed_hook) {
1408 ret = tree->ops->writepage_io_failed_hook(bio, page,
1409 start, end, state);
1410 if (ret == 0) {
1411 state = NULL;
1412 uptodate = (err == 0);
1413 continue;
1414 }
1415 }
1416
1398 if (!uptodate) { 1417 if (!uptodate) {
1399 clear_extent_uptodate(tree, start, end, GFP_ATOMIC); 1418 clear_extent_uptodate(tree, start, end, GFP_ATOMIC);
1400 ClearPageUptodate(page); 1419 ClearPageUptodate(page);
1401 SetPageError(page); 1420 SetPageError(page);
1402 } 1421 }
1403 1422
1404 if (tree->ops && tree->ops->writepage_end_io_hook) {
1405 tree->ops->writepage_end_io_hook(page, start, end,
1406 state);
1407 }
1408
1409 /* 1423 /*
1410 * bios can get merged in funny ways, and so we need to 1424 * bios can get merged in funny ways, and so we need to
1411 * be careful with the state variable. We know the 1425 * be careful with the state variable. We know the
@@ -2073,9 +2087,9 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
2073 } else { 2087 } else {
2074 ret = 0; 2088 ret = 0;
2075 } 2089 }
2076 if (ret) 2090 if (ret) {
2077 SetPageError(page); 2091 SetPageError(page);
2078 else { 2092 } else {
2079 unsigned long max_nr = end_index + 1; 2093 unsigned long max_nr = end_index + 1;
2080 set_range_writeback(tree, cur, cur + iosize - 1); 2094 set_range_writeback(tree, cur, cur + iosize - 1);
2081 if (!PageWriteback(page)) { 2095 if (!PageWriteback(page)) {
@@ -2948,6 +2962,25 @@ int set_extent_buffer_dirty(struct extent_io_tree *tree,
2948} 2962}
2949EXPORT_SYMBOL(set_extent_buffer_dirty); 2963EXPORT_SYMBOL(set_extent_buffer_dirty);
2950 2964
2965int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
2966 struct extent_buffer *eb)
2967{
2968 unsigned long i;
2969 struct page *page;
2970 unsigned long num_pages;
2971
2972 num_pages = num_extent_pages(eb->start, eb->len);
2973 eb->flags &= ~EXTENT_UPTODATE;
2974
2975 clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
2976 GFP_NOFS);
2977 for (i = 0; i < num_pages; i++) {
2978 page = extent_buffer_page(eb, i);
2979 ClearPageUptodate(page);
2980 }
2981 return 0;
2982}
2983
2951int set_extent_buffer_uptodate(struct extent_io_tree *tree, 2984int set_extent_buffer_uptodate(struct extent_io_tree *tree,
2952 struct extent_buffer *eb) 2985 struct extent_buffer *eb)
2953{ 2986{