aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2011-12-01 09:30:36 -0500
committerChris Mason <chris.mason@oracle.com>2011-12-01 09:30:36 -0500
commitf4a8e6563ea5366f563cb741a27fe90c5fa7f0fc (patch)
treee51f3968c45fdce8372f16d4e815d44fe6a0272a /fs/btrfs
parentbe064d113906f04ea13088a8260e1e68ae0a4050 (diff)
Btrfs: fix meta data raid-repair merge problem
Commit 4a54c8c16 introduced raid-repair, killing the individual readpage_io_failed_hook entries from inode.c and disk-io.c. Commit 4bb31e92 introduced new readahead code, adding a readpage_io_failed_hook to disk-io.c. The raid-repair commit had logic to disable raid-repair, if readpage_io_failed_hook is set. Thus, the readahead commit effectively disabled raid-repair for meta data. This commit changes the logic to always attempt raid-repair when needed and call the readpage_io_failed_hook in case raid-repair fails. This is much more straight forward and should have been like that from the beginning. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> Reported-by: Stefan Behrens <sbehrens@giantdisaster.de> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/extent_io.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 9472d3de5e5..be1bf627a14 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2287,14 +2287,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2287 if (!uptodate) { 2287 if (!uptodate) {
2288 int failed_mirror; 2288 int failed_mirror;
2289 failed_mirror = (int)(unsigned long)bio->bi_bdev; 2289 failed_mirror = (int)(unsigned long)bio->bi_bdev;
2290 if (tree->ops && tree->ops->readpage_io_failed_hook) 2290 /*
2291 ret = tree->ops->readpage_io_failed_hook( 2291 * The generic bio_readpage_error handles errors the
2292 bio, page, start, end, 2292 * following way: If possible, new read requests are
2293 failed_mirror, state); 2293 * created and submitted and will end up in
2294 else 2294 * end_bio_extent_readpage as well (if we're lucky, not
2295 ret = bio_readpage_error(bio, page, start, end, 2295 * in the !uptodate case). In that case it returns 0 and
2296 failed_mirror, NULL); 2296 * we just go on with the next page in our bio. If it
2297 * can't handle the error it will return -EIO and we
2298 * remain responsible for that page.
2299 */
2300 ret = bio_readpage_error(bio, page, start, end,
2301 failed_mirror, NULL);
2297 if (ret == 0) { 2302 if (ret == 0) {
2303error_handled:
2298 uptodate = 2304 uptodate =
2299 test_bit(BIO_UPTODATE, &bio->bi_flags); 2305 test_bit(BIO_UPTODATE, &bio->bi_flags);
2300 if (err) 2306 if (err)
@@ -2302,6 +2308,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2302 uncache_state(&cached); 2308 uncache_state(&cached);
2303 continue; 2309 continue;
2304 } 2310 }
2311 if (tree->ops && tree->ops->readpage_io_failed_hook) {
2312 ret = tree->ops->readpage_io_failed_hook(
2313 bio, page, start, end,
2314 failed_mirror, state);
2315 if (ret == 0)
2316 goto error_handled;
2317 }
2305 } 2318 }
2306 2319
2307 if (uptodate) { 2320 if (uptodate) {