Skip to content

Commit

Permalink
ext4: cleanup ext4_ext_grow_indepth code
Browse files Browse the repository at this point in the history
Currently code make an impression what grow procedure is very complicated
and some mythical paths, blocks are involved. But in fact grow in depth
it relatively simple procedure:
 1) Just create new meta block and copy root data to that block.
 2) Convert root from extent to index if old depth == 0
 3) Update root block pointer

This patch does:
 - Reorganize code to make it more self explanatory
 - Do not pass path parameter to new_meta_block() in order to
   provoke allocation from inode's group because top-level block
   should site closer to it's inode, but not to leaf data block.

   [ This happens anyway, due to logic in mballoc; we should drop
     the path parameter from new_meta_block() entirely.  -- tytso ]

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
  • Loading branch information
Dmitry Monakhov authored and Theodore Ts'o committed Oct 22, 2011
1 parent 45dc63e commit 1939dd8
Showing 1 changed file with 15 additions and 26 deletions.
41 changes: 15 additions & 26 deletions fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -1050,16 +1050,14 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
*/
static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
unsigned int flags,
struct ext4_ext_path *path,
struct ext4_extent *newext)
{
struct ext4_ext_path *curp = path;
struct ext4_extent_header *neh;
struct buffer_head *bh;
ext4_fsblk_t newblock;
int err = 0;

newblock = ext4_ext_new_meta_block(handle, inode, path,
newblock = ext4_ext_new_meta_block(handle, inode, NULL,
newext, &err, flags);
if (newblock == 0)
return err;
Expand All @@ -1079,7 +1077,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
}

/* move top-level index/leaf into new block */
memmove(bh->b_data, curp->p_hdr, sizeof(EXT4_I(inode)->i_data));
memmove(bh->b_data, EXT4_I(inode)->i_data,
sizeof(EXT4_I(inode)->i_data));

/* set size of new block */
neh = ext_block_hdr(bh);
Expand All @@ -1097,32 +1096,23 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
if (err)
goto out;

/* create index in new top-level index: num,max,pointer */
err = ext4_ext_get_access(handle, inode, curp);
if (err)
goto out;

curp->p_hdr->eh_magic = EXT4_EXT_MAGIC;
curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
curp->p_hdr->eh_entries = cpu_to_le16(1);
curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);

if (path[0].p_hdr->eh_depth)
curp->p_idx->ei_block =
EXT_FIRST_INDEX(path[0].p_hdr)->ei_block;
else
curp->p_idx->ei_block =
EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block;
ext4_idx_store_pblock(curp->p_idx, newblock);

/* Update top-level index: num,max,pointer */
neh = ext_inode_hdr(inode);
neh->eh_entries = cpu_to_le16(1);
ext4_idx_store_pblock(EXT_FIRST_INDEX(neh), newblock);
if (neh->eh_depth == 0) {
/* Root extent block becomes index block */
neh->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
EXT_FIRST_INDEX(neh)->ei_block =
EXT_FIRST_EXTENT(neh)->ee_block;
}
ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n",
le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max),
le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block),
ext4_idx_pblock(EXT_FIRST_INDEX(neh)));

neh->eh_depth = cpu_to_le16(path->p_depth + 1);
err = ext4_ext_dirty(handle, inode, curp);
neh->eh_depth = cpu_to_le16(neh->eh_depth + 1);
ext4_mark_inode_dirty(handle, inode);
out:
brelse(bh);

Expand Down Expand Up @@ -1170,8 +1160,7 @@ static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
err = PTR_ERR(path);
} else {
/* tree is full, time to grow in depth */
err = ext4_ext_grow_indepth(handle, inode, flags,
path, newext);
err = ext4_ext_grow_indepth(handle, inode, flags, newext);
if (err)
goto out;

Expand Down

0 comments on commit 1939dd8

Please sign in to comment.