aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2011-10-22 01:26:05 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-10-22 01:26:05 -0400
commit1939dd84b3f52e9c8d1b46dffae2058f16a3ff6a (patch)
treef1b30614ea4c4e991abb279c9d7d181e207c7148 /fs/ext4
parent45dc63e7d8412546567399b94caeb683af58843e (diff)
ext4: cleanup ext4_ext_grow_indepth code
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>
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/extents.c41
1 files changed, 15 insertions, 26 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 2fc6cc0a51ca..385ebb435332 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1050,16 +1050,14 @@ cleanup:
1050 */ 1050 */
1051static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, 1051static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1052 unsigned int flags, 1052 unsigned int flags,
1053 struct ext4_ext_path *path,
1054 struct ext4_extent *newext) 1053 struct ext4_extent *newext)
1055{ 1054{
1056 struct ext4_ext_path *curp = path;
1057 struct ext4_extent_header *neh; 1055 struct ext4_extent_header *neh;
1058 struct buffer_head *bh; 1056 struct buffer_head *bh;
1059 ext4_fsblk_t newblock; 1057 ext4_fsblk_t newblock;
1060 int err = 0; 1058 int err = 0;
1061 1059
1062 newblock = ext4_ext_new_meta_block(handle, inode, path, 1060 newblock = ext4_ext_new_meta_block(handle, inode, NULL,
1063 newext, &err, flags); 1061 newext, &err, flags);
1064 if (newblock == 0) 1062 if (newblock == 0)
1065 return err; 1063 return err;
@@ -1079,7 +1077,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1079 } 1077 }
1080 1078
1081 /* move top-level index/leaf into new block */ 1079 /* move top-level index/leaf into new block */
1082 memmove(bh->b_data, curp->p_hdr, sizeof(EXT4_I(inode)->i_data)); 1080 memmove(bh->b_data, EXT4_I(inode)->i_data,
1081 sizeof(EXT4_I(inode)->i_data));
1083 1082
1084 /* set size of new block */ 1083 /* set size of new block */
1085 neh = ext_block_hdr(bh); 1084 neh = ext_block_hdr(bh);
@@ -1097,32 +1096,23 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1097 if (err) 1096 if (err)
1098 goto out; 1097 goto out;
1099 1098
1100 /* create index in new top-level index: num,max,pointer */ 1099 /* Update top-level index: num,max,pointer */
1101 err = ext4_ext_get_access(handle, inode, curp);
1102 if (err)
1103 goto out;
1104
1105 curp->p_hdr->eh_magic = EXT4_EXT_MAGIC;
1106 curp->p_hdr->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
1107 curp->p_hdr->eh_entries = cpu_to_le16(1);
1108 curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr);
1109
1110 if (path[0].p_hdr->eh_depth)
1111 curp->p_idx->ei_block =
1112 EXT_FIRST_INDEX(path[0].p_hdr)->ei_block;
1113 else
1114 curp->p_idx->ei_block =
1115 EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block;
1116 ext4_idx_store_pblock(curp->p_idx, newblock);
1117
1118 neh = ext_inode_hdr(inode); 1100 neh = ext_inode_hdr(inode);
1101 neh->eh_entries = cpu_to_le16(1);
1102 ext4_idx_store_pblock(EXT_FIRST_INDEX(neh), newblock);
1103 if (neh->eh_depth == 0) {
1104 /* Root extent block becomes index block */
1105 neh->eh_max = cpu_to_le16(ext4_ext_space_root_idx(inode, 0));
1106 EXT_FIRST_INDEX(neh)->ei_block =
1107 EXT_FIRST_EXTENT(neh)->ee_block;
1108 }
1119 ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n", 1109 ext_debug("new root: num %d(%d), lblock %d, ptr %llu\n",
1120 le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max), 1110 le16_to_cpu(neh->eh_entries), le16_to_cpu(neh->eh_max),
1121 le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block), 1111 le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block),
1122 ext4_idx_pblock(EXT_FIRST_INDEX(neh))); 1112 ext4_idx_pblock(EXT_FIRST_INDEX(neh)));
1123 1113
1124 neh->eh_depth = cpu_to_le16(path->p_depth + 1); 1114 neh->eh_depth = cpu_to_le16(neh->eh_depth + 1);
1125 err = ext4_ext_dirty(handle, inode, curp); 1115 ext4_mark_inode_dirty(handle, inode);
1126out: 1116out:
1127 brelse(bh); 1117 brelse(bh);
1128 1118
@@ -1170,8 +1160,7 @@ repeat:
1170 err = PTR_ERR(path); 1160 err = PTR_ERR(path);
1171 } else { 1161 } else {
1172 /* tree is full, time to grow in depth */ 1162 /* tree is full, time to grow in depth */
1173 err = ext4_ext_grow_indepth(handle, inode, flags, 1163 err = ext4_ext_grow_indepth(handle, inode, flags, newext);
1174 path, newext);
1175 if (err) 1164 if (err)
1176 goto out; 1165 goto out;
1177 1166