diff options
-rw-r--r-- | fs/btrfs/compression.c | 10 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 35 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 15 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 4 | ||||
-rw-r--r-- | fs/f2fs/data.c | 13 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 12 | ||||
-rw-r--r-- | fs/logfs/dev_bdev.c | 18 | ||||
-rw-r--r-- | fs/mpage.c | 17 | ||||
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 34 |
10 files changed, 67 insertions, 102 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 1499b27b4186..eac6784e43d7 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -201,18 +201,16 @@ csum_failed: | |||
201 | if (cb->errors) { | 201 | if (cb->errors) { |
202 | bio_io_error(cb->orig_bio); | 202 | bio_io_error(cb->orig_bio); |
203 | } else { | 203 | } else { |
204 | int bio_index = 0; | 204 | int i; |
205 | struct bio_vec *bvec = cb->orig_bio->bi_io_vec; | 205 | struct bio_vec *bvec; |
206 | 206 | ||
207 | /* | 207 | /* |
208 | * we have verified the checksum already, set page | 208 | * we have verified the checksum already, set page |
209 | * checked so the end_io handlers know about it | 209 | * checked so the end_io handlers know about it |
210 | */ | 210 | */ |
211 | while (bio_index < cb->orig_bio->bi_vcnt) { | 211 | bio_for_each_segment_all(bvec, cb->orig_bio, i) |
212 | SetPageChecked(bvec->bv_page); | 212 | SetPageChecked(bvec->bv_page); |
213 | bvec++; | 213 | |
214 | bio_index++; | ||
215 | } | ||
216 | bio_endio(cb->orig_bio, 0); | 214 | bio_endio(cb->orig_bio, 0); |
217 | } | 215 | } |
218 | 216 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8072cfa8a3b1..5a10c61adafc 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -842,20 +842,17 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
842 | 842 | ||
843 | static int btree_csum_one_bio(struct bio *bio) | 843 | static int btree_csum_one_bio(struct bio *bio) |
844 | { | 844 | { |
845 | struct bio_vec *bvec = bio->bi_io_vec; | 845 | struct bio_vec *bvec; |
846 | int bio_index = 0; | ||
847 | struct btrfs_root *root; | 846 | struct btrfs_root *root; |
848 | int ret = 0; | 847 | int i, ret = 0; |
849 | 848 | ||
850 | WARN_ON(bio->bi_vcnt <= 0); | 849 | bio_for_each_segment_all(bvec, bio, i) { |
851 | while (bio_index < bio->bi_vcnt) { | ||
852 | root = BTRFS_I(bvec->bv_page->mapping->host)->root; | 850 | root = BTRFS_I(bvec->bv_page->mapping->host)->root; |
853 | ret = csum_dirty_buffer(root, bvec->bv_page); | 851 | ret = csum_dirty_buffer(root, bvec->bv_page); |
854 | if (ret) | 852 | if (ret) |
855 | break; | 853 | break; |
856 | bio_index++; | ||
857 | bvec++; | ||
858 | } | 854 | } |
855 | |||
859 | return ret; | 856 | return ret; |
860 | } | 857 | } |
861 | 858 | ||
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index ff43802a7c88..8b5f9e1d1f0e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2332,12 +2332,13 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end) | |||
2332 | */ | 2332 | */ |
2333 | static void end_bio_extent_writepage(struct bio *bio, int err) | 2333 | static void end_bio_extent_writepage(struct bio *bio, int err) |
2334 | { | 2334 | { |
2335 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 2335 | struct bio_vec *bvec; |
2336 | struct extent_io_tree *tree; | 2336 | struct extent_io_tree *tree; |
2337 | u64 start; | 2337 | u64 start; |
2338 | u64 end; | 2338 | u64 end; |
2339 | int i; | ||
2339 | 2340 | ||
2340 | do { | 2341 | bio_for_each_segment_all(bvec, bio, i) { |
2341 | struct page *page = bvec->bv_page; | 2342 | struct page *page = bvec->bv_page; |
2342 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 2343 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2343 | 2344 | ||
@@ -2355,14 +2356,11 @@ static void end_bio_extent_writepage(struct bio *bio, int err) | |||
2355 | start = page_offset(page); | 2356 | start = page_offset(page); |
2356 | end = start + bvec->bv_offset + bvec->bv_len - 1; | 2357 | end = start + bvec->bv_offset + bvec->bv_len - 1; |
2357 | 2358 | ||
2358 | if (--bvec >= bio->bi_io_vec) | ||
2359 | prefetchw(&bvec->bv_page->flags); | ||
2360 | |||
2361 | if (end_extent_writepage(page, err, start, end)) | 2359 | if (end_extent_writepage(page, err, start, end)) |
2362 | continue; | 2360 | continue; |
2363 | 2361 | ||
2364 | end_page_writeback(page); | 2362 | end_page_writeback(page); |
2365 | } while (bvec >= bio->bi_io_vec); | 2363 | } |
2366 | 2364 | ||
2367 | bio_put(bio); | 2365 | bio_put(bio); |
2368 | } | 2366 | } |
@@ -2392,9 +2390,8 @@ endio_readpage_release_extent(struct extent_io_tree *tree, u64 start, u64 len, | |||
2392 | */ | 2390 | */ |
2393 | static void end_bio_extent_readpage(struct bio *bio, int err) | 2391 | static void end_bio_extent_readpage(struct bio *bio, int err) |
2394 | { | 2392 | { |
2393 | struct bio_vec *bvec; | ||
2395 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 2394 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
2396 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
2397 | struct bio_vec *bvec = bio->bi_io_vec; | ||
2398 | struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); | 2395 | struct btrfs_io_bio *io_bio = btrfs_io_bio(bio); |
2399 | struct extent_io_tree *tree; | 2396 | struct extent_io_tree *tree; |
2400 | u64 offset = 0; | 2397 | u64 offset = 0; |
@@ -2405,11 +2402,12 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
2405 | u64 extent_len = 0; | 2402 | u64 extent_len = 0; |
2406 | int mirror; | 2403 | int mirror; |
2407 | int ret; | 2404 | int ret; |
2405 | int i; | ||
2408 | 2406 | ||
2409 | if (err) | 2407 | if (err) |
2410 | uptodate = 0; | 2408 | uptodate = 0; |
2411 | 2409 | ||
2412 | do { | 2410 | bio_for_each_segment_all(bvec, bio, i) { |
2413 | struct page *page = bvec->bv_page; | 2411 | struct page *page = bvec->bv_page; |
2414 | struct inode *inode = page->mapping->host; | 2412 | struct inode *inode = page->mapping->host; |
2415 | 2413 | ||
@@ -2433,9 +2431,6 @@ static void end_bio_extent_readpage(struct bio *bio, int err) | |||
2433 | end = start + bvec->bv_offset + bvec->bv_len - 1; | 2431 | end = start + bvec->bv_offset + bvec->bv_len - 1; |
2434 | len = bvec->bv_len; | 2432 | len = bvec->bv_len; |
2435 | 2433 | ||
2436 | if (++bvec <= bvec_end) | ||
2437 | prefetchw(&bvec->bv_page->flags); | ||
2438 | |||
2439 | mirror = io_bio->mirror_num; | 2434 | mirror = io_bio->mirror_num; |
2440 | if (likely(uptodate && tree->ops && | 2435 | if (likely(uptodate && tree->ops && |
2441 | tree->ops->readpage_end_io_hook)) { | 2436 | tree->ops->readpage_end_io_hook)) { |
@@ -2516,7 +2511,7 @@ readpage_ok: | |||
2516 | extent_start = start; | 2511 | extent_start = start; |
2517 | extent_len = end + 1 - start; | 2512 | extent_len = end + 1 - start; |
2518 | } | 2513 | } |
2519 | } while (bvec <= bvec_end); | 2514 | } |
2520 | 2515 | ||
2521 | if (extent_len) | 2516 | if (extent_len) |
2522 | endio_readpage_release_extent(tree, extent_start, extent_len, | 2517 | endio_readpage_release_extent(tree, extent_start, extent_len, |
@@ -2547,7 +2542,6 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | |||
2547 | } | 2542 | } |
2548 | 2543 | ||
2549 | if (bio) { | 2544 | if (bio) { |
2550 | bio->bi_size = 0; | ||
2551 | bio->bi_bdev = bdev; | 2545 | bio->bi_bdev = bdev; |
2552 | bio->bi_sector = first_sector; | 2546 | bio->bi_sector = first_sector; |
2553 | btrfs_bio = btrfs_io_bio(bio); | 2547 | btrfs_bio = btrfs_io_bio(bio); |
@@ -3410,20 +3404,18 @@ static void end_extent_buffer_writeback(struct extent_buffer *eb) | |||
3410 | 3404 | ||
3411 | static void end_bio_extent_buffer_writepage(struct bio *bio, int err) | 3405 | static void end_bio_extent_buffer_writepage(struct bio *bio, int err) |
3412 | { | 3406 | { |
3413 | int uptodate = err == 0; | 3407 | struct bio_vec *bvec; |
3414 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
3415 | struct extent_buffer *eb; | 3408 | struct extent_buffer *eb; |
3416 | int done; | 3409 | int i, done; |
3417 | 3410 | ||
3418 | do { | 3411 | bio_for_each_segment_all(bvec, bio, i) { |
3419 | struct page *page = bvec->bv_page; | 3412 | struct page *page = bvec->bv_page; |
3420 | 3413 | ||
3421 | bvec--; | ||
3422 | eb = (struct extent_buffer *)page->private; | 3414 | eb = (struct extent_buffer *)page->private; |
3423 | BUG_ON(!eb); | 3415 | BUG_ON(!eb); |
3424 | done = atomic_dec_and_test(&eb->io_pages); | 3416 | done = atomic_dec_and_test(&eb->io_pages); |
3425 | 3417 | ||
3426 | if (!uptodate || test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { | 3418 | if (err || test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { |
3427 | set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); | 3419 | set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); |
3428 | ClearPageUptodate(page); | 3420 | ClearPageUptodate(page); |
3429 | SetPageError(page); | 3421 | SetPageError(page); |
@@ -3435,10 +3427,9 @@ static void end_bio_extent_buffer_writepage(struct bio *bio, int err) | |||
3435 | continue; | 3427 | continue; |
3436 | 3428 | ||
3437 | end_extent_buffer_writeback(eb); | 3429 | end_extent_buffer_writeback(eb); |
3438 | } while (bvec >= bio->bi_io_vec); | 3430 | } |
3439 | 3431 | ||
3440 | bio_put(bio); | 3432 | bio_put(bio); |
3441 | |||
3442 | } | 3433 | } |
3443 | 3434 | ||
3444 | static int write_one_eb(struct extent_buffer *eb, | 3435 | static int write_one_eb(struct extent_buffer *eb, |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f1a77449d032..d6630dc130ba 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -6779,17 +6779,16 @@ unlock_err: | |||
6779 | static void btrfs_endio_direct_read(struct bio *bio, int err) | 6779 | static void btrfs_endio_direct_read(struct bio *bio, int err) |
6780 | { | 6780 | { |
6781 | struct btrfs_dio_private *dip = bio->bi_private; | 6781 | struct btrfs_dio_private *dip = bio->bi_private; |
6782 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; | 6782 | struct bio_vec *bvec; |
6783 | struct bio_vec *bvec = bio->bi_io_vec; | ||
6784 | struct inode *inode = dip->inode; | 6783 | struct inode *inode = dip->inode; |
6785 | struct btrfs_root *root = BTRFS_I(inode)->root; | 6784 | struct btrfs_root *root = BTRFS_I(inode)->root; |
6786 | struct bio *dio_bio; | 6785 | struct bio *dio_bio; |
6787 | u32 *csums = (u32 *)dip->csum; | 6786 | u32 *csums = (u32 *)dip->csum; |
6788 | int index = 0; | ||
6789 | u64 start; | 6787 | u64 start; |
6788 | int i; | ||
6790 | 6789 | ||
6791 | start = dip->logical_offset; | 6790 | start = dip->logical_offset; |
6792 | do { | 6791 | bio_for_each_segment_all(bvec, bio, i) { |
6793 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { | 6792 | if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) { |
6794 | struct page *page = bvec->bv_page; | 6793 | struct page *page = bvec->bv_page; |
6795 | char *kaddr; | 6794 | char *kaddr; |
@@ -6805,18 +6804,16 @@ static void btrfs_endio_direct_read(struct bio *bio, int err) | |||
6805 | local_irq_restore(flags); | 6804 | local_irq_restore(flags); |
6806 | 6805 | ||
6807 | flush_dcache_page(bvec->bv_page); | 6806 | flush_dcache_page(bvec->bv_page); |
6808 | if (csum != csums[index]) { | 6807 | if (csum != csums[i]) { |
6809 | btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u", | 6808 | btrfs_err(root->fs_info, "csum failed ino %llu off %llu csum %u expected csum %u", |
6810 | btrfs_ino(inode), start, csum, | 6809 | btrfs_ino(inode), start, csum, |
6811 | csums[index]); | 6810 | csums[i]); |
6812 | err = -EIO; | 6811 | err = -EIO; |
6813 | } | 6812 | } |
6814 | } | 6813 | } |
6815 | 6814 | ||
6816 | start += bvec->bv_len; | 6815 | start += bvec->bv_len; |
6817 | bvec++; | 6816 | } |
6818 | index++; | ||
6819 | } while (bvec <= bvec_end); | ||
6820 | 6817 | ||
6821 | unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, | 6818 | unlock_extent(&BTRFS_I(inode)->io_tree, dip->logical_offset, |
6822 | dip->logical_offset + dip->bytes - 1); | 6819 | dip->logical_offset + dip->bytes - 1); |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index d488f80ee32d..a31e4da14508 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -65,9 +65,9 @@ static void ext4_finish_bio(struct bio *bio) | |||
65 | { | 65 | { |
66 | int i; | 66 | int i; |
67 | int error = !test_bit(BIO_UPTODATE, &bio->bi_flags); | 67 | int error = !test_bit(BIO_UPTODATE, &bio->bi_flags); |
68 | struct bio_vec *bvec; | ||
68 | 69 | ||
69 | for (i = 0; i < bio->bi_vcnt; i++) { | 70 | bio_for_each_segment_all(bvec, bio, i) { |
70 | struct bio_vec *bvec = &bio->bi_io_vec[i]; | ||
71 | struct page *page = bvec->bv_page; | 71 | struct page *page = bvec->bv_page; |
72 | struct buffer_head *bh, *head; | 72 | struct buffer_head *bh, *head; |
73 | unsigned bio_start = bvec->bv_offset; | 73 | unsigned bio_start = bvec->bv_offset; |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index aa3438c571fa..a4949096cf4c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
@@ -351,23 +351,20 @@ repeat: | |||
351 | 351 | ||
352 | static void read_end_io(struct bio *bio, int err) | 352 | static void read_end_io(struct bio *bio, int err) |
353 | { | 353 | { |
354 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 354 | struct bio_vec *bvec; |
355 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 355 | int i; |
356 | 356 | ||
357 | do { | 357 | bio_for_each_segment_all(bvec, bio, i) { |
358 | struct page *page = bvec->bv_page; | 358 | struct page *page = bvec->bv_page; |
359 | 359 | ||
360 | if (--bvec >= bio->bi_io_vec) | 360 | if (!err) { |
361 | prefetchw(&bvec->bv_page->flags); | ||
362 | |||
363 | if (uptodate) { | ||
364 | SetPageUptodate(page); | 361 | SetPageUptodate(page); |
365 | } else { | 362 | } else { |
366 | ClearPageUptodate(page); | 363 | ClearPageUptodate(page); |
367 | SetPageError(page); | 364 | SetPageError(page); |
368 | } | 365 | } |
369 | unlock_page(page); | 366 | unlock_page(page); |
370 | } while (bvec >= bio->bi_io_vec); | 367 | } |
371 | bio_put(bio); | 368 | bio_put(bio); |
372 | } | 369 | } |
373 | 370 | ||
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index fa284d397199..a90c6bc0d129 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -575,16 +575,14 @@ static const struct segment_allocation default_salloc_ops = { | |||
575 | 575 | ||
576 | static void f2fs_end_io_write(struct bio *bio, int err) | 576 | static void f2fs_end_io_write(struct bio *bio, int err) |
577 | { | 577 | { |
578 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | ||
579 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | ||
580 | struct bio_private *p = bio->bi_private; | 578 | struct bio_private *p = bio->bi_private; |
579 | struct bio_vec *bvec; | ||
580 | int i; | ||
581 | 581 | ||
582 | do { | 582 | bio_for_each_segment_all(bvec, bio, i) { |
583 | struct page *page = bvec->bv_page; | 583 | struct page *page = bvec->bv_page; |
584 | 584 | ||
585 | if (--bvec >= bio->bi_io_vec) | 585 | if (err) { |
586 | prefetchw(&bvec->bv_page->flags); | ||
587 | if (!uptodate) { | ||
588 | SetPageError(page); | 586 | SetPageError(page); |
589 | if (page->mapping) | 587 | if (page->mapping) |
590 | set_bit(AS_EIO, &page->mapping->flags); | 588 | set_bit(AS_EIO, &page->mapping->flags); |
@@ -593,7 +591,7 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
593 | } | 591 | } |
594 | end_page_writeback(page); | 592 | end_page_writeback(page); |
595 | dec_page_count(p->sbi, F2FS_WRITEBACK); | 593 | dec_page_count(p->sbi, F2FS_WRITEBACK); |
596 | } while (bvec >= bio->bi_io_vec); | 594 | } |
597 | 595 | ||
598 | if (p->is_sync) | 596 | if (p->is_sync) |
599 | complete(p->wait); | 597 | complete(p->wait); |
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 0f95f0d0b313..e6df3be3b31b 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c | |||
@@ -56,22 +56,18 @@ static DECLARE_WAIT_QUEUE_HEAD(wq); | |||
56 | static void writeseg_end_io(struct bio *bio, int err) | 56 | static void writeseg_end_io(struct bio *bio, int err) |
57 | { | 57 | { |
58 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 58 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
59 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 59 | struct bio_vec *bvec; |
60 | int i; | ||
60 | struct super_block *sb = bio->bi_private; | 61 | struct super_block *sb = bio->bi_private; |
61 | struct logfs_super *super = logfs_super(sb); | 62 | struct logfs_super *super = logfs_super(sb); |
62 | struct page *page; | ||
63 | 63 | ||
64 | BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */ | 64 | BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */ |
65 | BUG_ON(err); | 65 | BUG_ON(err); |
66 | BUG_ON(bio->bi_vcnt == 0); | 66 | |
67 | do { | 67 | bio_for_each_segment_all(bvec, bio, i) { |
68 | page = bvec->bv_page; | 68 | end_page_writeback(bvec->bv_page); |
69 | if (--bvec >= bio->bi_io_vec) | 69 | page_cache_release(bvec->bv_page); |
70 | prefetchw(&bvec->bv_page->flags); | 70 | } |
71 | |||
72 | end_page_writeback(page); | ||
73 | page_cache_release(page); | ||
74 | } while (bvec >= bio->bi_io_vec); | ||
75 | bio_put(bio); | 71 | bio_put(bio); |
76 | if (atomic_dec_and_test(&super->s_pending_writes)) | 72 | if (atomic_dec_and_test(&super->s_pending_writes)) |
77 | wake_up(&wq); | 73 | wake_up(&wq); |
diff --git a/fs/mpage.c b/fs/mpage.c index 0face1c4d4c6..dd6d5878f4d9 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -43,16 +43,14 @@ | |||
43 | */ | 43 | */ |
44 | static void mpage_end_io(struct bio *bio, int err) | 44 | static void mpage_end_io(struct bio *bio, int err) |
45 | { | 45 | { |
46 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 46 | struct bio_vec *bv; |
47 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 47 | int i; |
48 | 48 | ||
49 | do { | 49 | bio_for_each_segment_all(bv, bio, i) { |
50 | struct page *page = bvec->bv_page; | 50 | struct page *page = bv->bv_page; |
51 | 51 | ||
52 | if (--bvec >= bio->bi_io_vec) | ||
53 | prefetchw(&bvec->bv_page->flags); | ||
54 | if (bio_data_dir(bio) == READ) { | 52 | if (bio_data_dir(bio) == READ) { |
55 | if (uptodate) { | 53 | if (!err) { |
56 | SetPageUptodate(page); | 54 | SetPageUptodate(page); |
57 | } else { | 55 | } else { |
58 | ClearPageUptodate(page); | 56 | ClearPageUptodate(page); |
@@ -60,14 +58,15 @@ static void mpage_end_io(struct bio *bio, int err) | |||
60 | } | 58 | } |
61 | unlock_page(page); | 59 | unlock_page(page); |
62 | } else { /* bio_data_dir(bio) == WRITE */ | 60 | } else { /* bio_data_dir(bio) == WRITE */ |
63 | if (!uptodate) { | 61 | if (err) { |
64 | SetPageError(page); | 62 | SetPageError(page); |
65 | if (page->mapping) | 63 | if (page->mapping) |
66 | set_bit(AS_EIO, &page->mapping->flags); | 64 | set_bit(AS_EIO, &page->mapping->flags); |
67 | } | 65 | } |
68 | end_page_writeback(page); | 66 | end_page_writeback(page); |
69 | } | 67 | } |
70 | } while (bvec >= bio->bi_io_vec); | 68 | } |
69 | |||
71 | bio_put(bio); | 70 | bio_put(bio); |
72 | } | 71 | } |
73 | 72 | ||
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index e242bbf72972..da768923bf7c 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c | |||
@@ -201,18 +201,14 @@ static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw, | |||
201 | static void bl_end_io_read(struct bio *bio, int err) | 201 | static void bl_end_io_read(struct bio *bio, int err) |
202 | { | 202 | { |
203 | struct parallel_io *par = bio->bi_private; | 203 | struct parallel_io *par = bio->bi_private; |
204 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 204 | struct bio_vec *bvec; |
205 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 205 | int i; |
206 | 206 | ||
207 | do { | 207 | if (!err) |
208 | struct page *page = bvec->bv_page; | 208 | bio_for_each_segment_all(bvec, bio, i) |
209 | SetPageUptodate(bvec->bv_page); | ||
209 | 210 | ||
210 | if (--bvec >= bio->bi_io_vec) | 211 | if (err) { |
211 | prefetchw(&bvec->bv_page->flags); | ||
212 | if (uptodate) | ||
213 | SetPageUptodate(page); | ||
214 | } while (bvec >= bio->bi_io_vec); | ||
215 | if (!uptodate) { | ||
216 | struct nfs_read_data *rdata = par->data; | 212 | struct nfs_read_data *rdata = par->data; |
217 | struct nfs_pgio_header *header = rdata->header; | 213 | struct nfs_pgio_header *header = rdata->header; |
218 | 214 | ||
@@ -383,20 +379,16 @@ static void mark_extents_written(struct pnfs_block_layout *bl, | |||
383 | static void bl_end_io_write_zero(struct bio *bio, int err) | 379 | static void bl_end_io_write_zero(struct bio *bio, int err) |
384 | { | 380 | { |
385 | struct parallel_io *par = bio->bi_private; | 381 | struct parallel_io *par = bio->bi_private; |
386 | const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 382 | struct bio_vec *bvec; |
387 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 383 | int i; |
388 | |||
389 | do { | ||
390 | struct page *page = bvec->bv_page; | ||
391 | 384 | ||
392 | if (--bvec >= bio->bi_io_vec) | 385 | bio_for_each_segment_all(bvec, bio, i) { |
393 | prefetchw(&bvec->bv_page->flags); | ||
394 | /* This is the zeroing page we added */ | 386 | /* This is the zeroing page we added */ |
395 | end_page_writeback(page); | 387 | end_page_writeback(bvec->bv_page); |
396 | page_cache_release(page); | 388 | page_cache_release(bvec->bv_page); |
397 | } while (bvec >= bio->bi_io_vec); | 389 | } |
398 | 390 | ||
399 | if (unlikely(!uptodate)) { | 391 | if (unlikely(err)) { |
400 | struct nfs_write_data *data = par->data; | 392 | struct nfs_write_data *data = par->data; |
401 | struct nfs_pgio_header *header = data->header; | 393 | struct nfs_pgio_header *header = data->header; |
402 | 394 | ||