aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/resize.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/resize.c')
-rw-r--r--fs/ext4/resize.c432
1 files changed, 343 insertions, 89 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 41f6ef68e2e1..7a75e1086961 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -45,6 +45,28 @@ void ext4_resize_end(struct super_block *sb)
45 smp_mb__after_clear_bit(); 45 smp_mb__after_clear_bit();
46} 46}
47 47
48static ext4_group_t ext4_meta_bg_first_group(struct super_block *sb,
49 ext4_group_t group) {
50 return (group >> EXT4_DESC_PER_BLOCK_BITS(sb)) <<
51 EXT4_DESC_PER_BLOCK_BITS(sb);
52}
53
54static ext4_fsblk_t ext4_meta_bg_first_block_no(struct super_block *sb,
55 ext4_group_t group) {
56 group = ext4_meta_bg_first_group(sb, group);
57 return ext4_group_first_block_no(sb, group);
58}
59
60static ext4_grpblk_t ext4_group_overhead_blocks(struct super_block *sb,
61 ext4_group_t group) {
62 ext4_grpblk_t overhead;
63 overhead = ext4_bg_num_gdb(sb, group);
64 if (ext4_bg_has_super(sb, group))
65 overhead += 1 +
66 le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks);
67 return overhead;
68}
69
48#define outside(b, first, last) ((b) < (first) || (b) >= (last)) 70#define outside(b, first, last) ((b) < (first) || (b) >= (last))
49#define inside(b, first, last) ((b) >= (first) && (b) < (last)) 71#define inside(b, first, last) ((b) >= (first) && (b) < (last))
50 72
@@ -57,9 +79,7 @@ static int verify_group_input(struct super_block *sb,
57 ext4_fsblk_t end = start + input->blocks_count; 79 ext4_fsblk_t end = start + input->blocks_count;
58 ext4_group_t group = input->group; 80 ext4_group_t group = input->group;
59 ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group; 81 ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
60 unsigned overhead = ext4_bg_has_super(sb, group) ? 82 unsigned overhead = ext4_group_overhead_blocks(sb, group);
61 (1 + ext4_bg_num_gdb(sb, group) +
62 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
63 ext4_fsblk_t metaend = start + overhead; 83 ext4_fsblk_t metaend = start + overhead;
64 struct buffer_head *bh = NULL; 84 struct buffer_head *bh = NULL;
65 ext4_grpblk_t free_blocks_count, offset; 85 ext4_grpblk_t free_blocks_count, offset;
@@ -200,13 +220,15 @@ static void free_flex_gd(struct ext4_new_flex_group_data *flex_gd)
200 * be a partial of a flex group. 220 * be a partial of a flex group.
201 * 221 *
202 * @sb: super block of fs to which the groups belongs 222 * @sb: super block of fs to which the groups belongs
223 *
224 * Returns 0 on a successful allocation of the metadata blocks in the
225 * block group.
203 */ 226 */
204static void ext4_alloc_group_tables(struct super_block *sb, 227static int ext4_alloc_group_tables(struct super_block *sb,
205 struct ext4_new_flex_group_data *flex_gd, 228 struct ext4_new_flex_group_data *flex_gd,
206 int flexbg_size) 229 int flexbg_size)
207{ 230{
208 struct ext4_new_group_data *group_data = flex_gd->groups; 231 struct ext4_new_group_data *group_data = flex_gd->groups;
209 struct ext4_super_block *es = EXT4_SB(sb)->s_es;
210 ext4_fsblk_t start_blk; 232 ext4_fsblk_t start_blk;
211 ext4_fsblk_t last_blk; 233 ext4_fsblk_t last_blk;
212 ext4_group_t src_group; 234 ext4_group_t src_group;
@@ -226,23 +248,24 @@ static void ext4_alloc_group_tables(struct super_block *sb,
226 (last_group & ~(flexbg_size - 1)))); 248 (last_group & ~(flexbg_size - 1))));
227next_group: 249next_group:
228 group = group_data[0].group; 250 group = group_data[0].group;
251 if (src_group >= group_data[0].group + flex_gd->count)
252 return -ENOSPC;
229 start_blk = ext4_group_first_block_no(sb, src_group); 253 start_blk = ext4_group_first_block_no(sb, src_group);
230 last_blk = start_blk + group_data[src_group - group].blocks_count; 254 last_blk = start_blk + group_data[src_group - group].blocks_count;
231 255
232 overhead = ext4_bg_has_super(sb, src_group) ? 256 overhead = ext4_group_overhead_blocks(sb, src_group);
233 (1 + ext4_bg_num_gdb(sb, src_group) +
234 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
235 257
236 start_blk += overhead; 258 start_blk += overhead;
237 259
238 BUG_ON(src_group >= group_data[0].group + flex_gd->count);
239 /* We collect contiguous blocks as much as possible. */ 260 /* We collect contiguous blocks as much as possible. */
240 src_group++; 261 src_group++;
241 for (; src_group <= last_group; src_group++) 262 for (; src_group <= last_group; src_group++) {
242 if (!ext4_bg_has_super(sb, src_group)) 263 overhead = ext4_group_overhead_blocks(sb, src_group);
264 if (overhead != 0)
243 last_blk += group_data[src_group - group].blocks_count; 265 last_blk += group_data[src_group - group].blocks_count;
244 else 266 else
245 break; 267 break;
268 }
246 269
247 /* Allocate block bitmaps */ 270 /* Allocate block bitmaps */
248 for (; bb_index < flex_gd->count; bb_index++) { 271 for (; bb_index < flex_gd->count; bb_index++) {
@@ -300,6 +323,7 @@ next_group:
300 group_data[i].free_blocks_count); 323 group_data[i].free_blocks_count);
301 } 324 }
302 } 325 }
326 return 0;
303} 327}
304 328
305static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, 329static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
@@ -433,11 +457,13 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
433 ext4_group_t group, count; 457 ext4_group_t group, count;
434 struct buffer_head *bh = NULL; 458 struct buffer_head *bh = NULL;
435 int reserved_gdb, i, j, err = 0, err2; 459 int reserved_gdb, i, j, err = 0, err2;
460 int meta_bg;
436 461
437 BUG_ON(!flex_gd->count || !group_data || 462 BUG_ON(!flex_gd->count || !group_data ||
438 group_data[0].group != sbi->s_groups_count); 463 group_data[0].group != sbi->s_groups_count);
439 464
440 reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks); 465 reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
466 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
441 467
442 /* This transaction may be extended/restarted along the way */ 468 /* This transaction may be extended/restarted along the way */
443 handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA); 469 handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
@@ -447,12 +473,25 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
447 group = group_data[0].group; 473 group = group_data[0].group;
448 for (i = 0; i < flex_gd->count; i++, group++) { 474 for (i = 0; i < flex_gd->count; i++, group++) {
449 unsigned long gdblocks; 475 unsigned long gdblocks;
476 ext4_grpblk_t overhead;
450 477
451 gdblocks = ext4_bg_num_gdb(sb, group); 478 gdblocks = ext4_bg_num_gdb(sb, group);
452 start = ext4_group_first_block_no(sb, group); 479 start = ext4_group_first_block_no(sb, group);
453 480
481 if (meta_bg == 0 && !ext4_bg_has_super(sb, group))
482 goto handle_itb;
483
484 if (meta_bg == 1) {
485 ext4_group_t first_group;
486 first_group = ext4_meta_bg_first_group(sb, group);
487 if (first_group != group + 1 &&
488 first_group != group + EXT4_DESC_PER_BLOCK(sb) - 1)
489 goto handle_itb;
490 }
491
492 block = start + ext4_bg_has_super(sb, group);
454 /* Copy all of the GDT blocks into the backup in this group */ 493 /* Copy all of the GDT blocks into the backup in this group */
455 for (j = 0, block = start + 1; j < gdblocks; j++, block++) { 494 for (j = 0; j < gdblocks; j++, block++) {
456 struct buffer_head *gdb; 495 struct buffer_head *gdb;
457 496
458 ext4_debug("update backup group %#04llx\n", block); 497 ext4_debug("update backup group %#04llx\n", block);
@@ -493,6 +532,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
493 goto out; 532 goto out;
494 } 533 }
495 534
535handle_itb:
496 /* Initialize group tables of the grop @group */ 536 /* Initialize group tables of the grop @group */
497 if (!(bg_flags[i] & EXT4_BG_INODE_ZEROED)) 537 if (!(bg_flags[i] & EXT4_BG_INODE_ZEROED))
498 goto handle_bb; 538 goto handle_bb;
@@ -521,11 +561,11 @@ handle_bb:
521 err = PTR_ERR(bh); 561 err = PTR_ERR(bh);
522 goto out; 562 goto out;
523 } 563 }
524 if (ext4_bg_has_super(sb, group)) { 564 overhead = ext4_group_overhead_blocks(sb, group);
565 if (overhead != 0) {
525 ext4_debug("mark backup superblock %#04llx (+0)\n", 566 ext4_debug("mark backup superblock %#04llx (+0)\n",
526 start); 567 start);
527 ext4_set_bits(bh->b_data, 0, gdblocks + reserved_gdb + 568 ext4_set_bits(bh->b_data, 0, overhead);
528 1);
529 } 569 }
530 ext4_mark_bitmap_end(group_data[i].blocks_count, 570 ext4_mark_bitmap_end(group_data[i].blocks_count,
531 sb->s_blocksize * 8, bh->b_data); 571 sb->s_blocksize * 8, bh->b_data);
@@ -822,6 +862,45 @@ exit_bh:
822} 862}
823 863
824/* 864/*
865 * add_new_gdb_meta_bg is the sister of add_new_gdb.
866 */
867static int add_new_gdb_meta_bg(struct super_block *sb,
868 handle_t *handle, ext4_group_t group) {
869 ext4_fsblk_t gdblock;
870 struct buffer_head *gdb_bh;
871 struct buffer_head **o_group_desc, **n_group_desc;
872 unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
873 int err;
874
875 gdblock = ext4_meta_bg_first_block_no(sb, group) +
876 ext4_bg_has_super(sb, group);
877 gdb_bh = sb_bread(sb, gdblock);
878 if (!gdb_bh)
879 return -EIO;
880 n_group_desc = ext4_kvmalloc((gdb_num + 1) *
881 sizeof(struct buffer_head *),
882 GFP_NOFS);
883 if (!n_group_desc) {
884 err = -ENOMEM;
885 ext4_warning(sb, "not enough memory for %lu groups",
886 gdb_num + 1);
887 return err;
888 }
889
890 o_group_desc = EXT4_SB(sb)->s_group_desc;
891 memcpy(n_group_desc, o_group_desc,
892 EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
893 n_group_desc[gdb_num] = gdb_bh;
894 EXT4_SB(sb)->s_group_desc = n_group_desc;
895 EXT4_SB(sb)->s_gdb_count++;
896 ext4_kvfree(o_group_desc);
897 err = ext4_journal_get_write_access(handle, gdb_bh);
898 if (unlikely(err))
899 brelse(gdb_bh);
900 return err;
901}
902
903/*
825 * Called when we are adding a new group which has a backup copy of each of 904 * Called when we are adding a new group which has a backup copy of each of
826 * the GDT blocks (i.e. sparse group) and there are reserved GDT blocks. 905 * the GDT blocks (i.e. sparse group) and there are reserved GDT blocks.
827 * We need to add these reserved backup GDT blocks to the resize inode, so 906 * We need to add these reserved backup GDT blocks to the resize inode, so
@@ -949,16 +1028,16 @@ exit_free:
949 * do not copy the full number of backups at this time. The resize 1028 * do not copy the full number of backups at this time. The resize
950 * which changed s_groups_count will backup again. 1029 * which changed s_groups_count will backup again.
951 */ 1030 */
952static void update_backups(struct super_block *sb, 1031static void update_backups(struct super_block *sb, int blk_off, char *data,
953 int blk_off, char *data, int size) 1032 int size, int meta_bg)
954{ 1033{
955 struct ext4_sb_info *sbi = EXT4_SB(sb); 1034 struct ext4_sb_info *sbi = EXT4_SB(sb);
956 const ext4_group_t last = sbi->s_groups_count; 1035 ext4_group_t last;
957 const int bpg = EXT4_BLOCKS_PER_GROUP(sb); 1036 const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
958 unsigned three = 1; 1037 unsigned three = 1;
959 unsigned five = 5; 1038 unsigned five = 5;
960 unsigned seven = 7; 1039 unsigned seven = 7;
961 ext4_group_t group; 1040 ext4_group_t group = 0;
962 int rest = sb->s_blocksize - size; 1041 int rest = sb->s_blocksize - size;
963 handle_t *handle; 1042 handle_t *handle;
964 int err = 0, err2; 1043 int err = 0, err2;
@@ -970,10 +1049,17 @@ static void update_backups(struct super_block *sb,
970 goto exit_err; 1049 goto exit_err;
971 } 1050 }
972 1051
973 ext4_superblock_csum_set(sb, (struct ext4_super_block *)data); 1052 if (meta_bg == 0) {
1053 group = ext4_list_backups(sb, &three, &five, &seven);
1054 last = sbi->s_groups_count;
1055 } else {
1056 group = ext4_meta_bg_first_group(sb, group) + 1;
1057 last = (ext4_group_t)(group + EXT4_DESC_PER_BLOCK(sb) - 2);
1058 }
974 1059
975 while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) { 1060 while (group < sbi->s_groups_count) {
976 struct buffer_head *bh; 1061 struct buffer_head *bh;
1062 ext4_fsblk_t backup_block;
977 1063
978 /* Out of journal space, and can't get more - abort - so sad */ 1064 /* Out of journal space, and can't get more - abort - so sad */
979 if (ext4_handle_valid(handle) && 1065 if (ext4_handle_valid(handle) &&
@@ -982,13 +1068,20 @@ static void update_backups(struct super_block *sb,
982 (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA))) 1068 (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
983 break; 1069 break;
984 1070
985 bh = sb_getblk(sb, group * bpg + blk_off); 1071 if (meta_bg == 0)
1072 backup_block = group * bpg + blk_off;
1073 else
1074 backup_block = (ext4_group_first_block_no(sb, group) +
1075 ext4_bg_has_super(sb, group));
1076
1077 bh = sb_getblk(sb, backup_block);
986 if (!bh) { 1078 if (!bh) {
987 err = -EIO; 1079 err = -EIO;
988 break; 1080 break;
989 } 1081 }
990 ext4_debug("update metadata backup %#04lx\n", 1082 ext4_debug("update metadata backup %llu(+%llu)\n",
991 (unsigned long)bh->b_blocknr); 1083 backup_block, backup_block -
1084 ext4_group_first_block_no(sb, group));
992 if ((err = ext4_journal_get_write_access(handle, bh))) 1085 if ((err = ext4_journal_get_write_access(handle, bh)))
993 break; 1086 break;
994 lock_buffer(bh); 1087 lock_buffer(bh);
@@ -1001,6 +1094,13 @@ static void update_backups(struct super_block *sb,
1001 if (unlikely(err)) 1094 if (unlikely(err))
1002 ext4_std_error(sb, err); 1095 ext4_std_error(sb, err);
1003 brelse(bh); 1096 brelse(bh);
1097
1098 if (meta_bg == 0)
1099 group = ext4_list_backups(sb, &three, &five, &seven);
1100 else if (group == last)
1101 break;
1102 else
1103 group = last;
1004 } 1104 }
1005 if ((err2 = ext4_journal_stop(handle)) && !err) 1105 if ((err2 = ext4_journal_stop(handle)) && !err)
1006 err = err2; 1106 err = err2;
@@ -1043,7 +1143,9 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
1043 struct ext4_super_block *es = sbi->s_es; 1143 struct ext4_super_block *es = sbi->s_es;
1044 struct buffer_head *gdb_bh; 1144 struct buffer_head *gdb_bh;
1045 int i, gdb_off, gdb_num, err = 0; 1145 int i, gdb_off, gdb_num, err = 0;
1146 int meta_bg;
1046 1147
1148 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1047 for (i = 0; i < count; i++, group++) { 1149 for (i = 0; i < count; i++, group++) {
1048 int reserved_gdb = ext4_bg_has_super(sb, group) ? 1150 int reserved_gdb = ext4_bg_has_super(sb, group) ?
1049 le16_to_cpu(es->s_reserved_gdt_blocks) : 0; 1151 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
@@ -1063,8 +1165,11 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
1063 1165
1064 if (!err && reserved_gdb && ext4_bg_num_gdb(sb, group)) 1166 if (!err && reserved_gdb && ext4_bg_num_gdb(sb, group))
1065 err = reserve_backup_gdb(handle, resize_inode, group); 1167 err = reserve_backup_gdb(handle, resize_inode, group);
1066 } else 1168 } else if (meta_bg != 0) {
1169 err = add_new_gdb_meta_bg(sb, handle, group);
1170 } else {
1067 err = add_new_gdb(handle, resize_inode, group); 1171 err = add_new_gdb(handle, resize_inode, group);
1172 }
1068 if (err) 1173 if (err)
1069 break; 1174 break;
1070 } 1175 }
@@ -1076,17 +1181,12 @@ static struct buffer_head *ext4_get_bitmap(struct super_block *sb, __u64 block)
1076 struct buffer_head *bh = sb_getblk(sb, block); 1181 struct buffer_head *bh = sb_getblk(sb, block);
1077 if (!bh) 1182 if (!bh)
1078 return NULL; 1183 return NULL;
1079 1184 if (!bh_uptodate_or_lock(bh)) {
1080 if (bitmap_uptodate(bh)) 1185 if (bh_submit_read(bh) < 0) {
1081 return bh; 1186 brelse(bh);
1082 1187 return NULL;
1083 lock_buffer(bh); 1188 }
1084 if (bh_submit_read(bh) < 0) {
1085 unlock_buffer(bh);
1086 brelse(bh);
1087 return NULL;
1088 } 1189 }
1089 unlock_buffer(bh);
1090 1190
1091 return bh; 1191 return bh;
1092} 1192}
@@ -1161,6 +1261,9 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
1161 ext4_free_group_clusters_set(sb, gdp, 1261 ext4_free_group_clusters_set(sb, gdp,
1162 EXT4_B2C(sbi, group_data->free_blocks_count)); 1262 EXT4_B2C(sbi, group_data->free_blocks_count));
1163 ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); 1263 ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
1264 if (ext4_has_group_desc_csum(sb))
1265 ext4_itable_unused_set(sb, gdp,
1266 EXT4_INODES_PER_GROUP(sb));
1164 gdp->bg_flags = cpu_to_le16(*bg_flags); 1267 gdp->bg_flags = cpu_to_le16(*bg_flags);
1165 ext4_group_desc_csum_set(sb, group, gdp); 1268 ext4_group_desc_csum_set(sb, group, gdp);
1166 1269
@@ -1216,7 +1319,7 @@ static void ext4_update_super(struct super_block *sb,
1216 } 1319 }
1217 1320
1218 reserved_blocks = ext4_r_blocks_count(es) * 100; 1321 reserved_blocks = ext4_r_blocks_count(es) * 100;
1219 do_div(reserved_blocks, ext4_blocks_count(es)); 1322 reserved_blocks = div64_u64(reserved_blocks, ext4_blocks_count(es));
1220 reserved_blocks *= blocks_count; 1323 reserved_blocks *= blocks_count;
1221 do_div(reserved_blocks, 100); 1324 do_div(reserved_blocks, 100);
1222 1325
@@ -1227,6 +1330,7 @@ static void ext4_update_super(struct super_block *sb,
1227 le32_add_cpu(&es->s_free_inodes_count, EXT4_INODES_PER_GROUP(sb) * 1330 le32_add_cpu(&es->s_free_inodes_count, EXT4_INODES_PER_GROUP(sb) *
1228 flex_gd->count); 1331 flex_gd->count);
1229 1332
1333 ext4_debug("free blocks count %llu", ext4_free_blocks_count(es));
1230 /* 1334 /*
1231 * We need to protect s_groups_count against other CPUs seeing 1335 * We need to protect s_groups_count against other CPUs seeing
1232 * inconsistent state in the superblock. 1336 * inconsistent state in the superblock.
@@ -1261,6 +1365,8 @@ static void ext4_update_super(struct super_block *sb,
1261 percpu_counter_add(&sbi->s_freeinodes_counter, 1365 percpu_counter_add(&sbi->s_freeinodes_counter,
1262 EXT4_INODES_PER_GROUP(sb) * flex_gd->count); 1366 EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
1263 1367
1368 ext4_debug("free blocks count %llu",
1369 percpu_counter_read(&sbi->s_freeclusters_counter));
1264 if (EXT4_HAS_INCOMPAT_FEATURE(sb, 1370 if (EXT4_HAS_INCOMPAT_FEATURE(sb,
1265 EXT4_FEATURE_INCOMPAT_FLEX_BG) && 1371 EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
1266 sbi->s_log_groups_per_flex) { 1372 sbi->s_log_groups_per_flex) {
@@ -1349,16 +1455,24 @@ exit_journal:
1349 err = err2; 1455 err = err2;
1350 1456
1351 if (!err) { 1457 if (!err) {
1352 int i; 1458 int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
1459 int gdb_num_end = ((group + flex_gd->count - 1) /
1460 EXT4_DESC_PER_BLOCK(sb));
1461 int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
1462 EXT4_FEATURE_INCOMPAT_META_BG);
1463 sector_t old_gdb = 0;
1464
1353 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es, 1465 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
1354 sizeof(struct ext4_super_block)); 1466 sizeof(struct ext4_super_block), 0);
1355 for (i = 0; i < flex_gd->count; i++, group++) { 1467 for (; gdb_num <= gdb_num_end; gdb_num++) {
1356 struct buffer_head *gdb_bh; 1468 struct buffer_head *gdb_bh;
1357 int gdb_num; 1469
1358 gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
1359 gdb_bh = sbi->s_group_desc[gdb_num]; 1470 gdb_bh = sbi->s_group_desc[gdb_num];
1471 if (old_gdb == gdb_bh->b_blocknr)
1472 continue;
1360 update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data, 1473 update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
1361 gdb_bh->b_size); 1474 gdb_bh->b_size, meta_bg);
1475 old_gdb = gdb_bh->b_blocknr;
1362 } 1476 }
1363 } 1477 }
1364exit: 1478exit:
@@ -1402,9 +1516,7 @@ static int ext4_setup_next_flex_gd(struct super_block *sb,
1402 1516
1403 group_data[i].group = group + i; 1517 group_data[i].group = group + i;
1404 group_data[i].blocks_count = blocks_per_group; 1518 group_data[i].blocks_count = blocks_per_group;
1405 overhead = ext4_bg_has_super(sb, group + i) ? 1519 overhead = ext4_group_overhead_blocks(sb, group + i);
1406 (1 + ext4_bg_num_gdb(sb, group + i) +
1407 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
1408 group_data[i].free_blocks_count = blocks_per_group - overhead; 1520 group_data[i].free_blocks_count = blocks_per_group - overhead;
1409 if (ext4_has_group_desc_csum(sb)) 1521 if (ext4_has_group_desc_csum(sb))
1410 flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT | 1522 flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT |
@@ -1492,6 +1604,14 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
1492 if (err) 1604 if (err)
1493 goto out; 1605 goto out;
1494 1606
1607 err = ext4_alloc_flex_bg_array(sb, input->group + 1);
1608 if (err)
1609 return err;
1610
1611 err = ext4_mb_alloc_groupinfo(sb, input->group + 1);
1612 if (err)
1613 goto out;
1614
1495 flex_gd.count = 1; 1615 flex_gd.count = 1;
1496 flex_gd.groups = input; 1616 flex_gd.groups = input;
1497 flex_gd.bg_flags = &bg_flags; 1617 flex_gd.bg_flags = &bg_flags;
@@ -1544,11 +1664,13 @@ errout:
1544 err = err2; 1664 err = err2;
1545 1665
1546 if (!err) { 1666 if (!err) {
1667 ext4_fsblk_t first_block;
1668 first_block = ext4_group_first_block_no(sb, 0);
1547 if (test_opt(sb, DEBUG)) 1669 if (test_opt(sb, DEBUG))
1548 printk(KERN_DEBUG "EXT4-fs: extended group to %llu " 1670 printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
1549 "blocks\n", ext4_blocks_count(es)); 1671 "blocks\n", ext4_blocks_count(es));
1550 update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es, 1672 update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr - first_block,
1551 sizeof(struct ext4_super_block)); 1673 (char *)es, sizeof(struct ext4_super_block), 0);
1552 } 1674 }
1553 return err; 1675 return err;
1554} 1676}
@@ -1631,6 +1753,94 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
1631 return err; 1753 return err;
1632} /* ext4_group_extend */ 1754} /* ext4_group_extend */
1633 1755
1756
1757static int num_desc_blocks(struct super_block *sb, ext4_group_t groups)
1758{
1759 return (groups + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb);
1760}
1761
1762/*
1763 * Release the resize inode and drop the resize_inode feature if there
1764 * are no more reserved gdt blocks, and then convert the file system
1765 * to enable meta_bg
1766 */
1767static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
1768{
1769 handle_t *handle;
1770 struct ext4_sb_info *sbi = EXT4_SB(sb);
1771 struct ext4_super_block *es = sbi->s_es;
1772 struct ext4_inode_info *ei = EXT4_I(inode);
1773 ext4_fsblk_t nr;
1774 int i, ret, err = 0;
1775 int credits = 1;
1776
1777 ext4_msg(sb, KERN_INFO, "Converting file system to meta_bg");
1778 if (inode) {
1779 if (es->s_reserved_gdt_blocks) {
1780 ext4_error(sb, "Unexpected non-zero "
1781 "s_reserved_gdt_blocks");
1782 return -EPERM;
1783 }
1784
1785 /* Do a quick sanity check of the resize inode */
1786 if (inode->i_blocks != 1 << (inode->i_blkbits - 9))
1787 goto invalid_resize_inode;
1788 for (i = 0; i < EXT4_N_BLOCKS; i++) {
1789 if (i == EXT4_DIND_BLOCK) {
1790 if (ei->i_data[i])
1791 continue;
1792 else
1793 goto invalid_resize_inode;
1794 }
1795 if (ei->i_data[i])
1796 goto invalid_resize_inode;
1797 }
1798 credits += 3; /* block bitmap, bg descriptor, resize inode */
1799 }
1800
1801 handle = ext4_journal_start_sb(sb, credits);
1802 if (IS_ERR(handle))
1803 return PTR_ERR(handle);
1804
1805 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
1806 if (err)
1807 goto errout;
1808
1809 EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
1810 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1811 sbi->s_es->s_first_meta_bg =
1812 cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
1813
1814 err = ext4_handle_dirty_super(handle, sb);
1815 if (err) {
1816 ext4_std_error(sb, err);
1817 goto errout;
1818 }
1819
1820 if (inode) {
1821 nr = le32_to_cpu(ei->i_data[EXT4_DIND_BLOCK]);
1822 ext4_free_blocks(handle, inode, NULL, nr, 1,
1823 EXT4_FREE_BLOCKS_METADATA |
1824 EXT4_FREE_BLOCKS_FORGET);
1825 ei->i_data[EXT4_DIND_BLOCK] = 0;
1826 inode->i_blocks = 0;
1827
1828 err = ext4_mark_inode_dirty(handle, inode);
1829 if (err)
1830 ext4_std_error(sb, err);
1831 }
1832
1833errout:
1834 ret = ext4_journal_stop(handle);
1835 if (!err)
1836 err = ret;
1837 return ret;
1838
1839invalid_resize_inode:
1840 ext4_error(sb, "corrupted/inconsistent resize inode");
1841 return -EINVAL;
1842}
1843
1634/* 1844/*
1635 * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count 1845 * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
1636 * 1846 *
@@ -1643,21 +1853,31 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1643 struct ext4_sb_info *sbi = EXT4_SB(sb); 1853 struct ext4_sb_info *sbi = EXT4_SB(sb);
1644 struct ext4_super_block *es = sbi->s_es; 1854 struct ext4_super_block *es = sbi->s_es;
1645 struct buffer_head *bh; 1855 struct buffer_head *bh;
1646 struct inode *resize_inode; 1856 struct inode *resize_inode = NULL;
1647 ext4_fsblk_t o_blocks_count; 1857 ext4_grpblk_t add, offset;
1648 ext4_group_t o_group;
1649 ext4_group_t n_group;
1650 ext4_grpblk_t offset, add;
1651 unsigned long n_desc_blocks; 1858 unsigned long n_desc_blocks;
1652 unsigned long o_desc_blocks; 1859 unsigned long o_desc_blocks;
1653 unsigned long desc_blocks; 1860 ext4_group_t o_group;
1654 int err = 0, flexbg_size = 1; 1861 ext4_group_t n_group;
1862 ext4_fsblk_t o_blocks_count;
1863 ext4_fsblk_t n_blocks_count_retry = 0;
1864 unsigned long last_update_time = 0;
1865 int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex;
1866 int meta_bg;
1655 1867
1868 /* See if the device is actually as big as what was requested */
1869 bh = sb_bread(sb, n_blocks_count - 1);
1870 if (!bh) {
1871 ext4_warning(sb, "can't read last block, resize aborted");
1872 return -ENOSPC;
1873 }
1874 brelse(bh);
1875
1876retry:
1656 o_blocks_count = ext4_blocks_count(es); 1877 o_blocks_count = ext4_blocks_count(es);
1657 1878
1658 if (test_opt(sb, DEBUG)) 1879 ext4_msg(sb, KERN_INFO, "resizing filesystem from %llu "
1659 ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu " 1880 "to %llu blocks", o_blocks_count, n_blocks_count);
1660 "to %llu blocks", o_blocks_count, n_blocks_count);
1661 1881
1662 if (n_blocks_count < o_blocks_count) { 1882 if (n_blocks_count < o_blocks_count) {
1663 /* On-line shrinking not supported */ 1883 /* On-line shrinking not supported */
@@ -1672,32 +1892,49 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1672 ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset); 1892 ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
1673 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset); 1893 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
1674 1894
1675 n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) / 1895 n_desc_blocks = num_desc_blocks(sb, n_group + 1);
1676 EXT4_DESC_PER_BLOCK(sb); 1896 o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
1677 o_desc_blocks = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
1678 EXT4_DESC_PER_BLOCK(sb);
1679 desc_blocks = n_desc_blocks - o_desc_blocks;
1680 1897
1681 if (desc_blocks && 1898 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1682 (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE) ||
1683 le16_to_cpu(es->s_reserved_gdt_blocks) < desc_blocks)) {
1684 ext4_warning(sb, "No reserved GDT blocks, can't resize");
1685 return -EPERM;
1686 }
1687 1899
1688 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); 1900 if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
1689 if (IS_ERR(resize_inode)) { 1901 if (meta_bg) {
1690 ext4_warning(sb, "Error opening resize inode"); 1902 ext4_error(sb, "resize_inode and meta_bg enabled "
1691 return PTR_ERR(resize_inode); 1903 "simultaneously");
1904 return -EINVAL;
1905 }
1906 if (n_desc_blocks > o_desc_blocks +
1907 le16_to_cpu(es->s_reserved_gdt_blocks)) {
1908 n_blocks_count_retry = n_blocks_count;
1909 n_desc_blocks = o_desc_blocks +
1910 le16_to_cpu(es->s_reserved_gdt_blocks);
1911 n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
1912 n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
1913 n_group--; /* set to last group number */
1914 }
1915
1916 if (!resize_inode)
1917 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
1918 if (IS_ERR(resize_inode)) {
1919 ext4_warning(sb, "Error opening resize inode");
1920 return PTR_ERR(resize_inode);
1921 }
1692 } 1922 }
1693 1923
1694 /* See if the device is actually as big as what was requested */ 1924 if ((!resize_inode && !meta_bg) || n_blocks_count == o_blocks_count) {
1695 bh = sb_bread(sb, n_blocks_count - 1); 1925 err = ext4_convert_meta_bg(sb, resize_inode);
1696 if (!bh) { 1926 if (err)
1697 ext4_warning(sb, "can't read last block, resize aborted"); 1927 goto out;
1698 return -ENOSPC; 1928 if (resize_inode) {
1929 iput(resize_inode);
1930 resize_inode = NULL;
1931 }
1932 if (n_blocks_count_retry) {
1933 n_blocks_count = n_blocks_count_retry;
1934 n_blocks_count_retry = 0;
1935 goto retry;
1936 }
1699 } 1937 }
1700 brelse(bh);
1701 1938
1702 /* extend the last group */ 1939 /* extend the last group */
1703 if (n_group == o_group) 1940 if (n_group == o_group)
@@ -1710,12 +1947,15 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1710 goto out; 1947 goto out;
1711 } 1948 }
1712 1949
1713 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) && 1950 if (ext4_blocks_count(es) == n_blocks_count)
1714 es->s_log_groups_per_flex) 1951 goto out;
1715 flexbg_size = 1 << es->s_log_groups_per_flex;
1716 1952
1717 o_blocks_count = ext4_blocks_count(es); 1953 err = ext4_alloc_flex_bg_array(sb, n_group + 1);
1718 if (o_blocks_count == n_blocks_count) 1954 if (err)
1955 return err;
1956
1957 err = ext4_mb_alloc_groupinfo(sb, n_group + 1);
1958 if (err)
1719 goto out; 1959 goto out;
1720 1960
1721 flex_gd = alloc_flex_gd(flexbg_size); 1961 flex_gd = alloc_flex_gd(flexbg_size);
@@ -1729,19 +1969,33 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
1729 */ 1969 */
1730 while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count, 1970 while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,
1731 flexbg_size)) { 1971 flexbg_size)) {
1732 ext4_alloc_group_tables(sb, flex_gd, flexbg_size); 1972 if (jiffies - last_update_time > HZ * 10) {
1973 if (last_update_time)
1974 ext4_msg(sb, KERN_INFO,
1975 "resized to %llu blocks",
1976 ext4_blocks_count(es));
1977 last_update_time = jiffies;
1978 }
1979 if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
1980 break;
1733 err = ext4_flex_group_add(sb, resize_inode, flex_gd); 1981 err = ext4_flex_group_add(sb, resize_inode, flex_gd);
1734 if (unlikely(err)) 1982 if (unlikely(err))
1735 break; 1983 break;
1736 } 1984 }
1737 1985
1986 if (!err && n_blocks_count_retry) {
1987 n_blocks_count = n_blocks_count_retry;
1988 n_blocks_count_retry = 0;
1989 free_flex_gd(flex_gd);
1990 flex_gd = NULL;
1991 goto retry;
1992 }
1993
1738out: 1994out:
1739 if (flex_gd) 1995 if (flex_gd)
1740 free_flex_gd(flex_gd); 1996 free_flex_gd(flex_gd);
1741 1997 if (resize_inode != NULL)
1742 iput(resize_inode); 1998 iput(resize_inode);
1743 if (test_opt(sb, DEBUG)) 1999 ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", n_blocks_count);
1744 ext4_msg(sb, KERN_DEBUG, "resized filesystem from %llu "
1745 "upto %llu blocks", o_blocks_count, n_blocks_count);
1746 return err; 2000 return err;
1747} 2001}