diff options
| -rw-r--r-- | fs/ext4/extents.c | 41 |
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 | */ |
| 1051 | static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | 1051 | static 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); |
| 1126 | out: | 1116 | out: |
| 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 | ||
