aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/resize.c
diff options
context:
space:
mode:
authorYongqiang Yang <xiaoqiangnk@gmail.com>2012-01-03 23:44:38 -0500
committerTheodore Ts'o <tytso@mit.edu>2012-01-03 23:44:38 -0500
commit4bac1f8cef7bfd2c62793f75aba66a5b8357dede (patch)
tree0cef082f69c53b66ec84af8bfdd65e8ddbad9f32 /fs/ext4/resize.c
parent3fbea4b3683a5dfa86489ef7799cbe55e8003dfa (diff)
ext4: add a new function which adds a flex group to a fs
This patch adds a new function named ext4_flex_group_add() which adds a flex group to a fs. The function is used by 64bit-resize interface. Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/resize.c')
-rw-r--r--fs/ext4/resize.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index a4075de73c72..dac23561f3eb 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1348,6 +1348,88 @@ static void ext4_update_super(struct super_block *sb,
1348 blocks_count, free_blocks, reserved_blocks); 1348 blocks_count, free_blocks, reserved_blocks);
1349} 1349}
1350 1350
1351/* Add a flex group to an fs. Ensure we handle all possible error conditions
1352 * _before_ we start modifying the filesystem, because we cannot abort the
1353 * transaction and not have it write the data to disk.
1354 */
1355static int ext4_flex_group_add(struct super_block *sb,
1356 struct inode *resize_inode,
1357 struct ext4_new_flex_group_data *flex_gd)
1358{
1359 struct ext4_sb_info *sbi = EXT4_SB(sb);
1360 struct ext4_super_block *es = sbi->s_es;
1361 ext4_fsblk_t o_blocks_count;
1362 ext4_grpblk_t last;
1363 ext4_group_t group;
1364 handle_t *handle;
1365 unsigned reserved_gdb;
1366 int err = 0, err2 = 0, credit;
1367
1368 BUG_ON(!flex_gd->count || !flex_gd->groups || !flex_gd->bg_flags);
1369
1370 reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
1371 o_blocks_count = ext4_blocks_count(es);
1372 ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last);
1373 BUG_ON(last);
1374
1375 err = setup_new_flex_group_blocks(sb, flex_gd);
1376 if (err)
1377 goto exit;
1378 /*
1379 * We will always be modifying at least the superblock and GDT
1380 * block. If we are adding a group past the last current GDT block,
1381 * we will also modify the inode and the dindirect block. If we
1382 * are adding a group with superblock/GDT backups we will also
1383 * modify each of the reserved GDT dindirect blocks.
1384 */
1385 credit = flex_gd->count * 4 + reserved_gdb;
1386 handle = ext4_journal_start_sb(sb, credit);
1387 if (IS_ERR(handle)) {
1388 err = PTR_ERR(handle);
1389 goto exit;
1390 }
1391
1392 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
1393 if (err)
1394 goto exit_journal;
1395
1396 group = flex_gd->groups[0].group;
1397 BUG_ON(group != EXT4_SB(sb)->s_groups_count);
1398 err = ext4_add_new_descs(handle, sb, group,
1399 resize_inode, flex_gd->count);
1400 if (err)
1401 goto exit_journal;
1402
1403 err = ext4_setup_new_descs(handle, sb, flex_gd);
1404 if (err)
1405 goto exit_journal;
1406
1407 ext4_update_super(sb, flex_gd);
1408
1409 err = ext4_handle_dirty_super(handle, sb);
1410
1411exit_journal:
1412 err2 = ext4_journal_stop(handle);
1413 if (!err)
1414 err = err2;
1415
1416 if (!err) {
1417 int i;
1418 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
1419 sizeof(struct ext4_super_block));
1420 for (i = 0; i < flex_gd->count; i++, group++) {
1421 struct buffer_head *gdb_bh;
1422 int gdb_num;
1423 gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
1424 gdb_bh = sbi->s_group_desc[gdb_num];
1425 update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
1426 gdb_bh->b_size);
1427 }
1428 }
1429exit:
1430 return err;
1431}
1432
1351/* Add group descriptor data to an existing or new group descriptor block. 1433/* Add group descriptor data to an existing or new group descriptor block.
1352 * Ensure we handle all possible error conditions _before_ we start modifying 1434 * Ensure we handle all possible error conditions _before_ we start modifying
1353 * the filesystem, because we cannot abort the transaction and not have it 1435 * the filesystem, because we cannot abort the transaction and not have it