diff options
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index ffa7cc3370c7..4c3ce7a0a7a4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1244,7 +1244,7 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) | |||
1244 | 1244 | ||
1245 | while (index <= end_index) { | 1245 | while (index <= end_index) { |
1246 | page = find_get_page(tree->mapping, index); | 1246 | page = find_get_page(tree->mapping, index); |
1247 | BUG_ON(!page); | 1247 | BUG_ON(!page); /* Pages should be in the extent_io_tree */ |
1248 | set_page_writeback(page); | 1248 | set_page_writeback(page); |
1249 | page_cache_release(page); | 1249 | page_cache_release(page); |
1250 | index++; | 1250 | index++; |
@@ -1523,7 +1523,7 @@ again: | |||
1523 | goto out_failed; | 1523 | goto out_failed; |
1524 | } | 1524 | } |
1525 | } | 1525 | } |
1526 | BUG_ON(ret); | 1526 | BUG_ON(ret); /* Only valid values are 0 and -EAGAIN */ |
1527 | 1527 | ||
1528 | /* step three, lock the state bits for the whole range */ | 1528 | /* step three, lock the state bits for the whole range */ |
1529 | lock_extent_bits(tree, delalloc_start, delalloc_end, 0, &cached_state); | 1529 | lock_extent_bits(tree, delalloc_start, delalloc_end, 0, &cached_state); |
@@ -2200,7 +2200,6 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end) | |||
2200 | /* Writeback already completed */ | 2200 | /* Writeback already completed */ |
2201 | if (ret == 0) | 2201 | if (ret == 0) |
2202 | return 1; | 2202 | return 1; |
2203 | BUG_ON(ret < 0); | ||
2204 | } | 2203 | } |
2205 | 2204 | ||
2206 | if (!uptodate) { | 2205 | if (!uptodate) { |
@@ -2353,7 +2352,6 @@ error_handled: | |||
2353 | if (ret == 0) | 2352 | if (ret == 0) |
2354 | goto error_handled; | 2353 | goto error_handled; |
2355 | } | 2354 | } |
2356 | BUG_ON(ret < 0); | ||
2357 | } | 2355 | } |
2358 | 2356 | ||
2359 | if (uptodate) { | 2357 | if (uptodate) { |
@@ -2405,6 +2403,10 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | |||
2405 | return bio; | 2403 | return bio; |
2406 | } | 2404 | } |
2407 | 2405 | ||
2406 | /* | ||
2407 | * Since writes are async, they will only return -ENOMEM. | ||
2408 | * Reads can return the full range of I/O error conditions. | ||
2409 | */ | ||
2408 | static int __must_check submit_one_bio(int rw, struct bio *bio, | 2410 | static int __must_check submit_one_bio(int rw, struct bio *bio, |
2409 | int mirror_num, unsigned long bio_flags) | 2411 | int mirror_num, unsigned long bio_flags) |
2410 | { | 2412 | { |
@@ -2477,7 +2479,8 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, | |||
2477 | bio_add_page(bio, page, page_size, offset) < page_size) { | 2479 | bio_add_page(bio, page, page_size, offset) < page_size) { |
2478 | ret = submit_one_bio(rw, bio, mirror_num, | 2480 | ret = submit_one_bio(rw, bio, mirror_num, |
2479 | prev_bio_flags); | 2481 | prev_bio_flags); |
2480 | BUG_ON(ret < 0); | 2482 | if (ret < 0) |
2483 | return ret; | ||
2481 | bio = NULL; | 2484 | bio = NULL; |
2482 | } else { | 2485 | } else { |
2483 | return 0; | 2486 | return 0; |
@@ -2498,10 +2501,8 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, | |||
2498 | 2501 | ||
2499 | if (bio_ret) | 2502 | if (bio_ret) |
2500 | *bio_ret = bio; | 2503 | *bio_ret = bio; |
2501 | else { | 2504 | else |
2502 | ret = submit_one_bio(rw, bio, mirror_num, bio_flags); | 2505 | ret = submit_one_bio(rw, bio, mirror_num, bio_flags); |
2503 | BUG_ON(ret < 0); | ||
2504 | } | ||
2505 | 2506 | ||
2506 | return ret; | 2507 | return ret; |
2507 | } | 2508 | } |
@@ -2525,6 +2526,7 @@ static void set_page_extent_head(struct page *page, unsigned long len) | |||
2525 | * basic readpage implementation. Locked extent state structs are inserted | 2526 | * basic readpage implementation. Locked extent state structs are inserted |
2526 | * into the tree that are removed when the IO is done (by the end_io | 2527 | * into the tree that are removed when the IO is done (by the end_io |
2527 | * handlers) | 2528 | * handlers) |
2529 | * XXX JDM: This needs looking at to ensure proper page locking | ||
2528 | */ | 2530 | */ |
2529 | static int __extent_read_full_page(struct extent_io_tree *tree, | 2531 | static int __extent_read_full_page(struct extent_io_tree *tree, |
2530 | struct page *page, | 2532 | struct page *page, |
@@ -2687,6 +2689,7 @@ static int __extent_read_full_page(struct extent_io_tree *tree, | |||
2687 | end_bio_extent_readpage, mirror_num, | 2689 | end_bio_extent_readpage, mirror_num, |
2688 | *bio_flags, | 2690 | *bio_flags, |
2689 | this_bio_flag); | 2691 | this_bio_flag); |
2692 | BUG_ON(ret == -ENOMEM); | ||
2690 | nr++; | 2693 | nr++; |
2691 | *bio_flags = this_bio_flag; | 2694 | *bio_flags = this_bio_flag; |
2692 | } | 2695 | } |
@@ -2713,10 +2716,8 @@ int extent_read_full_page(struct extent_io_tree *tree, struct page *page, | |||
2713 | 2716 | ||
2714 | ret = __extent_read_full_page(tree, page, get_extent, &bio, mirror_num, | 2717 | ret = __extent_read_full_page(tree, page, get_extent, &bio, mirror_num, |
2715 | &bio_flags); | 2718 | &bio_flags); |
2716 | if (bio) { | 2719 | if (bio) |
2717 | ret = submit_one_bio(READ, bio, mirror_num, bio_flags); | 2720 | ret = submit_one_bio(READ, bio, mirror_num, bio_flags); |
2718 | BUG_ON(ret < 0); | ||
2719 | } | ||
2720 | return ret; | 2721 | return ret; |
2721 | } | 2722 | } |
2722 | 2723 | ||
@@ -2830,7 +2831,11 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
2830 | delalloc_end, | 2831 | delalloc_end, |
2831 | &page_started, | 2832 | &page_started, |
2832 | &nr_written); | 2833 | &nr_written); |
2833 | BUG_ON(ret); | 2834 | /* File system has been set read-only */ |
2835 | if (ret) { | ||
2836 | SetPageError(page); | ||
2837 | goto done; | ||
2838 | } | ||
2834 | /* | 2839 | /* |
2835 | * delalloc_end is already one less than the total | 2840 | * delalloc_end is already one less than the total |
2836 | * length, so we don't subtract one from | 2841 | * length, so we don't subtract one from |
@@ -3141,7 +3146,7 @@ static void flush_epd_write_bio(struct extent_page_data *epd) | |||
3141 | rw = WRITE_SYNC; | 3146 | rw = WRITE_SYNC; |
3142 | 3147 | ||
3143 | ret = submit_one_bio(rw, epd->bio, 0, 0); | 3148 | ret = submit_one_bio(rw, epd->bio, 0, 0); |
3144 | BUG_ON(ret < 0); | 3149 | BUG_ON(ret < 0); /* -ENOMEM */ |
3145 | epd->bio = NULL; | 3150 | epd->bio = NULL; |
3146 | } | 3151 | } |
3147 | } | 3152 | } |
@@ -3257,10 +3262,8 @@ int extent_readpages(struct extent_io_tree *tree, | |||
3257 | page_cache_release(page); | 3262 | page_cache_release(page); |
3258 | } | 3263 | } |
3259 | BUG_ON(!list_empty(pages)); | 3264 | BUG_ON(!list_empty(pages)); |
3260 | if (bio) { | 3265 | if (bio) |
3261 | int ret = submit_one_bio(READ, bio, 0, bio_flags); | 3266 | return submit_one_bio(READ, bio, 0, bio_flags); |
3262 | BUG_ON(ret < 0); | ||
3263 | } | ||
3264 | return 0; | 3267 | return 0; |
3265 | } | 3268 | } |
3266 | 3269 | ||
@@ -4090,7 +4093,8 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, | |||
4090 | 4093 | ||
4091 | if (bio) { | 4094 | if (bio) { |
4092 | err = submit_one_bio(READ, bio, mirror_num, bio_flags); | 4095 | err = submit_one_bio(READ, bio, mirror_num, bio_flags); |
4093 | BUG_ON(err < 0); | 4096 | if (err) |
4097 | return err; | ||
4094 | } | 4098 | } |
4095 | 4099 | ||
4096 | if (ret || wait != WAIT_COMPLETE) | 4100 | if (ret || wait != WAIT_COMPLETE) |