aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ded3d469f978..77146b826a13 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1107,7 +1107,7 @@ static int
1107ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, 1107ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1108 struct ext4_extent *ex2) 1108 struct ext4_extent *ex2)
1109{ 1109{
1110 unsigned short ext1_ee_len, ext2_ee_len; 1110 unsigned short ext1_ee_len, ext2_ee_len, max_len;
1111 1111
1112 /* 1112 /*
1113 * Make sure that either both extents are uninitialized, or 1113 * Make sure that either both extents are uninitialized, or
@@ -1116,6 +1116,11 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1116 if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2)) 1116 if (ext4_ext_is_uninitialized(ex1) ^ ext4_ext_is_uninitialized(ex2))
1117 return 0; 1117 return 0;
1118 1118
1119 if (ext4_ext_is_uninitialized(ex1))
1120 max_len = EXT_UNINIT_MAX_LEN;
1121 else
1122 max_len = EXT_INIT_MAX_LEN;
1123
1119 ext1_ee_len = ext4_ext_get_actual_len(ex1); 1124 ext1_ee_len = ext4_ext_get_actual_len(ex1);
1120 ext2_ee_len = ext4_ext_get_actual_len(ex2); 1125 ext2_ee_len = ext4_ext_get_actual_len(ex2);
1121 1126
@@ -1128,7 +1133,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1128 * as an RO_COMPAT feature, refuse to merge to extents if 1133 * as an RO_COMPAT feature, refuse to merge to extents if
1129 * this can result in the top bit of ee_len being set. 1134 * this can result in the top bit of ee_len being set.
1130 */ 1135 */
1131 if (ext1_ee_len + ext2_ee_len > EXT_MAX_LEN) 1136 if (ext1_ee_len + ext2_ee_len > max_len)
1132 return 0; 1137 return 0;
1133#ifdef AGGRESSIVE_TEST 1138#ifdef AGGRESSIVE_TEST
1134 if (le16_to_cpu(ex1->ee_len) >= 4) 1139 if (le16_to_cpu(ex1->ee_len) >= 4)
@@ -1815,7 +1820,11 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
1815 1820
1816 ex->ee_block = cpu_to_le32(block); 1821 ex->ee_block = cpu_to_le32(block);
1817 ex->ee_len = cpu_to_le16(num); 1822 ex->ee_len = cpu_to_le16(num);
1818 if (uninitialized) 1823 /*
1824 * Do not mark uninitialized if all the blocks in the
1825 * extent have been removed.
1826 */
1827 if (uninitialized && num)
1819 ext4_ext_mark_uninitialized(ex); 1828 ext4_ext_mark_uninitialized(ex);
1820 1829
1821 err = ext4_ext_dirty(handle, inode, path + depth); 1830 err = ext4_ext_dirty(handle, inode, path + depth);
@@ -2308,6 +2317,19 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2308 /* allocate new block */ 2317 /* allocate new block */
2309 goal = ext4_ext_find_goal(inode, path, iblock); 2318 goal = ext4_ext_find_goal(inode, path, iblock);
2310 2319
2320 /*
2321 * See if request is beyond maximum number of blocks we can have in
2322 * a single extent. For an initialized extent this limit is
2323 * EXT_INIT_MAX_LEN and for an uninitialized extent this limit is
2324 * EXT_UNINIT_MAX_LEN.
2325 */
2326 if (max_blocks > EXT_INIT_MAX_LEN &&
2327 create != EXT4_CREATE_UNINITIALIZED_EXT)
2328 max_blocks = EXT_INIT_MAX_LEN;
2329 else if (max_blocks > EXT_UNINIT_MAX_LEN &&
2330 create == EXT4_CREATE_UNINITIALIZED_EXT)
2331 max_blocks = EXT_UNINIT_MAX_LEN;
2332
2311 /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ 2333 /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */
2312 newex.ee_block = cpu_to_le32(iblock); 2334 newex.ee_block = cpu_to_le32(iblock);
2313 newex.ee_len = cpu_to_le16(max_blocks); 2335 newex.ee_len = cpu_to_le16(max_blocks);