diff options
author | Yongqiang Yang <xiaoqiangnk@gmail.com> | 2012-01-03 23:44:38 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2012-01-03 23:44:38 -0500 |
commit | 3fbea4b3683a5dfa86489ef7799cbe55e8003dfa (patch) | |
tree | 42d88ed8ecc885f262af7be3e8e66192c12af379 /fs/ext4 | |
parent | c72df9f928efd5b17e84bdb7b8ec1be3b9c1ea9d (diff) |
ext4: add a new function which allocates bitmaps and inode tables
This patch adds a new function named ext4_allocates_group_table()
which allocates block bitmaps, inode bitmaps and inode tables for a
flex groups and is used by resize code.
Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/resize.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 12eace096546..a4075de73c72 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -189,6 +189,117 @@ static void free_flex_gd(struct ext4_new_flex_group_data *flex_gd) | |||
189 | kfree(flex_gd); | 189 | kfree(flex_gd); |
190 | } | 190 | } |
191 | 191 | ||
192 | /* | ||
193 | * ext4_alloc_group_tables() allocates block bitmaps, inode bitmaps | ||
194 | * and inode tables for a flex group. | ||
195 | * | ||
196 | * This function is used by 64bit-resize. Note that this function allocates | ||
197 | * group tables from the 1st group of groups contained by @flexgd, which may | ||
198 | * be a partial of a flex group. | ||
199 | * | ||
200 | * @sb: super block of fs to which the groups belongs | ||
201 | */ | ||
202 | static void ext4_alloc_group_tables(struct super_block *sb, | ||
203 | struct ext4_new_flex_group_data *flex_gd, | ||
204 | int flexbg_size) | ||
205 | { | ||
206 | struct ext4_new_group_data *group_data = flex_gd->groups; | ||
207 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||
208 | ext4_fsblk_t start_blk; | ||
209 | ext4_fsblk_t last_blk; | ||
210 | ext4_group_t src_group; | ||
211 | ext4_group_t bb_index = 0; | ||
212 | ext4_group_t ib_index = 0; | ||
213 | ext4_group_t it_index = 0; | ||
214 | ext4_group_t group; | ||
215 | ext4_group_t last_group; | ||
216 | unsigned overhead; | ||
217 | |||
218 | BUG_ON(flex_gd->count == 0 || group_data == NULL); | ||
219 | |||
220 | src_group = group_data[0].group; | ||
221 | last_group = src_group + flex_gd->count - 1; | ||
222 | |||
223 | BUG_ON((flexbg_size > 1) && ((src_group & ~(flexbg_size - 1)) != | ||
224 | (last_group & ~(flexbg_size - 1)))); | ||
225 | next_group: | ||
226 | group = group_data[0].group; | ||
227 | start_blk = ext4_group_first_block_no(sb, src_group); | ||
228 | last_blk = start_blk + group_data[src_group - group].blocks_count; | ||
229 | |||
230 | overhead = ext4_bg_has_super(sb, src_group) ? | ||
231 | (1 + ext4_bg_num_gdb(sb, src_group) + | ||
232 | le16_to_cpu(es->s_reserved_gdt_blocks)) : 0; | ||
233 | |||
234 | start_blk += overhead; | ||
235 | |||
236 | BUG_ON(src_group >= group_data[0].group + flex_gd->count); | ||
237 | /* We collect contiguous blocks as much as possible. */ | ||
238 | src_group++; | ||
239 | for (; src_group <= last_group; src_group++) | ||
240 | if (!ext4_bg_has_super(sb, src_group)) | ||
241 | last_blk += group_data[src_group - group].blocks_count; | ||
242 | else | ||
243 | break; | ||
244 | |||
245 | /* Allocate block bitmaps */ | ||
246 | for (; bb_index < flex_gd->count; bb_index++) { | ||
247 | if (start_blk >= last_blk) | ||
248 | goto next_group; | ||
249 | group_data[bb_index].block_bitmap = start_blk++; | ||
250 | ext4_get_group_no_and_offset(sb, start_blk - 1, &group, NULL); | ||
251 | group -= group_data[0].group; | ||
252 | group_data[group].free_blocks_count--; | ||
253 | if (flexbg_size > 1) | ||
254 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
255 | } | ||
256 | |||
257 | /* Allocate inode bitmaps */ | ||
258 | for (; ib_index < flex_gd->count; ib_index++) { | ||
259 | if (start_blk >= last_blk) | ||
260 | goto next_group; | ||
261 | group_data[ib_index].inode_bitmap = start_blk++; | ||
262 | ext4_get_group_no_and_offset(sb, start_blk - 1, &group, NULL); | ||
263 | group -= group_data[0].group; | ||
264 | group_data[group].free_blocks_count--; | ||
265 | if (flexbg_size > 1) | ||
266 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
267 | } | ||
268 | |||
269 | /* Allocate inode tables */ | ||
270 | for (; it_index < flex_gd->count; it_index++) { | ||
271 | if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk) | ||
272 | goto next_group; | ||
273 | group_data[it_index].inode_table = start_blk; | ||
274 | ext4_get_group_no_and_offset(sb, start_blk, &group, NULL); | ||
275 | group -= group_data[0].group; | ||
276 | group_data[group].free_blocks_count -= | ||
277 | EXT4_SB(sb)->s_itb_per_group; | ||
278 | if (flexbg_size > 1) | ||
279 | flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT; | ||
280 | |||
281 | start_blk += EXT4_SB(sb)->s_itb_per_group; | ||
282 | } | ||
283 | |||
284 | if (test_opt(sb, DEBUG)) { | ||
285 | int i; | ||
286 | group = group_data[0].group; | ||
287 | |||
288 | printk(KERN_DEBUG "EXT4-fs: adding a flex group with " | ||
289 | "%d groups, flexbg size is %d:\n", flex_gd->count, | ||
290 | flexbg_size); | ||
291 | |||
292 | for (i = 0; i < flex_gd->count; i++) { | ||
293 | printk(KERN_DEBUG "adding %s group %u: %u " | ||
294 | "blocks (%d free)\n", | ||
295 | ext4_bg_has_super(sb, group + i) ? "normal" : | ||
296 | "no-super", group + i, | ||
297 | group_data[i].blocks_count, | ||
298 | group_data[i].free_blocks_count); | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | |||
192 | static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, | 303 | static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, |
193 | ext4_fsblk_t blk) | 304 | ext4_fsblk_t blk) |
194 | { | 305 | { |