diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2014-10-01 22:57:09 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-10-01 22:57:09 -0400 |
commit | be5cd90ddaf471e676fad6ced29e69e8610c5d20 (patch) | |
tree | 3009c16441b2c134588c714c61e629b07a4974cf | |
parent | dfe076c106f63cf6bcd375c56db9c8c89a088dab (diff) | |
download | linux-be5cd90ddaf471e676fad6ced29e69e8610c5d20.tar.bz2 |
ext4: optimize block allocation on grow indepth
It is reasonable to prepend newly created index to older one.
[ Dropped no longer used function parameter newext. -tytso ]
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/ext4/extents.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 8170b3254767..c3ed9af20d20 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -1263,16 +1263,24 @@ cleanup: * just created block */ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, - unsigned int flags, - struct ext4_extent *newext) + unsigned int flags) { struct ext4_extent_header *neh; struct buffer_head *bh; - ext4_fsblk_t newblock; + ext4_fsblk_t newblock, goal = 0; + struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; int err = 0; - newblock = ext4_ext_new_meta_block(handle, inode, NULL, - newext, &err, flags); + /* Try to prepend new index to old one */ + if (ext_depth(inode)) + goal = ext4_idx_pblock(EXT_FIRST_INDEX(ext_inode_hdr(inode))); + if (goal > le32_to_cpu(es->s_first_data_block)) { + flags |= EXT4_MB_HINT_TRY_GOAL; + goal--; + } else + goal = ext4_inode_to_goal_block(inode); + newblock = ext4_new_meta_blocks(handle, inode, goal, flags, + NULL, &err); if (newblock == 0) return err; @@ -1373,7 +1381,7 @@ repeat: err = PTR_ERR(path); } else { /* tree is full, time to grow in depth */ - err = ext4_ext_grow_indepth(handle, inode, mb_flags, newext); + err = ext4_ext_grow_indepth(handle, inode, mb_flags); if (err) goto out; |