diff options
-rw-r--r-- | fs/ext4/extents.c | 69 |
1 files changed, 7 insertions, 62 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 820278410220..a0e623055955 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2535,77 +2535,22 @@ void ext4_ext_release(struct super_block *sb) | |||
2535 | #endif | 2535 | #endif |
2536 | } | 2536 | } |
2537 | 2537 | ||
2538 | static void bi_complete(struct bio *bio, int error) | ||
2539 | { | ||
2540 | complete((struct completion *)bio->bi_private); | ||
2541 | } | ||
2542 | |||
2543 | /* FIXME!! we need to try to merge to left or right after zero-out */ | 2538 | /* FIXME!! we need to try to merge to left or right after zero-out */ |
2544 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | 2539 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) |
2545 | { | 2540 | { |
2541 | ext4_fsblk_t ee_pblock; | ||
2542 | unsigned int ee_len; | ||
2546 | int ret; | 2543 | int ret; |
2547 | struct bio *bio; | ||
2548 | int blkbits, blocksize; | ||
2549 | sector_t ee_pblock; | ||
2550 | struct completion event; | ||
2551 | unsigned int ee_len, len, done, offset; | ||
2552 | 2544 | ||
2553 | |||
2554 | blkbits = inode->i_blkbits; | ||
2555 | blocksize = inode->i_sb->s_blocksize; | ||
2556 | ee_len = ext4_ext_get_actual_len(ex); | 2545 | ee_len = ext4_ext_get_actual_len(ex); |
2557 | ee_pblock = ext_pblock(ex); | 2546 | ee_pblock = ext_pblock(ex); |
2558 | 2547 | ||
2559 | /* convert ee_pblock to 512 byte sectors */ | 2548 | ret = sb_issue_zeroout(inode->i_sb, ee_pblock, ee_len, |
2560 | ee_pblock = ee_pblock << (blkbits - 9); | 2549 | GFP_NOFS, BLKDEV_IFL_WAIT); |
2561 | 2550 | if (ret > 0) | |
2562 | while (ee_len > 0) { | 2551 | ret = 0; |
2563 | |||
2564 | if (ee_len > BIO_MAX_PAGES) | ||
2565 | len = BIO_MAX_PAGES; | ||
2566 | else | ||
2567 | len = ee_len; | ||
2568 | |||
2569 | bio = bio_alloc(GFP_NOIO, len); | ||
2570 | if (!bio) | ||
2571 | return -ENOMEM; | ||
2572 | |||
2573 | bio->bi_sector = ee_pblock; | ||
2574 | bio->bi_bdev = inode->i_sb->s_bdev; | ||
2575 | |||
2576 | done = 0; | ||
2577 | offset = 0; | ||
2578 | while (done < len) { | ||
2579 | ret = bio_add_page(bio, ZERO_PAGE(0), | ||
2580 | blocksize, offset); | ||
2581 | if (ret != blocksize) { | ||
2582 | /* | ||
2583 | * We can't add any more pages because of | ||
2584 | * hardware limitations. Start a new bio. | ||
2585 | */ | ||
2586 | break; | ||
2587 | } | ||
2588 | done++; | ||
2589 | offset += blocksize; | ||
2590 | if (offset >= PAGE_CACHE_SIZE) | ||
2591 | offset = 0; | ||
2592 | } | ||
2593 | |||
2594 | init_completion(&event); | ||
2595 | bio->bi_private = &event; | ||
2596 | bio->bi_end_io = bi_complete; | ||
2597 | submit_bio(WRITE, bio); | ||
2598 | wait_for_completion(&event); | ||
2599 | 2552 | ||
2600 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { | 2553 | return ret; |
2601 | bio_put(bio); | ||
2602 | return -EIO; | ||
2603 | } | ||
2604 | bio_put(bio); | ||
2605 | ee_len -= done; | ||
2606 | ee_pblock += done << (blkbits - 9); | ||
2607 | } | ||
2608 | return 0; | ||
2609 | } | 2554 | } |
2610 | 2555 | ||
2611 | #define EXT4_EXT_ZERO_LEN 7 | 2556 | #define EXT4_EXT_ZERO_LEN 7 |