aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorZheng Liu <wenqing.lz@taobao.com>2013-02-18 00:28:47 -0500
committerTheodore Ts'o <tytso@mit.edu>2013-02-18 00:28:47 -0500
commitf7fec032aa782d3fd7e51fbdf08aa3a296c01500 (patch)
tree3efc694cb743f6248721566f35e0f43352f9eb1f /fs/ext4/extents.c
parenta25a4e1a5d5dc0f97dddbca44e695c532d8228c1 (diff)
ext4: track all extent status in extent status tree
By recording the phycisal block and status, extent status tree is able to track the status of every extents. When we call _map_blocks functions to lookup an extent or create a new written/unwritten/delayed extent, this extent will be inserted into extent status tree. We don't load all extents from disk in alloc_inode() because it costs too much memory, and if a file is opened and closed frequently it will takes too much time to load all extent information. So currently when we create/lookup an extent, this extent will be inserted into extent status tree. Hence, the extent status tree may not comprehensively contain all of the extents found in the file. Here a condition we need to take care is that an extent might contains unwritten and delayed status simultaneously because an extent is delayed allocated and could be allocated by fallocate. At this time we need to keep delayed status because later we need to update delayed reservation space using it. Signed-off-by: Zheng Liu <wenqing.lz@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Jan kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index cae8ae3c1746..be0b1b3eed97 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2076,8 +2076,18 @@ static int ext4_fill_fiemap_extents(struct inode *inode,
2076 break; 2076 break;
2077 } 2077 }
2078 2078
2079 /* This is possible iff next == next_del == EXT_MAX_BLOCKS */ 2079 /*
2080 if (next == next_del) { 2080 * This is possible iff next == next_del == EXT_MAX_BLOCKS.
2081 * we need to check next == EXT_MAX_BLOCKS because it is
2082 * possible that an extent is with unwritten and delayed
2083 * status due to when an extent is delayed allocated and
2084 * is allocated by fallocate status tree will track both of
2085 * them in a extent.
2086 *
2087 * So we could return a unwritten and delayed extent, and
2088 * its block is equal to 'next'.
2089 */
2090 if (next == next_del && next == EXT_MAX_BLOCKS) {
2081 flags |= FIEMAP_EXTENT_LAST; 2091 flags |= FIEMAP_EXTENT_LAST;
2082 if (unlikely(next_del != EXT_MAX_BLOCKS || 2092 if (unlikely(next_del != EXT_MAX_BLOCKS ||
2083 next != EXT_MAX_BLOCKS)) { 2093 next != EXT_MAX_BLOCKS)) {
@@ -3522,9 +3532,9 @@ out:
3522 * 3532 *
3523 * Return 1 if there is a delalloc block in the range, otherwise 0. 3533 * Return 1 if there is a delalloc block in the range, otherwise 0.
3524 */ 3534 */
3525static int ext4_find_delalloc_range(struct inode *inode, 3535int ext4_find_delalloc_range(struct inode *inode,
3526 ext4_lblk_t lblk_start, 3536 ext4_lblk_t lblk_start,
3527 ext4_lblk_t lblk_end) 3537 ext4_lblk_t lblk_end)
3528{ 3538{
3529 struct extent_status es; 3539 struct extent_status es;
3530 3540