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.c128
1 files changed, 63 insertions, 65 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 3753ceb0b0dd..95bf4679ac54 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -15,7 +15,7 @@
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public Licens 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
21 */ 21 */
@@ -1736,6 +1736,12 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1736 */ 1736 */
1737 if (ext1_ee_len + ext2_ee_len > EXT_INIT_MAX_LEN) 1737 if (ext1_ee_len + ext2_ee_len > EXT_INIT_MAX_LEN)
1738 return 0; 1738 return 0;
1739 /*
1740 * The check for IO to unwritten extent is somewhat racy as we
1741 * increment i_unwritten / set EXT4_STATE_DIO_UNWRITTEN only after
1742 * dropping i_data_sem. But reserved blocks should save us in that
1743 * case.
1744 */
1739 if (ext4_ext_is_unwritten(ex1) && 1745 if (ext4_ext_is_unwritten(ex1) &&
1740 (ext4_test_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN) || 1746 (ext4_test_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN) ||
1741 atomic_read(&EXT4_I(inode)->i_unwritten) || 1747 atomic_read(&EXT4_I(inode)->i_unwritten) ||
@@ -2293,59 +2299,69 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
2293} 2299}
2294 2300
2295/* 2301/*
2296 * ext4_ext_put_gap_in_cache: 2302 * ext4_ext_determine_hole - determine hole around given block
2297 * calculate boundaries of the gap that the requested block fits into 2303 * @inode: inode we lookup in
2298 * and cache this gap 2304 * @path: path in extent tree to @lblk
2305 * @lblk: pointer to logical block around which we want to determine hole
2306 *
2307 * Determine hole length (and start if easily possible) around given logical
2308 * block. We don't try too hard to find the beginning of the hole but @path
2309 * actually points to extent before @lblk, we provide it.
2310 *
2311 * The function returns the length of a hole starting at @lblk. We update @lblk
2312 * to the beginning of the hole if we managed to find it.
2299 */ 2313 */
2300static void 2314static ext4_lblk_t ext4_ext_determine_hole(struct inode *inode,
2301ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, 2315 struct ext4_ext_path *path,
2302 ext4_lblk_t block) 2316 ext4_lblk_t *lblk)
2303{ 2317{
2304 int depth = ext_depth(inode); 2318 int depth = ext_depth(inode);
2305 ext4_lblk_t len;
2306 ext4_lblk_t lblock;
2307 struct ext4_extent *ex; 2319 struct ext4_extent *ex;
2308 struct extent_status es; 2320 ext4_lblk_t len;
2309 2321
2310 ex = path[depth].p_ext; 2322 ex = path[depth].p_ext;
2311 if (ex == NULL) { 2323 if (ex == NULL) {
2312 /* there is no extent yet, so gap is [0;-] */ 2324 /* there is no extent yet, so gap is [0;-] */
2313 lblock = 0; 2325 *lblk = 0;
2314 len = EXT_MAX_BLOCKS; 2326 len = EXT_MAX_BLOCKS;
2315 ext_debug("cache gap(whole file):"); 2327 } else if (*lblk < le32_to_cpu(ex->ee_block)) {
2316 } else if (block < le32_to_cpu(ex->ee_block)) { 2328 len = le32_to_cpu(ex->ee_block) - *lblk;
2317 lblock = block; 2329 } else if (*lblk >= le32_to_cpu(ex->ee_block)
2318 len = le32_to_cpu(ex->ee_block) - block;
2319 ext_debug("cache gap(before): %u [%u:%u]",
2320 block,
2321 le32_to_cpu(ex->ee_block),
2322 ext4_ext_get_actual_len(ex));
2323 } else if (block >= le32_to_cpu(ex->ee_block)
2324 + ext4_ext_get_actual_len(ex)) { 2330 + ext4_ext_get_actual_len(ex)) {
2325 ext4_lblk_t next; 2331 ext4_lblk_t next;
2326 lblock = le32_to_cpu(ex->ee_block)
2327 + ext4_ext_get_actual_len(ex);
2328 2332
2333 *lblk = le32_to_cpu(ex->ee_block) + ext4_ext_get_actual_len(ex);
2329 next = ext4_ext_next_allocated_block(path); 2334 next = ext4_ext_next_allocated_block(path);
2330 ext_debug("cache gap(after): [%u:%u] %u", 2335 BUG_ON(next == *lblk);
2331 le32_to_cpu(ex->ee_block), 2336 len = next - *lblk;
2332 ext4_ext_get_actual_len(ex),
2333 block);
2334 BUG_ON(next == lblock);
2335 len = next - lblock;
2336 } else { 2337 } else {
2337 BUG(); 2338 BUG();
2338 } 2339 }
2340 return len;
2341}
2339 2342
2340 ext4_es_find_delayed_extent_range(inode, lblock, lblock + len - 1, &es); 2343/*
2344 * ext4_ext_put_gap_in_cache:
2345 * calculate boundaries of the gap that the requested block fits into
2346 * and cache this gap
2347 */
2348static void
2349ext4_ext_put_gap_in_cache(struct inode *inode, ext4_lblk_t hole_start,
2350 ext4_lblk_t hole_len)
2351{
2352 struct extent_status es;
2353
2354 ext4_es_find_delayed_extent_range(inode, hole_start,
2355 hole_start + hole_len - 1, &es);
2341 if (es.es_len) { 2356 if (es.es_len) {
2342 /* There's delayed extent containing lblock? */ 2357 /* There's delayed extent containing lblock? */
2343 if (es.es_lblk <= lblock) 2358 if (es.es_lblk <= hole_start)
2344 return; 2359 return;
2345 len = min(es.es_lblk - lblock, len); 2360 hole_len = min(es.es_lblk - hole_start, hole_len);
2346 } 2361 }
2347 ext_debug(" -> %u:%u\n", lblock, len); 2362 ext_debug(" -> %u:%u\n", hole_start, hole_len);
2348 ext4_es_insert_extent(inode, lblock, len, ~0, EXTENT_STATUS_HOLE); 2363 ext4_es_insert_extent(inode, hole_start, hole_len, ~0,
2364 EXTENT_STATUS_HOLE);
2349} 2365}
2350 2366
2351/* 2367/*
@@ -3927,7 +3943,7 @@ get_reserved_cluster_alloc(struct inode *inode, ext4_lblk_t lblk_start,
3927static int 3943static int
3928convert_initialized_extent(handle_t *handle, struct inode *inode, 3944convert_initialized_extent(handle_t *handle, struct inode *inode,
3929 struct ext4_map_blocks *map, 3945 struct ext4_map_blocks *map,
3930 struct ext4_ext_path **ppath, int flags, 3946 struct ext4_ext_path **ppath,
3931 unsigned int allocated) 3947 unsigned int allocated)
3932{ 3948{
3933 struct ext4_ext_path *path = *ppath; 3949 struct ext4_ext_path *path = *ppath;
@@ -4007,7 +4023,6 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
4007 struct ext4_ext_path *path = *ppath; 4023 struct ext4_ext_path *path = *ppath;
4008 int ret = 0; 4024 int ret = 0;
4009 int err = 0; 4025 int err = 0;
4010 ext4_io_end_t *io = ext4_inode_aio(inode);
4011 4026
4012 ext_debug("ext4_ext_handle_unwritten_extents: inode %lu, logical " 4027 ext_debug("ext4_ext_handle_unwritten_extents: inode %lu, logical "
4013 "block %llu, max_blocks %u, flags %x, allocated %u\n", 4028 "block %llu, max_blocks %u, flags %x, allocated %u\n",
@@ -4030,15 +4045,6 @@ ext4_ext_handle_unwritten_extents(handle_t *handle, struct inode *inode,
4030 flags | EXT4_GET_BLOCKS_CONVERT); 4045 flags | EXT4_GET_BLOCKS_CONVERT);
4031 if (ret <= 0) 4046 if (ret <= 0)
4032 goto out; 4047 goto out;
4033 /*
4034 * Flag the inode(non aio case) or end_io struct (aio case)
4035 * that this IO needs to conversion to written when IO is
4036 * completed
4037 */
4038 if (io)
4039 ext4_set_io_unwritten_flag(inode, io);
4040 else
4041 ext4_set_inode_state(inode, EXT4_STATE_DIO_UNWRITTEN);
4042 map->m_flags |= EXT4_MAP_UNWRITTEN; 4048 map->m_flags |= EXT4_MAP_UNWRITTEN;
4043 goto out; 4049 goto out;
4044 } 4050 }
@@ -4283,9 +4289,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
4283 unsigned int allocated = 0, offset = 0; 4289 unsigned int allocated = 0, offset = 0;
4284 unsigned int allocated_clusters = 0; 4290 unsigned int allocated_clusters = 0;
4285 struct ext4_allocation_request ar; 4291 struct ext4_allocation_request ar;
4286 ext4_io_end_t *io = ext4_inode_aio(inode);
4287 ext4_lblk_t cluster_offset; 4292 ext4_lblk_t cluster_offset;
4288 int set_unwritten = 0;
4289 bool map_from_cluster = false; 4293 bool map_from_cluster = false;
4290 4294
4291 ext_debug("blocks %u/%u requested for inode %lu\n", 4295 ext_debug("blocks %u/%u requested for inode %lu\n",
@@ -4347,7 +4351,7 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
4347 (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) { 4351 (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN)) {
4348 allocated = convert_initialized_extent( 4352 allocated = convert_initialized_extent(
4349 handle, inode, map, &path, 4353 handle, inode, map, &path,
4350 flags, allocated); 4354 allocated);
4351 goto out2; 4355 goto out2;
4352 } else if (!ext4_ext_is_unwritten(ex)) 4356 } else if (!ext4_ext_is_unwritten(ex))
4353 goto out; 4357 goto out;
@@ -4368,11 +4372,22 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
4368 * we couldn't try to create block if create flag is zero 4372 * we couldn't try to create block if create flag is zero
4369 */ 4373 */
4370 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { 4374 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
4375 ext4_lblk_t hole_start, hole_len;
4376
4377 hole_start = map->m_lblk;
4378 hole_len = ext4_ext_determine_hole(inode, path, &hole_start);
4371 /* 4379 /*
4372 * put just found gap into cache to speed up 4380 * put just found gap into cache to speed up
4373 * subsequent requests 4381 * subsequent requests
4374 */ 4382 */
4375 ext4_ext_put_gap_in_cache(inode, path, map->m_lblk); 4383 ext4_ext_put_gap_in_cache(inode, hole_start, hole_len);
4384
4385 /* Update hole_len to reflect hole size after map->m_lblk */
4386 if (hole_start != map->m_lblk)
4387 hole_len -= map->m_lblk - hole_start;
4388 map->m_pblk = 0;
4389 map->m_len = min_t(unsigned int, map->m_len, hole_len);
4390
4376 goto out2; 4391 goto out2;
4377 } 4392 }
4378 4393
@@ -4482,15 +4497,6 @@ got_allocated_blocks:
4482 if (flags & EXT4_GET_BLOCKS_UNWRIT_EXT){ 4497 if (flags & EXT4_GET_BLOCKS_UNWRIT_EXT){
4483 ext4_ext_mark_unwritten(&newex); 4498 ext4_ext_mark_unwritten(&newex);
4484 map->m_flags |= EXT4_MAP_UNWRITTEN; 4499 map->m_flags |= EXT4_MAP_UNWRITTEN;
4485 /*
4486 * io_end structure was created for every IO write to an
4487 * unwritten extent. To avoid unnecessary conversion,
4488 * here we flag the IO that really needs the conversion.
4489 * For non asycn direct IO case, flag the inode state
4490 * that we need to perform conversion when IO is done.
4491 */
4492 if (flags & EXT4_GET_BLOCKS_PRE_IO)
4493 set_unwritten = 1;
4494 } 4500 }
4495 4501
4496 err = 0; 4502 err = 0;
@@ -4501,14 +4507,6 @@ got_allocated_blocks:
4501 err = ext4_ext_insert_extent(handle, inode, &path, 4507 err = ext4_ext_insert_extent(handle, inode, &path,
4502 &newex, flags); 4508 &newex, flags);
4503 4509
4504 if (!err && set_unwritten) {
4505 if (io)
4506 ext4_set_io_unwritten_flag(inode, io);
4507 else
4508 ext4_set_inode_state(inode,
4509 EXT4_STATE_DIO_UNWRITTEN);
4510 }
4511
4512 if (err && free_on_err) { 4510 if (err && free_on_err) {
4513 int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ? 4511 int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
4514 EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0; 4512 EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;