aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-05-16 19:00:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-05-16 19:00:00 -0400
commite35fd6609b2fee54484d520deccb8f18bf7d38f3 (patch)
tree9b786445602819074f599c282b31bead166e8c03 /fs/ext4
parent8e48dcfbd7c0892b4cfd064d682cc4c95a29df32 (diff)
ext4: Add new abstraction ext4_map_blocks() underneath ext4_get_blocks()
Jack up ext4_get_blocks() and add a new function, ext4_map_blocks() which uses a much smaller structure, struct ext4_map_blocks which is 20 bytes, as opposed to a struct buffer_head, which nearly 5 times bigger on an x86_64 machine. By switching things to use ext4_map_blocks(), we can save stack space by using ext4_map_blocks() since we can avoid allocating a struct buffer_head on the stack. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/ext4.h30
-rw-r--r--fs/ext4/extents.c237
-rw-r--r--fs/ext4/inode.c102
3 files changed, 199 insertions, 170 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index d266003cac3e..57fc0e5c0918 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -126,6 +126,29 @@ struct ext4_allocation_request {
126}; 126};
127 127
128/* 128/*
129 * Logical to physical block mapping, used by ext4_map_blocks()
130 *
131 * This structure is used to pass requests into ext4_map_blocks() as
132 * well as to store the information returned by ext4_map_blocks(). It
133 * takes less room on the stack than a struct buffer_head.
134 */
135#define EXT4_MAP_NEW (1 << BH_New)
136#define EXT4_MAP_MAPPED (1 << BH_Mapped)
137#define EXT4_MAP_UNWRITTEN (1 << BH_Unwritten)
138#define EXT4_MAP_BOUNDARY (1 << BH_Boundary)
139#define EXT4_MAP_UNINIT (1 << BH_Uninit)
140#define EXT4_MAP_FLAGS (EXT4_MAP_NEW | EXT4_MAP_MAPPED |\
141 EXT4_MAP_UNWRITTEN | EXT4_MAP_BOUNDARY |\
142 EXT4_MAP_UNINIT)
143
144struct ext4_map_blocks {
145 ext4_fsblk_t m_pblk;
146 ext4_lblk_t m_lblk;
147 unsigned int m_len;
148 unsigned int m_flags;
149};
150
151/*
129 * For delayed allocation tracking 152 * For delayed allocation tracking
130 */ 153 */
131struct mpage_da_data { 154struct mpage_da_data {
@@ -1773,9 +1796,8 @@ extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
1773extern int ext4_ext_writepage_trans_blocks(struct inode *, int); 1796extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
1774extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, 1797extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks,
1775 int chunk); 1798 int chunk);
1776extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 1799extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
1777 ext4_lblk_t iblock, unsigned int max_blocks, 1800 struct ext4_map_blocks *map, int flags);
1778 struct buffer_head *bh_result, int flags);
1779extern void ext4_ext_truncate(struct inode *); 1801extern void ext4_ext_truncate(struct inode *);
1780extern void ext4_ext_init(struct super_block *); 1802extern void ext4_ext_init(struct super_block *);
1781extern void ext4_ext_release(struct super_block *); 1803extern void ext4_ext_release(struct super_block *);
@@ -1783,6 +1805,8 @@ extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
1783 loff_t len); 1805 loff_t len);
1784extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset, 1806extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
1785 ssize_t len); 1807 ssize_t len);
1808extern int ext4_map_blocks(handle_t *handle, struct inode *inode,
1809 struct ext4_map_blocks *map, int flags);
1786extern int ext4_get_blocks(handle_t *handle, struct inode *inode, 1810extern int ext4_get_blocks(handle_t *handle, struct inode *inode,
1787 sector_t block, unsigned int max_blocks, 1811 sector_t block, unsigned int max_blocks,
1788 struct buffer_head *bh, int flags); 1812 struct buffer_head *bh, int flags);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 8a8f9f0be911..37f938789344 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2611,7 +2611,7 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
2611 2611
2612#define EXT4_EXT_ZERO_LEN 7 2612#define EXT4_EXT_ZERO_LEN 7
2613/* 2613/*
2614 * This function is called by ext4_ext_get_blocks() if someone tries to write 2614 * This function is called by ext4_ext_map_blocks() if someone tries to write
2615 * to an uninitialized extent. It may result in splitting the uninitialized 2615 * to an uninitialized extent. It may result in splitting the uninitialized
2616 * extent into multiple extents (upto three - one initialized and two 2616 * extent into multiple extents (upto three - one initialized and two
2617 * uninitialized). 2617 * uninitialized).
@@ -2621,10 +2621,9 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
2621 * c> Splits in three extents: Somone is writing in middle of the extent 2621 * c> Splits in three extents: Somone is writing in middle of the extent
2622 */ 2622 */
2623static int ext4_ext_convert_to_initialized(handle_t *handle, 2623static int ext4_ext_convert_to_initialized(handle_t *handle,
2624 struct inode *inode, 2624 struct inode *inode,
2625 struct ext4_ext_path *path, 2625 struct ext4_map_blocks *map,
2626 ext4_lblk_t iblock, 2626 struct ext4_ext_path *path)
2627 unsigned int max_blocks)
2628{ 2627{
2629 struct ext4_extent *ex, newex, orig_ex; 2628 struct ext4_extent *ex, newex, orig_ex;
2630 struct ext4_extent *ex1 = NULL; 2629 struct ext4_extent *ex1 = NULL;
@@ -2640,20 +2639,20 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2640 2639
2641 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical" 2640 ext_debug("ext4_ext_convert_to_initialized: inode %lu, logical"
2642 "block %llu, max_blocks %u\n", inode->i_ino, 2641 "block %llu, max_blocks %u\n", inode->i_ino,
2643 (unsigned long long)iblock, max_blocks); 2642 (unsigned long long)map->m_lblk, map->m_len);
2644 2643
2645 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 2644 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
2646 inode->i_sb->s_blocksize_bits; 2645 inode->i_sb->s_blocksize_bits;
2647 if (eof_block < iblock + max_blocks) 2646 if (eof_block < map->m_lblk + map->m_len)
2648 eof_block = iblock + max_blocks; 2647 eof_block = map->m_lblk + map->m_len;
2649 2648
2650 depth = ext_depth(inode); 2649 depth = ext_depth(inode);
2651 eh = path[depth].p_hdr; 2650 eh = path[depth].p_hdr;
2652 ex = path[depth].p_ext; 2651 ex = path[depth].p_ext;
2653 ee_block = le32_to_cpu(ex->ee_block); 2652 ee_block = le32_to_cpu(ex->ee_block);
2654 ee_len = ext4_ext_get_actual_len(ex); 2653 ee_len = ext4_ext_get_actual_len(ex);
2655 allocated = ee_len - (iblock - ee_block); 2654 allocated = ee_len - (map->m_lblk - ee_block);
2656 newblock = iblock - ee_block + ext_pblock(ex); 2655 newblock = map->m_lblk - ee_block + ext_pblock(ex);
2657 2656
2658 ex2 = ex; 2657 ex2 = ex;
2659 orig_ex.ee_block = ex->ee_block; 2658 orig_ex.ee_block = ex->ee_block;
@@ -2683,10 +2682,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2683 return allocated; 2682 return allocated;
2684 } 2683 }
2685 2684
2686 /* ex1: ee_block to iblock - 1 : uninitialized */ 2685 /* ex1: ee_block to map->m_lblk - 1 : uninitialized */
2687 if (iblock > ee_block) { 2686 if (map->m_lblk > ee_block) {
2688 ex1 = ex; 2687 ex1 = ex;
2689 ex1->ee_len = cpu_to_le16(iblock - ee_block); 2688 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
2690 ext4_ext_mark_uninitialized(ex1); 2689 ext4_ext_mark_uninitialized(ex1);
2691 ex2 = &newex; 2690 ex2 = &newex;
2692 } 2691 }
@@ -2695,15 +2694,15 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2695 * we insert ex3, if ex1 is NULL. This is to avoid temporary 2694 * we insert ex3, if ex1 is NULL. This is to avoid temporary
2696 * overlap of blocks. 2695 * overlap of blocks.
2697 */ 2696 */
2698 if (!ex1 && allocated > max_blocks) 2697 if (!ex1 && allocated > map->m_len)
2699 ex2->ee_len = cpu_to_le16(max_blocks); 2698 ex2->ee_len = cpu_to_le16(map->m_len);
2700 /* ex3: to ee_block + ee_len : uninitialised */ 2699 /* ex3: to ee_block + ee_len : uninitialised */
2701 if (allocated > max_blocks) { 2700 if (allocated > map->m_len) {
2702 unsigned int newdepth; 2701 unsigned int newdepth;
2703 /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */ 2702 /* If extent has less than EXT4_EXT_ZERO_LEN zerout directly */
2704 if (allocated <= EXT4_EXT_ZERO_LEN && may_zeroout) { 2703 if (allocated <= EXT4_EXT_ZERO_LEN && may_zeroout) {
2705 /* 2704 /*
2706 * iblock == ee_block is handled by the zerouout 2705 * map->m_lblk == ee_block is handled by the zerouout
2707 * at the beginning. 2706 * at the beginning.
2708 * Mark first half uninitialized. 2707 * Mark first half uninitialized.
2709 * Mark second half initialized and zero out the 2708 * Mark second half initialized and zero out the
@@ -2716,7 +2715,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2716 ext4_ext_dirty(handle, inode, path + depth); 2715 ext4_ext_dirty(handle, inode, path + depth);
2717 2716
2718 ex3 = &newex; 2717 ex3 = &newex;
2719 ex3->ee_block = cpu_to_le32(iblock); 2718 ex3->ee_block = cpu_to_le32(map->m_lblk);
2720 ext4_ext_store_pblock(ex3, newblock); 2719 ext4_ext_store_pblock(ex3, newblock);
2721 ex3->ee_len = cpu_to_le16(allocated); 2720 ex3->ee_len = cpu_to_le16(allocated);
2722 err = ext4_ext_insert_extent(handle, inode, path, 2721 err = ext4_ext_insert_extent(handle, inode, path,
@@ -2729,7 +2728,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2729 ex->ee_len = orig_ex.ee_len; 2728 ex->ee_len = orig_ex.ee_len;
2730 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); 2729 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2731 ext4_ext_dirty(handle, inode, path + depth); 2730 ext4_ext_dirty(handle, inode, path + depth);
2732 /* blocks available from iblock */ 2731 /* blocks available from map->m_lblk */
2733 return allocated; 2732 return allocated;
2734 2733
2735 } else if (err) 2734 } else if (err)
@@ -2751,8 +2750,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2751 */ 2750 */
2752 depth = ext_depth(inode); 2751 depth = ext_depth(inode);
2753 ext4_ext_drop_refs(path); 2752 ext4_ext_drop_refs(path);
2754 path = ext4_ext_find_extent(inode, 2753 path = ext4_ext_find_extent(inode, map->m_lblk,
2755 iblock, path); 2754 path);
2756 if (IS_ERR(path)) { 2755 if (IS_ERR(path)) {
2757 err = PTR_ERR(path); 2756 err = PTR_ERR(path);
2758 return err; 2757 return err;
@@ -2772,9 +2771,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2772 return allocated; 2771 return allocated;
2773 } 2772 }
2774 ex3 = &newex; 2773 ex3 = &newex;
2775 ex3->ee_block = cpu_to_le32(iblock + max_blocks); 2774 ex3->ee_block = cpu_to_le32(map->m_lblk + map->m_len);
2776 ext4_ext_store_pblock(ex3, newblock + max_blocks); 2775 ext4_ext_store_pblock(ex3, newblock + map->m_len);
2777 ex3->ee_len = cpu_to_le16(allocated - max_blocks); 2776 ex3->ee_len = cpu_to_le16(allocated - map->m_len);
2778 ext4_ext_mark_uninitialized(ex3); 2777 ext4_ext_mark_uninitialized(ex3);
2779 err = ext4_ext_insert_extent(handle, inode, path, ex3, 0); 2778 err = ext4_ext_insert_extent(handle, inode, path, ex3, 0);
2780 if (err == -ENOSPC && may_zeroout) { 2779 if (err == -ENOSPC && may_zeroout) {
@@ -2787,7 +2786,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2787 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); 2786 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2788 ext4_ext_dirty(handle, inode, path + depth); 2787 ext4_ext_dirty(handle, inode, path + depth);
2789 /* zeroed the full extent */ 2788 /* zeroed the full extent */
2790 /* blocks available from iblock */ 2789 /* blocks available from map->m_lblk */
2791 return allocated; 2790 return allocated;
2792 2791
2793 } else if (err) 2792 } else if (err)
@@ -2807,7 +2806,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2807 2806
2808 depth = newdepth; 2807 depth = newdepth;
2809 ext4_ext_drop_refs(path); 2808 ext4_ext_drop_refs(path);
2810 path = ext4_ext_find_extent(inode, iblock, path); 2809 path = ext4_ext_find_extent(inode, map->m_lblk, path);
2811 if (IS_ERR(path)) { 2810 if (IS_ERR(path)) {
2812 err = PTR_ERR(path); 2811 err = PTR_ERR(path);
2813 goto out; 2812 goto out;
@@ -2821,14 +2820,14 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2821 if (err) 2820 if (err)
2822 goto out; 2821 goto out;
2823 2822
2824 allocated = max_blocks; 2823 allocated = map->m_len;
2825 2824
2826 /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying 2825 /* If extent has less than EXT4_EXT_ZERO_LEN and we are trying
2827 * to insert a extent in the middle zerout directly 2826 * to insert a extent in the middle zerout directly
2828 * otherwise give the extent a chance to merge to left 2827 * otherwise give the extent a chance to merge to left
2829 */ 2828 */
2830 if (le16_to_cpu(orig_ex.ee_len) <= EXT4_EXT_ZERO_LEN && 2829 if (le16_to_cpu(orig_ex.ee_len) <= EXT4_EXT_ZERO_LEN &&
2831 iblock != ee_block && may_zeroout) { 2830 map->m_lblk != ee_block && may_zeroout) {
2832 err = ext4_ext_zeroout(inode, &orig_ex); 2831 err = ext4_ext_zeroout(inode, &orig_ex);
2833 if (err) 2832 if (err)
2834 goto fix_extent_len; 2833 goto fix_extent_len;
@@ -2838,7 +2837,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2838 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); 2837 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2839 ext4_ext_dirty(handle, inode, path + depth); 2838 ext4_ext_dirty(handle, inode, path + depth);
2840 /* zero out the first half */ 2839 /* zero out the first half */
2841 /* blocks available from iblock */ 2840 /* blocks available from map->m_lblk */
2842 return allocated; 2841 return allocated;
2843 } 2842 }
2844 } 2843 }
@@ -2849,12 +2848,12 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2849 */ 2848 */
2850 if (ex1 && ex1 != ex) { 2849 if (ex1 && ex1 != ex) {
2851 ex1 = ex; 2850 ex1 = ex;
2852 ex1->ee_len = cpu_to_le16(iblock - ee_block); 2851 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
2853 ext4_ext_mark_uninitialized(ex1); 2852 ext4_ext_mark_uninitialized(ex1);
2854 ex2 = &newex; 2853 ex2 = &newex;
2855 } 2854 }
2856 /* ex2: iblock to iblock + maxblocks-1 : initialised */ 2855 /* ex2: map->m_lblk to map->m_lblk + maxblocks-1 : initialised */
2857 ex2->ee_block = cpu_to_le32(iblock); 2856 ex2->ee_block = cpu_to_le32(map->m_lblk);
2858 ext4_ext_store_pblock(ex2, newblock); 2857 ext4_ext_store_pblock(ex2, newblock);
2859 ex2->ee_len = cpu_to_le16(allocated); 2858 ex2->ee_len = cpu_to_le16(allocated);
2860 if (ex2 != ex) 2859 if (ex2 != ex)
@@ -2924,7 +2923,7 @@ fix_extent_len:
2924} 2923}
2925 2924
2926/* 2925/*
2927 * This function is called by ext4_ext_get_blocks() from 2926 * This function is called by ext4_ext_map_blocks() from
2928 * ext4_get_blocks_dio_write() when DIO to write 2927 * ext4_get_blocks_dio_write() when DIO to write
2929 * to an uninitialized extent. 2928 * to an uninitialized extent.
2930 * 2929 *
@@ -2947,9 +2946,8 @@ fix_extent_len:
2947 */ 2946 */
2948static int ext4_split_unwritten_extents(handle_t *handle, 2947static int ext4_split_unwritten_extents(handle_t *handle,
2949 struct inode *inode, 2948 struct inode *inode,
2949 struct ext4_map_blocks *map,
2950 struct ext4_ext_path *path, 2950 struct ext4_ext_path *path,
2951 ext4_lblk_t iblock,
2952 unsigned int max_blocks,
2953 int flags) 2951 int flags)
2954{ 2952{
2955 struct ext4_extent *ex, newex, orig_ex; 2953 struct ext4_extent *ex, newex, orig_ex;
@@ -2965,20 +2963,20 @@ static int ext4_split_unwritten_extents(handle_t *handle,
2965 2963
2966 ext_debug("ext4_split_unwritten_extents: inode %lu, logical" 2964 ext_debug("ext4_split_unwritten_extents: inode %lu, logical"
2967 "block %llu, max_blocks %u\n", inode->i_ino, 2965 "block %llu, max_blocks %u\n", inode->i_ino,
2968 (unsigned long long)iblock, max_blocks); 2966 (unsigned long long)map->m_lblk, map->m_len);
2969 2967
2970 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> 2968 eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
2971 inode->i_sb->s_blocksize_bits; 2969 inode->i_sb->s_blocksize_bits;
2972 if (eof_block < iblock + max_blocks) 2970 if (eof_block < map->m_lblk + map->m_len)
2973 eof_block = iblock + max_blocks; 2971 eof_block = map->m_lblk + map->m_len;
2974 2972
2975 depth = ext_depth(inode); 2973 depth = ext_depth(inode);
2976 eh = path[depth].p_hdr; 2974 eh = path[depth].p_hdr;
2977 ex = path[depth].p_ext; 2975 ex = path[depth].p_ext;
2978 ee_block = le32_to_cpu(ex->ee_block); 2976 ee_block = le32_to_cpu(ex->ee_block);
2979 ee_len = ext4_ext_get_actual_len(ex); 2977 ee_len = ext4_ext_get_actual_len(ex);
2980 allocated = ee_len - (iblock - ee_block); 2978 allocated = ee_len - (map->m_lblk - ee_block);
2981 newblock = iblock - ee_block + ext_pblock(ex); 2979 newblock = map->m_lblk - ee_block + ext_pblock(ex);
2982 2980
2983 ex2 = ex; 2981 ex2 = ex;
2984 orig_ex.ee_block = ex->ee_block; 2982 orig_ex.ee_block = ex->ee_block;
@@ -2996,16 +2994,16 @@ static int ext4_split_unwritten_extents(handle_t *handle,
2996 * block where the write begins, and the write completely 2994 * block where the write begins, and the write completely
2997 * covers the extent, then we don't need to split it. 2995 * covers the extent, then we don't need to split it.
2998 */ 2996 */
2999 if ((iblock == ee_block) && (allocated <= max_blocks)) 2997 if ((map->m_lblk == ee_block) && (allocated <= map->m_len))
3000 return allocated; 2998 return allocated;
3001 2999
3002 err = ext4_ext_get_access(handle, inode, path + depth); 3000 err = ext4_ext_get_access(handle, inode, path + depth);
3003 if (err) 3001 if (err)
3004 goto out; 3002 goto out;
3005 /* ex1: ee_block to iblock - 1 : uninitialized */ 3003 /* ex1: ee_block to map->m_lblk - 1 : uninitialized */
3006 if (iblock > ee_block) { 3004 if (map->m_lblk > ee_block) {
3007 ex1 = ex; 3005 ex1 = ex;
3008 ex1->ee_len = cpu_to_le16(iblock - ee_block); 3006 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
3009 ext4_ext_mark_uninitialized(ex1); 3007 ext4_ext_mark_uninitialized(ex1);
3010 ex2 = &newex; 3008 ex2 = &newex;
3011 } 3009 }
@@ -3014,15 +3012,15 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3014 * we insert ex3, if ex1 is NULL. This is to avoid temporary 3012 * we insert ex3, if ex1 is NULL. This is to avoid temporary
3015 * overlap of blocks. 3013 * overlap of blocks.
3016 */ 3014 */
3017 if (!ex1 && allocated > max_blocks) 3015 if (!ex1 && allocated > map->m_len)
3018 ex2->ee_len = cpu_to_le16(max_blocks); 3016 ex2->ee_len = cpu_to_le16(map->m_len);
3019 /* ex3: to ee_block + ee_len : uninitialised */ 3017 /* ex3: to ee_block + ee_len : uninitialised */
3020 if (allocated > max_blocks) { 3018 if (allocated > map->m_len) {
3021 unsigned int newdepth; 3019 unsigned int newdepth;
3022 ex3 = &newex; 3020 ex3 = &newex;
3023 ex3->ee_block = cpu_to_le32(iblock + max_blocks); 3021 ex3->ee_block = cpu_to_le32(map->m_lblk + map->m_len);
3024 ext4_ext_store_pblock(ex3, newblock + max_blocks); 3022 ext4_ext_store_pblock(ex3, newblock + map->m_len);
3025 ex3->ee_len = cpu_to_le16(allocated - max_blocks); 3023 ex3->ee_len = cpu_to_le16(allocated - map->m_len);
3026 ext4_ext_mark_uninitialized(ex3); 3024 ext4_ext_mark_uninitialized(ex3);
3027 err = ext4_ext_insert_extent(handle, inode, path, ex3, flags); 3025 err = ext4_ext_insert_extent(handle, inode, path, ex3, flags);
3028 if (err == -ENOSPC && may_zeroout) { 3026 if (err == -ENOSPC && may_zeroout) {
@@ -3035,7 +3033,7 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3035 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex)); 3033 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
3036 ext4_ext_dirty(handle, inode, path + depth); 3034 ext4_ext_dirty(handle, inode, path + depth);
3037 /* zeroed the full extent */ 3035 /* zeroed the full extent */
3038 /* blocks available from iblock */ 3036 /* blocks available from map->m_lblk */
3039 return allocated; 3037 return allocated;
3040 3038
3041 } else if (err) 3039 } else if (err)
@@ -3055,7 +3053,7 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3055 3053
3056 depth = newdepth; 3054 depth = newdepth;
3057 ext4_ext_drop_refs(path); 3055 ext4_ext_drop_refs(path);
3058 path = ext4_ext_find_extent(inode, iblock, path); 3056 path = ext4_ext_find_extent(inode, map->m_lblk, path);
3059 if (IS_ERR(path)) { 3057 if (IS_ERR(path)) {
3060 err = PTR_ERR(path); 3058 err = PTR_ERR(path);
3061 goto out; 3059 goto out;
@@ -3069,7 +3067,7 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3069 if (err) 3067 if (err)
3070 goto out; 3068 goto out;
3071 3069
3072 allocated = max_blocks; 3070 allocated = map->m_len;
3073 } 3071 }
3074 /* 3072 /*
3075 * If there was a change of depth as part of the 3073 * If there was a change of depth as part of the
@@ -3078,15 +3076,15 @@ static int ext4_split_unwritten_extents(handle_t *handle,
3078 */ 3076 */
3079 if (ex1 && ex1 != ex) { 3077 if (ex1 && ex1 != ex) {
3080 ex1 = ex; 3078 ex1 = ex;
3081 ex1->ee_len = cpu_to_le16(iblock - ee_block); 3079 ex1->ee_len = cpu_to_le16(map->m_lblk - ee_block);
3082 ext4_ext_mark_uninitialized(ex1); 3080 ext4_ext_mark_uninitialized(ex1);
3083 ex2 = &newex; 3081 ex2 = &newex;
3084 } 3082 }
3085 /* 3083 /*
3086 * ex2: iblock to iblock + maxblocks-1 : to be direct IO written, 3084 * ex2: map->m_lblk to map->m_lblk + map->m_len-1 : to be written
3087 * uninitialised still. 3085 * using direct I/O, uninitialised still.
3088 */ 3086 */
3089 ex2->ee_block = cpu_to_le32(iblock); 3087 ex2->ee_block = cpu_to_le32(map->m_lblk);
3090 ext4_ext_store_pblock(ex2, newblock); 3088 ext4_ext_store_pblock(ex2, newblock);
3091 ex2->ee_len = cpu_to_le16(allocated); 3089 ex2->ee_len = cpu_to_le16(allocated);
3092 ext4_ext_mark_uninitialized(ex2); 3090 ext4_ext_mark_uninitialized(ex2);
@@ -3188,10 +3186,9 @@ static void unmap_underlying_metadata_blocks(struct block_device *bdev,
3188 3186
3189static int 3187static int
3190ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode, 3188ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3191 ext4_lblk_t iblock, unsigned int max_blocks, 3189 struct ext4_map_blocks *map,
3192 struct ext4_ext_path *path, int flags, 3190 struct ext4_ext_path *path, int flags,
3193 unsigned int allocated, struct buffer_head *bh_result, 3191 unsigned int allocated, ext4_fsblk_t newblock)
3194 ext4_fsblk_t newblock)
3195{ 3192{
3196 int ret = 0; 3193 int ret = 0;
3197 int err = 0; 3194 int err = 0;
@@ -3199,15 +3196,14 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3199 3196
3200 ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical" 3197 ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical"
3201 "block %llu, max_blocks %u, flags %d, allocated %u", 3198 "block %llu, max_blocks %u, flags %d, allocated %u",
3202 inode->i_ino, (unsigned long long)iblock, max_blocks, 3199 inode->i_ino, (unsigned long long)map->m_lblk, map->m_len,
3203 flags, allocated); 3200 flags, allocated);
3204 ext4_ext_show_leaf(inode, path); 3201 ext4_ext_show_leaf(inode, path);
3205 3202
3206 /* get_block() before submit the IO, split the extent */ 3203 /* get_block() before submit the IO, split the extent */
3207 if ((flags & EXT4_GET_BLOCKS_PRE_IO)) { 3204 if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
3208 ret = ext4_split_unwritten_extents(handle, 3205 ret = ext4_split_unwritten_extents(handle, inode, map,
3209 inode, path, iblock, 3206 path, flags);
3210 max_blocks, flags);
3211 /* 3207 /*
3212 * Flag the inode(non aio case) or end_io struct (aio case) 3208 * Flag the inode(non aio case) or end_io struct (aio case)
3213 * that this IO needs to convertion to written when IO is 3209 * that this IO needs to convertion to written when IO is
@@ -3218,7 +3214,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3218 else 3214 else
3219 ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN); 3215 ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
3220 if (ext4_should_dioread_nolock(inode)) 3216 if (ext4_should_dioread_nolock(inode))
3221 set_buffer_uninit(bh_result); 3217 map->m_flags |= EXT4_MAP_UNINIT;
3222 goto out; 3218 goto out;
3223 } 3219 }
3224 /* IO end_io complete, convert the filled extent to written */ 3220 /* IO end_io complete, convert the filled extent to written */
@@ -3246,14 +3242,12 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3246 * the buffer head will be unmapped so that 3242 * the buffer head will be unmapped so that
3247 * a read from the block returns 0s. 3243 * a read from the block returns 0s.
3248 */ 3244 */
3249 set_buffer_unwritten(bh_result); 3245 map->m_flags |= EXT4_MAP_UNWRITTEN;
3250 goto out1; 3246 goto out1;
3251 } 3247 }
3252 3248
3253 /* buffered write, writepage time, convert*/ 3249 /* buffered write, writepage time, convert*/
3254 ret = ext4_ext_convert_to_initialized(handle, inode, 3250 ret = ext4_ext_convert_to_initialized(handle, inode, map, path);
3255 path, iblock,
3256 max_blocks);
3257 if (ret >= 0) 3251 if (ret >= 0)
3258 ext4_update_inode_fsync_trans(handle, inode, 1); 3252 ext4_update_inode_fsync_trans(handle, inode, 1);
3259out: 3253out:
@@ -3262,7 +3256,7 @@ out:
3262 goto out2; 3256 goto out2;
3263 } else 3257 } else
3264 allocated = ret; 3258 allocated = ret;
3265 set_buffer_new(bh_result); 3259 map->m_flags |= EXT4_MAP_NEW;
3266 /* 3260 /*
3267 * if we allocated more blocks than requested 3261 * if we allocated more blocks than requested
3268 * we need to make sure we unmap the extra block 3262 * we need to make sure we unmap the extra block
@@ -3270,11 +3264,11 @@ out:
3270 * unmapped later when we find the buffer_head marked 3264 * unmapped later when we find the buffer_head marked
3271 * new. 3265 * new.
3272 */ 3266 */
3273 if (allocated > max_blocks) { 3267 if (allocated > map->m_len) {
3274 unmap_underlying_metadata_blocks(inode->i_sb->s_bdev, 3268 unmap_underlying_metadata_blocks(inode->i_sb->s_bdev,
3275 newblock + max_blocks, 3269 newblock + map->m_len,
3276 allocated - max_blocks); 3270 allocated - map->m_len);
3277 allocated = max_blocks; 3271 allocated = map->m_len;
3278 } 3272 }
3279 3273
3280 /* 3274 /*
@@ -3288,13 +3282,13 @@ out:
3288 ext4_da_update_reserve_space(inode, allocated, 0); 3282 ext4_da_update_reserve_space(inode, allocated, 0);
3289 3283
3290map_out: 3284map_out:
3291 set_buffer_mapped(bh_result); 3285 map->m_flags |= EXT4_MAP_MAPPED;
3292out1: 3286out1:
3293 if (allocated > max_blocks) 3287 if (allocated > map->m_len)
3294 allocated = max_blocks; 3288 allocated = map->m_len;
3295 ext4_ext_show_leaf(inode, path); 3289 ext4_ext_show_leaf(inode, path);
3296 bh_result->b_bdev = inode->i_sb->s_bdev; 3290 map->m_pblk = newblock;
3297 bh_result->b_blocknr = newblock; 3291 map->m_len = allocated;
3298out2: 3292out2:
3299 if (path) { 3293 if (path) {
3300 ext4_ext_drop_refs(path); 3294 ext4_ext_drop_refs(path);
@@ -3320,10 +3314,8 @@ out2:
3320 * 3314 *
3321 * return < 0, error case. 3315 * return < 0, error case.
3322 */ 3316 */
3323int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 3317int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
3324 ext4_lblk_t iblock, 3318 struct ext4_map_blocks *map, int flags)
3325 unsigned int max_blocks, struct buffer_head *bh_result,
3326 int flags)
3327{ 3319{
3328 struct ext4_ext_path *path = NULL; 3320 struct ext4_ext_path *path = NULL;
3329 struct ext4_extent_header *eh; 3321 struct ext4_extent_header *eh;
@@ -3334,12 +3326,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3334 struct ext4_allocation_request ar; 3326 struct ext4_allocation_request ar;
3335 ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio; 3327 ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
3336 3328
3337 __clear_bit(BH_New, &bh_result->b_state);
3338 ext_debug("blocks %u/%u requested for inode %lu\n", 3329 ext_debug("blocks %u/%u requested for inode %lu\n",
3339 iblock, max_blocks, inode->i_ino); 3330 map->m_lblk, map->m_len, inode->i_ino);
3340 3331
3341 /* check in cache */ 3332 /* check in cache */
3342 cache_type = ext4_ext_in_cache(inode, iblock, &newex); 3333 cache_type = ext4_ext_in_cache(inode, map->m_lblk, &newex);
3343 if (cache_type) { 3334 if (cache_type) {
3344 if (cache_type == EXT4_EXT_CACHE_GAP) { 3335 if (cache_type == EXT4_EXT_CACHE_GAP) {
3345 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { 3336 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
@@ -3352,12 +3343,12 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3352 /* we should allocate requested block */ 3343 /* we should allocate requested block */
3353 } else if (cache_type == EXT4_EXT_CACHE_EXTENT) { 3344 } else if (cache_type == EXT4_EXT_CACHE_EXTENT) {
3354 /* block is already allocated */ 3345 /* block is already allocated */
3355 newblock = iblock 3346 newblock = map->m_lblk
3356 - le32_to_cpu(newex.ee_block) 3347 - le32_to_cpu(newex.ee_block)
3357 + ext_pblock(&newex); 3348 + ext_pblock(&newex);
3358 /* number of remaining blocks in the extent */ 3349 /* number of remaining blocks in the extent */
3359 allocated = ext4_ext_get_actual_len(&newex) - 3350 allocated = ext4_ext_get_actual_len(&newex) -
3360 (iblock - le32_to_cpu(newex.ee_block)); 3351 (map->m_lblk - le32_to_cpu(newex.ee_block));
3361 goto out; 3352 goto out;
3362 } else { 3353 } else {
3363 BUG(); 3354 BUG();
@@ -3365,7 +3356,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3365 } 3356 }
3366 3357
3367 /* find extent for this block */ 3358 /* find extent for this block */
3368 path = ext4_ext_find_extent(inode, iblock, NULL); 3359 path = ext4_ext_find_extent(inode, map->m_lblk, NULL);
3369 if (IS_ERR(path)) { 3360 if (IS_ERR(path)) {
3370 err = PTR_ERR(path); 3361 err = PTR_ERR(path);
3371 path = NULL; 3362 path = NULL;
@@ -3382,7 +3373,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3382 if (unlikely(path[depth].p_ext == NULL && depth != 0)) { 3373 if (unlikely(path[depth].p_ext == NULL && depth != 0)) {
3383 EXT4_ERROR_INODE(inode, "bad extent address " 3374 EXT4_ERROR_INODE(inode, "bad extent address "
3384 "iblock: %d, depth: %d pblock %lld", 3375 "iblock: %d, depth: %d pblock %lld",
3385 iblock, depth, path[depth].p_block); 3376 map->m_lblk, depth, path[depth].p_block);
3386 err = -EIO; 3377 err = -EIO;
3387 goto out2; 3378 goto out2;
3388 } 3379 }
@@ -3400,12 +3391,12 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3400 */ 3391 */
3401 ee_len = ext4_ext_get_actual_len(ex); 3392 ee_len = ext4_ext_get_actual_len(ex);
3402 /* if found extent covers block, simply return it */ 3393 /* if found extent covers block, simply return it */
3403 if (in_range(iblock, ee_block, ee_len)) { 3394 if (in_range(map->m_lblk, ee_block, ee_len)) {
3404 newblock = iblock - ee_block + ee_start; 3395 newblock = map->m_lblk - ee_block + ee_start;
3405 /* number of remaining blocks in the extent */ 3396 /* number of remaining blocks in the extent */
3406 allocated = ee_len - (iblock - ee_block); 3397 allocated = ee_len - (map->m_lblk - ee_block);
3407 ext_debug("%u fit into %u:%d -> %llu\n", iblock, 3398 ext_debug("%u fit into %u:%d -> %llu\n", map->m_lblk,
3408 ee_block, ee_len, newblock); 3399 ee_block, ee_len, newblock);
3409 3400
3410 /* Do not put uninitialized extent in the cache */ 3401 /* Do not put uninitialized extent in the cache */
3411 if (!ext4_ext_is_uninitialized(ex)) { 3402 if (!ext4_ext_is_uninitialized(ex)) {
@@ -3415,8 +3406,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3415 goto out; 3406 goto out;
3416 } 3407 }
3417 ret = ext4_ext_handle_uninitialized_extents(handle, 3408 ret = ext4_ext_handle_uninitialized_extents(handle,
3418 inode, iblock, max_blocks, path, 3409 inode, map, path, flags, allocated,
3419 flags, allocated, bh_result, newblock); 3410 newblock);
3420 return ret; 3411 return ret;
3421 } 3412 }
3422 } 3413 }
@@ -3430,7 +3421,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3430 * put just found gap into cache to speed up 3421 * put just found gap into cache to speed up
3431 * subsequent requests 3422 * subsequent requests
3432 */ 3423 */
3433 ext4_ext_put_gap_in_cache(inode, path, iblock); 3424 ext4_ext_put_gap_in_cache(inode, path, map->m_lblk);
3434 goto out2; 3425 goto out2;
3435 } 3426 }
3436 /* 3427 /*
@@ -3438,11 +3429,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3438 */ 3429 */
3439 3430
3440 /* find neighbour allocated blocks */ 3431 /* find neighbour allocated blocks */
3441 ar.lleft = iblock; 3432 ar.lleft = map->m_lblk;
3442 err = ext4_ext_search_left(inode, path, &ar.lleft, &ar.pleft); 3433 err = ext4_ext_search_left(inode, path, &ar.lleft, &ar.pleft);
3443 if (err) 3434 if (err)
3444 goto out2; 3435 goto out2;
3445 ar.lright = iblock; 3436 ar.lright = map->m_lblk;
3446 err = ext4_ext_search_right(inode, path, &ar.lright, &ar.pright); 3437 err = ext4_ext_search_right(inode, path, &ar.lright, &ar.pright);
3447 if (err) 3438 if (err)
3448 goto out2; 3439 goto out2;
@@ -3453,26 +3444,26 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3453 * EXT_INIT_MAX_LEN and for an uninitialized extent this limit is 3444 * EXT_INIT_MAX_LEN and for an uninitialized extent this limit is
3454 * EXT_UNINIT_MAX_LEN. 3445 * EXT_UNINIT_MAX_LEN.
3455 */ 3446 */
3456 if (max_blocks > EXT_INIT_MAX_LEN && 3447 if (map->m_len > EXT_INIT_MAX_LEN &&
3457 !(flags & EXT4_GET_BLOCKS_UNINIT_EXT)) 3448 !(flags & EXT4_GET_BLOCKS_UNINIT_EXT))
3458 max_blocks = EXT_INIT_MAX_LEN; 3449 map->m_len = EXT_INIT_MAX_LEN;
3459 else if (max_blocks > EXT_UNINIT_MAX_LEN && 3450 else if (map->m_len > EXT_UNINIT_MAX_LEN &&
3460 (flags & EXT4_GET_BLOCKS_UNINIT_EXT)) 3451 (flags & EXT4_GET_BLOCKS_UNINIT_EXT))
3461 max_blocks = EXT_UNINIT_MAX_LEN; 3452 map->m_len = EXT_UNINIT_MAX_LEN;
3462 3453
3463 /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ 3454 /* Check if we can really insert (m_lblk)::(m_lblk + m_len) extent */
3464 newex.ee_block = cpu_to_le32(iblock); 3455 newex.ee_block = cpu_to_le32(map->m_lblk);
3465 newex.ee_len = cpu_to_le16(max_blocks); 3456 newex.ee_len = cpu_to_le16(map->m_len);
3466 err = ext4_ext_check_overlap(inode, &newex, path); 3457 err = ext4_ext_check_overlap(inode, &newex, path);
3467 if (err) 3458 if (err)
3468 allocated = ext4_ext_get_actual_len(&newex); 3459 allocated = ext4_ext_get_actual_len(&newex);
3469 else 3460 else
3470 allocated = max_blocks; 3461 allocated = map->m_len;
3471 3462
3472 /* allocate new block */ 3463 /* allocate new block */
3473 ar.inode = inode; 3464 ar.inode = inode;
3474 ar.goal = ext4_ext_find_goal(inode, path, iblock); 3465 ar.goal = ext4_ext_find_goal(inode, path, map->m_lblk);
3475 ar.logical = iblock; 3466 ar.logical = map->m_lblk;
3476 ar.len = allocated; 3467 ar.len = allocated;
3477 if (S_ISREG(inode->i_mode)) 3468 if (S_ISREG(inode->i_mode))
3478 ar.flags = EXT4_MB_HINT_DATA; 3469 ar.flags = EXT4_MB_HINT_DATA;
@@ -3506,7 +3497,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3506 EXT4_STATE_DIO_UNWRITTEN); 3497 EXT4_STATE_DIO_UNWRITTEN);
3507 } 3498 }
3508 if (ext4_should_dioread_nolock(inode)) 3499 if (ext4_should_dioread_nolock(inode))
3509 set_buffer_uninit(bh_result); 3500 map->m_flags |= EXT4_MAP_UNINIT;
3510 } 3501 }
3511 3502
3512 if (unlikely(EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) { 3503 if (unlikely(EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) {
@@ -3518,7 +3509,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3518 goto out2; 3509 goto out2;
3519 } 3510 }
3520 last_ex = EXT_LAST_EXTENT(eh); 3511 last_ex = EXT_LAST_EXTENT(eh);
3521 if (iblock + ar.len > le32_to_cpu(last_ex->ee_block) 3512 if (map->m_lblk + ar.len > le32_to_cpu(last_ex->ee_block)
3522 + ext4_ext_get_actual_len(last_ex)) 3513 + ext4_ext_get_actual_len(last_ex))
3523 EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL; 3514 EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL;
3524 } 3515 }
@@ -3536,9 +3527,9 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3536 /* previous routine could use block we allocated */ 3527 /* previous routine could use block we allocated */
3537 newblock = ext_pblock(&newex); 3528 newblock = ext_pblock(&newex);
3538 allocated = ext4_ext_get_actual_len(&newex); 3529 allocated = ext4_ext_get_actual_len(&newex);
3539 if (allocated > max_blocks) 3530 if (allocated > map->m_len)
3540 allocated = max_blocks; 3531 allocated = map->m_len;
3541 set_buffer_new(bh_result); 3532 map->m_flags |= EXT4_MAP_NEW;
3542 3533
3543 /* 3534 /*
3544 * Update reserved blocks/metadata blocks after successful 3535 * Update reserved blocks/metadata blocks after successful
@@ -3552,18 +3543,18 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3552 * when it is _not_ an uninitialized extent. 3543 * when it is _not_ an uninitialized extent.
3553 */ 3544 */
3554 if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) { 3545 if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) {
3555 ext4_ext_put_in_cache(inode, iblock, allocated, newblock, 3546 ext4_ext_put_in_cache(inode, map->m_lblk, allocated, newblock,
3556 EXT4_EXT_CACHE_EXTENT); 3547 EXT4_EXT_CACHE_EXTENT);
3557 ext4_update_inode_fsync_trans(handle, inode, 1); 3548 ext4_update_inode_fsync_trans(handle, inode, 1);
3558 } else 3549 } else
3559 ext4_update_inode_fsync_trans(handle, inode, 0); 3550 ext4_update_inode_fsync_trans(handle, inode, 0);
3560out: 3551out:
3561 if (allocated > max_blocks) 3552 if (allocated > map->m_len)
3562 allocated = max_blocks; 3553 allocated = map->m_len;
3563 ext4_ext_show_leaf(inode, path); 3554 ext4_ext_show_leaf(inode, path);
3564 set_buffer_mapped(bh_result); 3555 map->m_flags |= EXT4_MAP_MAPPED;
3565 bh_result->b_bdev = inode->i_sb->s_bdev; 3556 map->m_pblk = newblock;
3566 bh_result->b_blocknr = newblock; 3557 map->m_len = allocated;
3567out2: 3558out2:
3568 if (path) { 3559 if (path) {
3569 ext4_ext_drop_refs(path); 3560 ext4_ext_drop_refs(path);
@@ -3729,7 +3720,7 @@ retry:
3729 if (ret <= 0) { 3720 if (ret <= 0) {
3730#ifdef EXT4FS_DEBUG 3721#ifdef EXT4FS_DEBUG
3731 WARN_ON(ret <= 0); 3722 WARN_ON(ret <= 0);
3732 printk(KERN_ERR "%s: ext4_ext_get_blocks " 3723 printk(KERN_ERR "%s: ext4_ext_map_blocks "
3733 "returned error inode#%lu, block=%u, " 3724 "returned error inode#%lu, block=%u, "
3734 "max_blocks=%u", __func__, 3725 "max_blocks=%u", __func__,
3735 inode->i_ino, block, max_blocks); 3726 inode->i_ino, block, max_blocks);
@@ -3806,7 +3797,7 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
3806 EXT4_GET_BLOCKS_IO_CONVERT_EXT); 3797 EXT4_GET_BLOCKS_IO_CONVERT_EXT);
3807 if (ret <= 0) { 3798 if (ret <= 0) {
3808 WARN_ON(ret <= 0); 3799 WARN_ON(ret <= 0);
3809 printk(KERN_ERR "%s: ext4_ext_get_blocks " 3800 printk(KERN_ERR "%s: ext4_ext_map_blocks "
3810 "returned error inode#%lu, block=%u, " 3801 "returned error inode#%lu, block=%u, "
3811 "max_blocks=%u", __func__, 3802 "max_blocks=%u", __func__,
3812 inode->i_ino, block, max_blocks); 3803 inode->i_ino, block, max_blocks);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 830336d3911b..ff2f5fd681b5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -149,7 +149,7 @@ int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
149 int ret; 149 int ret;
150 150
151 /* 151 /*
152 * Drop i_data_sem to avoid deadlock with ext4_get_blocks At this 152 * Drop i_data_sem to avoid deadlock with ext4_map_blocks. At this
153 * moment, get_block can be called only for blocks inside i_size since 153 * moment, get_block can be called only for blocks inside i_size since
154 * page cache has been already dropped and writes are blocked by 154 * page cache has been already dropped and writes are blocked by
155 * i_mutex. So we can safely drop the i_data_sem here. 155 * i_mutex. So we can safely drop the i_data_sem here.
@@ -890,9 +890,9 @@ err_out:
890} 890}
891 891
892/* 892/*
893 * The ext4_ind_get_blocks() function handles non-extents inodes 893 * The ext4_ind_map_blocks() function handles non-extents inodes
894 * (i.e., using the traditional indirect/double-indirect i_blocks 894 * (i.e., using the traditional indirect/double-indirect i_blocks
895 * scheme) for ext4_get_blocks(). 895 * scheme) for ext4_map_blocks().
896 * 896 *
897 * Allocation strategy is simple: if we have to allocate something, we will 897 * Allocation strategy is simple: if we have to allocate something, we will
898 * have to go the whole way to leaf. So let's do it before attaching anything 898 * have to go the whole way to leaf. So let's do it before attaching anything
@@ -917,9 +917,8 @@ err_out:
917 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system 917 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system
918 * blocks. 918 * blocks.
919 */ 919 */
920static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode, 920static int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
921 ext4_lblk_t iblock, unsigned int maxblocks, 921 struct ext4_map_blocks *map,
922 struct buffer_head *bh_result,
923 int flags) 922 int flags)
924{ 923{
925 int err = -EIO; 924 int err = -EIO;
@@ -935,7 +934,7 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
935 934
936 J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); 935 J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL));
937 J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0); 936 J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0);
938 depth = ext4_block_to_path(inode, iblock, offsets, 937 depth = ext4_block_to_path(inode, map->m_lblk, offsets,
939 &blocks_to_boundary); 938 &blocks_to_boundary);
940 939
941 if (depth == 0) 940 if (depth == 0)
@@ -946,10 +945,9 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
946 /* Simplest case - block found, no allocation needed */ 945 /* Simplest case - block found, no allocation needed */
947 if (!partial) { 946 if (!partial) {
948 first_block = le32_to_cpu(chain[depth - 1].key); 947 first_block = le32_to_cpu(chain[depth - 1].key);
949 clear_buffer_new(bh_result);
950 count++; 948 count++;
951 /*map more blocks*/ 949 /*map more blocks*/
952 while (count < maxblocks && count <= blocks_to_boundary) { 950 while (count < map->m_len && count <= blocks_to_boundary) {
953 ext4_fsblk_t blk; 951 ext4_fsblk_t blk;
954 952
955 blk = le32_to_cpu(*(chain[depth-1].p + count)); 953 blk = le32_to_cpu(*(chain[depth-1].p + count));
@@ -969,7 +967,7 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
969 /* 967 /*
970 * Okay, we need to do block allocation. 968 * Okay, we need to do block allocation.
971 */ 969 */
972 goal = ext4_find_goal(inode, iblock, partial); 970 goal = ext4_find_goal(inode, map->m_lblk, partial);
973 971
974 /* the number of blocks need to allocate for [d,t]indirect blocks */ 972 /* the number of blocks need to allocate for [d,t]indirect blocks */
975 indirect_blks = (chain + depth) - partial - 1; 973 indirect_blks = (chain + depth) - partial - 1;
@@ -979,11 +977,11 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
979 * direct blocks to allocate for this branch. 977 * direct blocks to allocate for this branch.
980 */ 978 */
981 count = ext4_blks_to_allocate(partial, indirect_blks, 979 count = ext4_blks_to_allocate(partial, indirect_blks,
982 maxblocks, blocks_to_boundary); 980 map->m_len, blocks_to_boundary);
983 /* 981 /*
984 * Block out ext4_truncate while we alter the tree 982 * Block out ext4_truncate while we alter the tree
985 */ 983 */
986 err = ext4_alloc_branch(handle, inode, iblock, indirect_blks, 984 err = ext4_alloc_branch(handle, inode, map->m_lblk, indirect_blks,
987 &count, goal, 985 &count, goal,
988 offsets + (partial - chain), partial); 986 offsets + (partial - chain), partial);
989 987
@@ -995,18 +993,20 @@ static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode,
995 * may need to return -EAGAIN upwards in the worst case. --sct 993 * may need to return -EAGAIN upwards in the worst case. --sct
996 */ 994 */
997 if (!err) 995 if (!err)
998 err = ext4_splice_branch(handle, inode, iblock, 996 err = ext4_splice_branch(handle, inode, map->m_lblk,
999 partial, indirect_blks, count); 997 partial, indirect_blks, count);
1000 if (err) 998 if (err)
1001 goto cleanup; 999 goto cleanup;
1002 1000
1003 set_buffer_new(bh_result); 1001 map->m_flags |= EXT4_MAP_NEW;
1004 1002
1005 ext4_update_inode_fsync_trans(handle, inode, 1); 1003 ext4_update_inode_fsync_trans(handle, inode, 1);
1006got_it: 1004got_it:
1007 map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key)); 1005 map->m_flags |= EXT4_MAP_MAPPED;
1006 map->m_pblk = le32_to_cpu(chain[depth-1].key);
1007 map->m_len = count;
1008 if (count > blocks_to_boundary) 1008 if (count > blocks_to_boundary)
1009 set_buffer_boundary(bh_result); 1009 map->m_flags |= EXT4_MAP_BOUNDARY;
1010 err = count; 1010 err = count;
1011 /* Clean up and exit */ 1011 /* Clean up and exit */
1012 partial = chain + depth - 1; /* the whole chain */ 1012 partial = chain + depth - 1; /* the whole chain */
@@ -1016,7 +1016,6 @@ cleanup:
1016 brelse(partial->bh); 1016 brelse(partial->bh);
1017 partial--; 1017 partial--;
1018 } 1018 }
1019 BUFFER_TRACE(bh_result, "returned");
1020out: 1019out:
1021 return err; 1020 return err;
1022} 1021}
@@ -1203,15 +1202,15 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
1203} 1202}
1204 1203
1205/* 1204/*
1206 * The ext4_get_blocks() function tries to look up the requested blocks, 1205 * The ext4_map_blocks() function tries to look up the requested blocks,
1207 * and returns if the blocks are already mapped. 1206 * and returns if the blocks are already mapped.
1208 * 1207 *
1209 * Otherwise it takes the write lock of the i_data_sem and allocate blocks 1208 * Otherwise it takes the write lock of the i_data_sem and allocate blocks
1210 * and store the allocated blocks in the result buffer head and mark it 1209 * and store the allocated blocks in the result buffer head and mark it
1211 * mapped. 1210 * mapped.
1212 * 1211 *
1213 * If file type is extents based, it will call ext4_ext_get_blocks(), 1212 * If file type is extents based, it will call ext4_ext_map_blocks(),
1214 * Otherwise, call with ext4_ind_get_blocks() to handle indirect mapping 1213 * Otherwise, call with ext4_ind_map_blocks() to handle indirect mapping
1215 * based files 1214 * based files
1216 * 1215 *
1217 * On success, it returns the number of blocks being mapped or allocate. 1216 * On success, it returns the number of blocks being mapped or allocate.
@@ -1224,35 +1223,30 @@ static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
1224 * 1223 *
1225 * It returns the error in case of allocation failure. 1224 * It returns the error in case of allocation failure.
1226 */ 1225 */
1227int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block, 1226int ext4_map_blocks(handle_t *handle, struct inode *inode,
1228 unsigned int max_blocks, struct buffer_head *bh, 1227 struct ext4_map_blocks *map, int flags)
1229 int flags)
1230{ 1228{
1231 int retval; 1229 int retval;
1232 1230
1233 clear_buffer_mapped(bh); 1231 map->m_flags = 0;
1234 clear_buffer_unwritten(bh); 1232 ext_debug("ext4_map_blocks(): inode %lu, flag %d, max_blocks %u,"
1235 1233 "logical block %lu\n", inode->i_ino, flags, map->m_len,
1236 ext_debug("ext4_get_blocks(): inode %lu, flag %d, max_blocks %u," 1234 (unsigned long) map->m_lblk);
1237 "logical block %lu\n", inode->i_ino, flags, max_blocks,
1238 (unsigned long)block);
1239 /* 1235 /*
1240 * Try to see if we can get the block without requesting a new 1236 * Try to see if we can get the block without requesting a new
1241 * file system block. 1237 * file system block.
1242 */ 1238 */
1243 down_read((&EXT4_I(inode)->i_data_sem)); 1239 down_read((&EXT4_I(inode)->i_data_sem));
1244 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 1240 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
1245 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, 1241 retval = ext4_ext_map_blocks(handle, inode, map, 0);
1246 bh, 0);
1247 } else { 1242 } else {
1248 retval = ext4_ind_get_blocks(handle, inode, block, max_blocks, 1243 retval = ext4_ind_map_blocks(handle, inode, map, 0);
1249 bh, 0);
1250 } 1244 }
1251 up_read((&EXT4_I(inode)->i_data_sem)); 1245 up_read((&EXT4_I(inode)->i_data_sem));
1252 1246
1253 if (retval > 0 && buffer_mapped(bh)) { 1247 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
1254 int ret = check_block_validity(inode, "file system corruption", 1248 int ret = check_block_validity(inode, "file system corruption",
1255 block, bh->b_blocknr, retval); 1249 map->m_lblk, map->m_pblk, retval);
1256 if (ret != 0) 1250 if (ret != 0)
1257 return ret; 1251 return ret;
1258 } 1252 }
@@ -1268,7 +1262,7 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1268 * ext4_ext_get_block() returns th create = 0 1262 * ext4_ext_get_block() returns th create = 0
1269 * with buffer head unmapped. 1263 * with buffer head unmapped.
1270 */ 1264 */
1271 if (retval > 0 && buffer_mapped(bh)) 1265 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED)
1272 return retval; 1266 return retval;
1273 1267
1274 /* 1268 /*
@@ -1281,7 +1275,7 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1281 * of BH_Unwritten and BH_Mapped flags being simultaneously 1275 * of BH_Unwritten and BH_Mapped flags being simultaneously
1282 * set on the buffer_head. 1276 * set on the buffer_head.
1283 */ 1277 */
1284 clear_buffer_unwritten(bh); 1278 map->m_flags &= ~EXT4_MAP_UNWRITTEN;
1285 1279
1286 /* 1280 /*
1287 * New blocks allocate and/or writing to uninitialized extent 1281 * New blocks allocate and/or writing to uninitialized extent
@@ -1304,13 +1298,11 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1304 * could have changed the inode type in between 1298 * could have changed the inode type in between
1305 */ 1299 */
1306 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 1300 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
1307 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, 1301 retval = ext4_ext_map_blocks(handle, inode, map, flags);
1308 bh, flags);
1309 } else { 1302 } else {
1310 retval = ext4_ind_get_blocks(handle, inode, block, 1303 retval = ext4_ind_map_blocks(handle, inode, map, flags);
1311 max_blocks, bh, flags);
1312 1304
1313 if (retval > 0 && buffer_new(bh)) { 1305 if (retval > 0 && map->m_flags & EXT4_MAP_NEW) {
1314 /* 1306 /*
1315 * We allocated new blocks which will result in 1307 * We allocated new blocks which will result in
1316 * i_data's format changing. Force the migrate 1308 * i_data's format changing. Force the migrate
@@ -1333,16 +1325,38 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1333 EXT4_I(inode)->i_delalloc_reserved_flag = 0; 1325 EXT4_I(inode)->i_delalloc_reserved_flag = 0;
1334 1326
1335 up_write((&EXT4_I(inode)->i_data_sem)); 1327 up_write((&EXT4_I(inode)->i_data_sem));
1336 if (retval > 0 && buffer_mapped(bh)) { 1328 if (retval > 0 && map->m_flags & EXT4_MAP_MAPPED) {
1337 int ret = check_block_validity(inode, "file system " 1329 int ret = check_block_validity(inode, "file system "
1338 "corruption after allocation", 1330 "corruption after allocation",
1339 block, bh->b_blocknr, retval); 1331 map->m_lblk, map->m_pblk,
1332 retval);
1340 if (ret != 0) 1333 if (ret != 0)
1341 return ret; 1334 return ret;
1342 } 1335 }
1343 return retval; 1336 return retval;
1344} 1337}
1345 1338
1339int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1340 unsigned int max_blocks, struct buffer_head *bh,
1341 int flags)
1342{
1343 struct ext4_map_blocks map;
1344 int ret;
1345
1346 map.m_lblk = block;
1347 map.m_len = max_blocks;
1348
1349 ret = ext4_map_blocks(handle, inode, &map, flags);
1350 if (ret < 0)
1351 return ret;
1352
1353 bh->b_blocknr = map.m_pblk;
1354 bh->b_size = inode->i_sb->s_blocksize * map.m_len;
1355 bh->b_bdev = inode->i_sb->s_bdev;
1356 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
1357 return ret;
1358}
1359
1346/* Maximum number of blocks we map for direct IO at once. */ 1360/* Maximum number of blocks we map for direct IO at once. */
1347#define DIO_MAX_BLOCKS 4096 1361#define DIO_MAX_BLOCKS 4096
1348 1362