aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c69
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
2538static 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 */
2544static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) 2539static 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