diff options
| -rw-r--r-- | fs/jfs/jfs_metapage.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index c350057087dd..07b6c5dfb4b6 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
| @@ -369,6 +369,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) | |||
| 369 | unsigned long bio_bytes = 0; | 369 | unsigned long bio_bytes = 0; |
| 370 | unsigned long bio_offset = 0; | 370 | unsigned long bio_offset = 0; |
| 371 | int offset; | 371 | int offset; |
| 372 | int bad_blocks = 0; | ||
| 372 | 373 | ||
| 373 | page_start = (sector_t)page->index << | 374 | page_start = (sector_t)page->index << |
| 374 | (PAGE_CACHE_SHIFT - inode->i_blkbits); | 375 | (PAGE_CACHE_SHIFT - inode->i_blkbits); |
| @@ -394,6 +395,7 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) | |||
| 394 | } | 395 | } |
| 395 | 396 | ||
| 396 | clear_bit(META_dirty, &mp->flag); | 397 | clear_bit(META_dirty, &mp->flag); |
| 398 | set_bit(META_io, &mp->flag); | ||
| 397 | block_offset = offset >> inode->i_blkbits; | 399 | block_offset = offset >> inode->i_blkbits; |
| 398 | lblock = page_start + block_offset; | 400 | lblock = page_start + block_offset; |
| 399 | if (bio) { | 401 | if (bio) { |
| @@ -402,7 +404,6 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) | |||
| 402 | len = min(xlen, blocks_per_mp); | 404 | len = min(xlen, blocks_per_mp); |
| 403 | xlen -= len; | 405 | xlen -= len; |
| 404 | bio_bytes += len << inode->i_blkbits; | 406 | bio_bytes += len << inode->i_blkbits; |
| 405 | set_bit(META_io, &mp->flag); | ||
| 406 | continue; | 407 | continue; |
| 407 | } | 408 | } |
| 408 | /* Not contiguous */ | 409 | /* Not contiguous */ |
| @@ -424,12 +425,14 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) | |||
| 424 | xlen = (PAGE_CACHE_SIZE - offset) >> inode->i_blkbits; | 425 | xlen = (PAGE_CACHE_SIZE - offset) >> inode->i_blkbits; |
| 425 | pblock = metapage_get_blocks(inode, lblock, &xlen); | 426 | pblock = metapage_get_blocks(inode, lblock, &xlen); |
| 426 | if (!pblock) { | 427 | if (!pblock) { |
| 427 | /* Need better error handling */ | ||
| 428 | printk(KERN_ERR "JFS: metapage_get_blocks failed\n"); | 428 | printk(KERN_ERR "JFS: metapage_get_blocks failed\n"); |
| 429 | dec_io(page, last_write_complete); | 429 | /* |
| 430 | * We already called inc_io(), but can't cancel it | ||
| 431 | * with dec_io() until we're done with the page | ||
| 432 | */ | ||
| 433 | bad_blocks++; | ||
| 430 | continue; | 434 | continue; |
| 431 | } | 435 | } |
| 432 | set_bit(META_io, &mp->flag); | ||
| 433 | len = min(xlen, (int)JFS_SBI(inode->i_sb)->nbperpage); | 436 | len = min(xlen, (int)JFS_SBI(inode->i_sb)->nbperpage); |
| 434 | 437 | ||
| 435 | bio = bio_alloc(GFP_NOFS, 1); | 438 | bio = bio_alloc(GFP_NOFS, 1); |
| @@ -459,6 +462,9 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) | |||
| 459 | 462 | ||
| 460 | unlock_page(page); | 463 | unlock_page(page); |
| 461 | 464 | ||
| 465 | if (bad_blocks) | ||
| 466 | goto err_out; | ||
| 467 | |||
| 462 | if (nr_underway == 0) | 468 | if (nr_underway == 0) |
| 463 | end_page_writeback(page); | 469 | end_page_writeback(page); |
| 464 | 470 | ||
| @@ -474,7 +480,9 @@ skip: | |||
| 474 | bio_put(bio); | 480 | bio_put(bio); |
| 475 | unlock_page(page); | 481 | unlock_page(page); |
| 476 | dec_io(page, last_write_complete); | 482 | dec_io(page, last_write_complete); |
| 477 | 483 | err_out: | |
| 484 | while (bad_blocks--) | ||
| 485 | dec_io(page, last_write_complete); | ||
| 478 | return -EIO; | 486 | return -EIO; |
| 479 | } | 487 | } |
| 480 | 488 | ||
