aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_io.c85
1 files changed, 30 insertions, 55 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 3e6e410002e5..ca4355ddea06 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1948,28 +1948,6 @@ static void check_page_uptodate(struct extent_io_tree *tree, struct page *page)
1948} 1948}
1949 1949
1950/* 1950/*
1951 * helper function to unlock a page if all the extents in the tree
1952 * for that page are unlocked
1953 */
1954static void check_page_locked(struct extent_io_tree *tree, struct page *page)
1955{
1956 u64 start = page_offset(page);
1957 u64 end = start + PAGE_CACHE_SIZE - 1;
1958 if (!test_range_bit(tree, start, end, EXTENT_LOCKED, 0, NULL))
1959 unlock_page(page);
1960}
1961
1962/*
1963 * helper function to end page writeback if all the extents
1964 * in the tree for that page are done with writeback
1965 */
1966static void check_page_writeback(struct extent_io_tree *tree,
1967 struct page *page)
1968{
1969 end_page_writeback(page);
1970}
1971
1972/*
1973 * When IO fails, either with EIO or csum verification fails, we 1951 * When IO fails, either with EIO or csum verification fails, we
1974 * try other mirrors that might have a good copy of the data. This 1952 * try other mirrors that might have a good copy of the data. This
1975 * io_failure_record is used to record state as we go through all the 1953 * io_failure_record is used to record state as we go through all the
@@ -2398,19 +2376,24 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
2398 struct extent_io_tree *tree; 2376 struct extent_io_tree *tree;
2399 u64 start; 2377 u64 start;
2400 u64 end; 2378 u64 end;
2401 int whole_page;
2402 2379
2403 do { 2380 do {
2404 struct page *page = bvec->bv_page; 2381 struct page *page = bvec->bv_page;
2405 tree = &BTRFS_I(page->mapping->host)->io_tree; 2382 tree = &BTRFS_I(page->mapping->host)->io_tree;
2406 2383
2407 start = page_offset(page) + bvec->bv_offset; 2384 /* We always issue full-page reads, but if some block
2408 end = start + bvec->bv_len - 1; 2385 * in a page fails to read, blk_update_request() will
2386 * advance bv_offset and adjust bv_len to compensate.
2387 * Print a warning for nonzero offsets, and an error
2388 * if they don't add up to a full page. */
2389 if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE)
2390 printk("%s page write in btrfs with offset %u and length %u\n",
2391 bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE
2392 ? KERN_ERR "partial" : KERN_INFO "incomplete",
2393 bvec->bv_offset, bvec->bv_len);
2409 2394
2410 if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE) 2395 start = page_offset(page);
2411 whole_page = 1; 2396 end = start + bvec->bv_offset + bvec->bv_len - 1;
2412 else
2413 whole_page = 0;
2414 2397
2415 if (--bvec >= bio->bi_io_vec) 2398 if (--bvec >= bio->bi_io_vec)
2416 prefetchw(&bvec->bv_page->flags); 2399 prefetchw(&bvec->bv_page->flags);
@@ -2418,10 +2401,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
2418 if (end_extent_writepage(page, err, start, end)) 2401 if (end_extent_writepage(page, err, start, end))
2419 continue; 2402 continue;
2420 2403
2421 if (whole_page) 2404 end_page_writeback(page);
2422 end_page_writeback(page);
2423 else
2424 check_page_writeback(tree, page);
2425 } while (bvec >= bio->bi_io_vec); 2405 } while (bvec >= bio->bi_io_vec);
2426 2406
2427 bio_put(bio); 2407 bio_put(bio);
@@ -2446,7 +2426,6 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2446 struct extent_io_tree *tree; 2426 struct extent_io_tree *tree;
2447 u64 start; 2427 u64 start;
2448 u64 end; 2428 u64 end;
2449 int whole_page;
2450 int mirror; 2429 int mirror;
2451 int ret; 2430 int ret;
2452 2431
@@ -2463,13 +2442,19 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2463 (long int)bio->bi_bdev); 2442 (long int)bio->bi_bdev);
2464 tree = &BTRFS_I(page->mapping->host)->io_tree; 2443 tree = &BTRFS_I(page->mapping->host)->io_tree;
2465 2444
2466 start = page_offset(page) + bvec->bv_offset; 2445 /* We always issue full-page reads, but if some block
2467 end = start + bvec->bv_len - 1; 2446 * in a page fails to read, blk_update_request() will
2447 * advance bv_offset and adjust bv_len to compensate.
2448 * Print a warning for nonzero offsets, and an error
2449 * if they don't add up to a full page. */
2450 if (bvec->bv_offset || bvec->bv_len != PAGE_CACHE_SIZE)
2451 printk("%s page read in btrfs with offset %u and length %u\n",
2452 bvec->bv_offset + bvec->bv_len != PAGE_CACHE_SIZE
2453 ? KERN_ERR "partial" : KERN_INFO "incomplete",
2454 bvec->bv_offset, bvec->bv_len);
2468 2455
2469 if (bvec->bv_offset == 0 && bvec->bv_len == PAGE_CACHE_SIZE) 2456 start = page_offset(page);
2470 whole_page = 1; 2457 end = start + bvec->bv_offset + bvec->bv_len - 1;
2471 else
2472 whole_page = 0;
2473 2458
2474 if (++bvec <= bvec_end) 2459 if (++bvec <= bvec_end)
2475 prefetchw(&bvec->bv_page->flags); 2460 prefetchw(&bvec->bv_page->flags);
@@ -2528,23 +2513,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
2528 } 2513 }
2529 unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC); 2514 unlock_extent_cached(tree, start, end, &cached, GFP_ATOMIC);
2530 2515
2531 if (whole_page) { 2516 if (uptodate) {
2532 if (uptodate) { 2517 SetPageUptodate(page);
2533 SetPageUptodate(page);
2534 } else {
2535 ClearPageUptodate(page);
2536 SetPageError(page);
2537 }
2538 unlock_page(page);
2539 } else { 2518 } else {
2540 if (uptodate) { 2519 ClearPageUptodate(page);
2541 check_page_uptodate(tree, page); 2520 SetPageError(page);
2542 } else {
2543 ClearPageUptodate(page);
2544 SetPageError(page);
2545 }
2546 check_page_locked(tree, page);
2547 } 2521 }
2522 unlock_page(page);
2548 } while (bvec <= bvec_end); 2523 } while (bvec <= bvec_end);
2549 2524
2550 bio_put(bio); 2525 bio_put(bio);