aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYongqiang Yang <xiaoqiangnk@gmail.com>2011-05-03 11:45:29 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-05-03 11:45:29 -0400
commit197217a5af79c23609da03eda2a52ee8603eec52 (patch)
treedf05721599f21c46fb4879ec3195431dd9a45804
parentdf5e6223407e3e645065c4bd968fee007f0e0287 (diff)
ext4: add a function merging extents right and left
1) Rename ext4_ext_try_to_merge() to ext4_ext_try_to_merge_right(). 2) Add a new function ext4_ext_try_to_merge() which tries to merge an extent both left and right. 3) Use the new function in ext4_ext_convert_unwritten_endio() and ext4_ext_insert_extent(). Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com> Tested-by: Allison Henderson <achender@linux.vnet.ibm.com>
-rw-r--r--fs/ext4/extents.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 4890d6f3ad15..23a98b6f00a2 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1563,7 +1563,7 @@ ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
1563 * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns 1563 * Returns 0 if the extents (ex and ex+1) were _not_ merged and returns
1564 * 1 if they got merged. 1564 * 1 if they got merged.
1565 */ 1565 */
1566static int ext4_ext_try_to_merge(struct inode *inode, 1566static int ext4_ext_try_to_merge_right(struct inode *inode,
1567 struct ext4_ext_path *path, 1567 struct ext4_ext_path *path,
1568 struct ext4_extent *ex) 1568 struct ext4_extent *ex)
1569{ 1569{
@@ -1603,6 +1603,31 @@ static int ext4_ext_try_to_merge(struct inode *inode,
1603} 1603}
1604 1604
1605/* 1605/*
1606 * This function tries to merge the @ex extent to neighbours in the tree.
1607 * return 1 if merge left else 0.
1608 */
1609static int ext4_ext_try_to_merge(struct inode *inode,
1610 struct ext4_ext_path *path,
1611 struct ext4_extent *ex) {
1612 struct ext4_extent_header *eh;
1613 unsigned int depth;
1614 int merge_done = 0;
1615 int ret = 0;
1616
1617 depth = ext_depth(inode);
1618 BUG_ON(path[depth].p_hdr == NULL);
1619 eh = path[depth].p_hdr;
1620
1621 if (ex > EXT_FIRST_EXTENT(eh))
1622 merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1);
1623
1624 if (!merge_done)
1625 ret = ext4_ext_try_to_merge_right(inode, path, ex);
1626
1627 return ret;
1628}
1629
1630/*
1606 * check if a portion of the "newext" extent overlaps with an 1631 * check if a portion of the "newext" extent overlaps with an
1607 * existing extent. 1632 * existing extent.
1608 * 1633 *
@@ -3039,6 +3064,7 @@ fix_extent_len:
3039 ext4_ext_dirty(handle, inode, path + depth); 3064 ext4_ext_dirty(handle, inode, path + depth);
3040 return err; 3065 return err;
3041} 3066}
3067
3042static int ext4_convert_unwritten_extents_endio(handle_t *handle, 3068static int ext4_convert_unwritten_extents_endio(handle_t *handle,
3043 struct inode *inode, 3069 struct inode *inode,
3044 struct ext4_ext_path *path) 3070 struct ext4_ext_path *path)
@@ -3047,46 +3073,27 @@ static int ext4_convert_unwritten_extents_endio(handle_t *handle,
3047 struct ext4_extent_header *eh; 3073 struct ext4_extent_header *eh;
3048 int depth; 3074 int depth;
3049 int err = 0; 3075 int err = 0;
3050 int ret = 0;
3051 3076
3052 depth = ext_depth(inode); 3077 depth = ext_depth(inode);
3053 eh = path[depth].p_hdr; 3078 eh = path[depth].p_hdr;
3054 ex = path[depth].p_ext; 3079 ex = path[depth].p_ext;
3055 3080
3081 ext_debug("ext4_convert_unwritten_extents_endio: inode %lu, logical"
3082 "block %llu, max_blocks %u\n", inode->i_ino,
3083 (unsigned long long)le32_to_cpu(ex->ee_block),
3084 ext4_ext_get_actual_len(ex));
3085
3056 err = ext4_ext_get_access(handle, inode, path + depth); 3086 err = ext4_ext_get_access(handle, inode, path + depth);
3057 if (err) 3087 if (err)
3058 goto out; 3088 goto out;
3059 /* first mark the extent as initialized */ 3089 /* first mark the extent as initialized */
3060 ext4_ext_mark_initialized(ex); 3090 ext4_ext_mark_initialized(ex);
3061 3091
3062 /* 3092 /* note: ext4_ext_correct_indexes() isn't needed here because
3063 * We have to see if it can be merged with the extent 3093 * borders are not changed
3064 * on the left.
3065 */ 3094 */
3066 if (ex > EXT_FIRST_EXTENT(eh)) { 3095 ext4_ext_try_to_merge(inode, path, ex);
3067 /* 3096
3068 * To merge left, pass "ex - 1" to try_to_merge(),
3069 * since it merges towards right _only_.
3070 */
3071 ret = ext4_ext_try_to_merge(inode, path, ex - 1);
3072 if (ret) {
3073 err = ext4_ext_correct_indexes(handle, inode, path);
3074 if (err)
3075 goto out;
3076 depth = ext_depth(inode);
3077 ex--;
3078 }
3079 }
3080 /*
3081 * Try to Merge towards right.
3082 */
3083 ret = ext4_ext_try_to_merge(inode, path, ex);
3084 if (ret) {
3085 err = ext4_ext_correct_indexes(handle, inode, path);
3086 if (err)
3087 goto out;
3088 depth = ext_depth(inode);
3089 }
3090 /* Mark modified extent as dirty */ 3097 /* Mark modified extent as dirty */
3091 err = ext4_ext_dirty(handle, inode, path + depth); 3098 err = ext4_ext_dirty(handle, inode, path + depth);
3092out: 3099out: