resize.c (01b944fe1cd4e21a2a9ed51adbdbafe2d5e905ba) resize.c (e2b911c53584a92266943f3b7f2cdbc19c1a4e80)
1/*
2 * linux/fs/ext4/resize.c
3 *
4 * Support for resizing an ext4 filesystem while it is mounted.
5 *
6 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com>
7 *
8 * This could probably be made into a module, because it is not often in use.

--- 476 unchanged lines hidden (view full) ---

485 struct buffer_head *bh = NULL;
486 int reserved_gdb, i, j, err = 0, err2;
487 int meta_bg;
488
489 BUG_ON(!flex_gd->count || !group_data ||
490 group_data[0].group != sbi->s_groups_count);
491
492 reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
1/*
2 * linux/fs/ext4/resize.c
3 *
4 * Support for resizing an ext4 filesystem while it is mounted.
5 *
6 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com>
7 *
8 * This could probably be made into a module, because it is not often in use.

--- 476 unchanged lines hidden (view full) ---

485 struct buffer_head *bh = NULL;
486 int reserved_gdb, i, j, err = 0, err2;
487 int meta_bg;
488
489 BUG_ON(!flex_gd->count || !group_data ||
490 group_data[0].group != sbi->s_groups_count);
491
492 reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
493 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
493 meta_bg = ext4_has_feature_meta_bg(sb);
494
495 /* This transaction may be extended/restarted along the way */
496 handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, EXT4_MAX_TRANS_DATA);
497 if (IS_ERR(handle))
498 return PTR_ERR(handle);
499
500 group = group_data[0].group;
501 for (i = 0; i < flex_gd->count; i++, group++) {

--- 173 unchanged lines hidden (view full) ---

675 */
676static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
677 unsigned *five, unsigned *seven)
678{
679 unsigned *min = three;
680 int mult = 3;
681 unsigned ret;
682
494
495 /* This transaction may be extended/restarted along the way */
496 handle = ext4_journal_start_sb(sb, EXT4_HT_RESIZE, EXT4_MAX_TRANS_DATA);
497 if (IS_ERR(handle))
498 return PTR_ERR(handle);
499
500 group = group_data[0].group;
501 for (i = 0; i < flex_gd->count; i++, group++) {

--- 173 unchanged lines hidden (view full) ---

675 */
676static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
677 unsigned *five, unsigned *seven)
678{
679 unsigned *min = three;
680 int mult = 3;
681 unsigned ret;
682
683 if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
684 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
683 if (!ext4_has_feature_sparse_super(sb)) {
685 ret = *min;
686 *min += 1;
687 return ret;
688 }
689
690 if (*five < *min) {
691 min = five;
692 mult = 5;

--- 460 unchanged lines hidden (view full) ---

1153 ext4_group_t count)
1154{
1155 struct ext4_sb_info *sbi = EXT4_SB(sb);
1156 struct ext4_super_block *es = sbi->s_es;
1157 struct buffer_head *gdb_bh;
1158 int i, gdb_off, gdb_num, err = 0;
1159 int meta_bg;
1160
684 ret = *min;
685 *min += 1;
686 return ret;
687 }
688
689 if (*five < *min) {
690 min = five;
691 mult = 5;

--- 460 unchanged lines hidden (view full) ---

1152 ext4_group_t count)
1153{
1154 struct ext4_sb_info *sbi = EXT4_SB(sb);
1155 struct ext4_super_block *es = sbi->s_es;
1156 struct buffer_head *gdb_bh;
1157 int i, gdb_off, gdb_num, err = 0;
1158 int meta_bg;
1159
1161 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1160 meta_bg = ext4_has_feature_meta_bg(sb);
1162 for (i = 0; i < count; i++, group++) {
1163 int reserved_gdb = ext4_bg_has_super(sb, group) ?
1164 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
1165
1166 gdb_off = group % EXT4_DESC_PER_BLOCK(sb);
1167 gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
1168
1169 /*

--- 206 unchanged lines hidden (view full) ---

1376 /* Update the free space counts */
1377 percpu_counter_add(&sbi->s_freeclusters_counter,
1378 EXT4_NUM_B2C(sbi, free_blocks));
1379 percpu_counter_add(&sbi->s_freeinodes_counter,
1380 EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
1381
1382 ext4_debug("free blocks count %llu",
1383 percpu_counter_read(&sbi->s_freeclusters_counter));
1161 for (i = 0; i < count; i++, group++) {
1162 int reserved_gdb = ext4_bg_has_super(sb, group) ?
1163 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
1164
1165 gdb_off = group % EXT4_DESC_PER_BLOCK(sb);
1166 gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
1167
1168 /*

--- 206 unchanged lines hidden (view full) ---

1375 /* Update the free space counts */
1376 percpu_counter_add(&sbi->s_freeclusters_counter,
1377 EXT4_NUM_B2C(sbi, free_blocks));
1378 percpu_counter_add(&sbi->s_freeinodes_counter,
1379 EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
1380
1381 ext4_debug("free blocks count %llu",
1382 percpu_counter_read(&sbi->s_freeclusters_counter));
1384 if (EXT4_HAS_INCOMPAT_FEATURE(sb,
1385 EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
1386 sbi->s_log_groups_per_flex) {
1383 if (ext4_has_feature_flex_bg(sb) && sbi->s_log_groups_per_flex) {
1387 ext4_group_t flex_group;
1388 flex_group = ext4_flex_group(sbi, group_data[0].group);
1389 atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
1390 &sbi->s_flex_groups[flex_group].free_clusters);
1391 atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
1392 &sbi->s_flex_groups[flex_group].free_inodes);
1393 }
1394

--- 76 unchanged lines hidden (view full) ---

1471 err2 = ext4_journal_stop(handle);
1472 if (!err)
1473 err = err2;
1474
1475 if (!err) {
1476 int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
1477 int gdb_num_end = ((group + flex_gd->count - 1) /
1478 EXT4_DESC_PER_BLOCK(sb));
1384 ext4_group_t flex_group;
1385 flex_group = ext4_flex_group(sbi, group_data[0].group);
1386 atomic64_add(EXT4_NUM_B2C(sbi, free_blocks),
1387 &sbi->s_flex_groups[flex_group].free_clusters);
1388 atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
1389 &sbi->s_flex_groups[flex_group].free_inodes);
1390 }
1391

--- 76 unchanged lines hidden (view full) ---

1468 err2 = ext4_journal_stop(handle);
1469 if (!err)
1470 err = err2;
1471
1472 if (!err) {
1473 int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
1474 int gdb_num_end = ((group + flex_gd->count - 1) /
1475 EXT4_DESC_PER_BLOCK(sb));
1479 int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
1480 EXT4_FEATURE_INCOMPAT_META_BG);
1476 int meta_bg = ext4_has_feature_meta_bg(sb);
1481 sector_t old_gdb = 0;
1482
1483 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
1484 sizeof(struct ext4_super_block), 0);
1485 for (; gdb_num <= gdb_num_end; gdb_num++) {
1486 struct buffer_head *gdb_bh;
1487
1488 gdb_bh = sbi->s_group_desc[gdb_num];

--- 91 unchanged lines hidden (view full) ---

1580 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
1581 struct inode *inode = NULL;
1582 int gdb_off;
1583 int err;
1584 __u16 bg_flags = 0;
1585
1586 gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
1587
1477 sector_t old_gdb = 0;
1478
1479 update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
1480 sizeof(struct ext4_super_block), 0);
1481 for (; gdb_num <= gdb_num_end; gdb_num++) {
1482 struct buffer_head *gdb_bh;
1483
1484 gdb_bh = sbi->s_group_desc[gdb_num];

--- 91 unchanged lines hidden (view full) ---

1576 le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
1577 struct inode *inode = NULL;
1578 int gdb_off;
1579 int err;
1580 __u16 bg_flags = 0;
1581
1582 gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
1583
1588 if (gdb_off == 0 && !EXT4_HAS_RO_COMPAT_FEATURE(sb,
1589 EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
1584 if (gdb_off == 0 && !ext4_has_feature_sparse_super(sb)) {
1590 ext4_warning(sb, "Can't resize non-sparse filesystem further");
1591 return -EPERM;
1592 }
1593
1594 if (ext4_blocks_count(es) + input->blocks_count <
1595 ext4_blocks_count(es)) {
1596 ext4_warning(sb, "blocks_count overflow");
1597 return -EINVAL;
1598 }
1599
1600 if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
1601 le32_to_cpu(es->s_inodes_count)) {
1602 ext4_warning(sb, "inodes_count overflow");
1603 return -EINVAL;
1604 }
1605
1606 if (reserved_gdb || gdb_off == 0) {
1585 ext4_warning(sb, "Can't resize non-sparse filesystem further");
1586 return -EPERM;
1587 }
1588
1589 if (ext4_blocks_count(es) + input->blocks_count <
1590 ext4_blocks_count(es)) {
1591 ext4_warning(sb, "blocks_count overflow");
1592 return -EINVAL;
1593 }
1594
1595 if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) <
1596 le32_to_cpu(es->s_inodes_count)) {
1597 ext4_warning(sb, "inodes_count overflow");
1598 return -EINVAL;
1599 }
1600
1601 if (reserved_gdb || gdb_off == 0) {
1607 if (!EXT4_HAS_COMPAT_FEATURE(sb,
1608 EXT4_FEATURE_COMPAT_RESIZE_INODE)
1609 || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
1602 if (ext4_has_feature_resize_inode(sb) ||
1603 !le16_to_cpu(es->s_reserved_gdt_blocks)) {
1610 ext4_warning(sb,
1611 "No reserved GDT blocks, can't resize");
1612 return -EPERM;
1613 }
1614 inode = ext4_iget(sb, EXT4_RESIZE_INO);
1615 if (IS_ERR(inode)) {
1616 ext4_warning(sb, "Error opening resize inode");
1617 return PTR_ERR(inode);

--- 202 unchanged lines hidden (view full) ---

1820 if (IS_ERR(handle))
1821 return PTR_ERR(handle);
1822
1823 BUFFER_TRACE(sbi->s_sbh, "get_write_access");
1824 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
1825 if (err)
1826 goto errout;
1827
1604 ext4_warning(sb,
1605 "No reserved GDT blocks, can't resize");
1606 return -EPERM;
1607 }
1608 inode = ext4_iget(sb, EXT4_RESIZE_INO);
1609 if (IS_ERR(inode)) {
1610 ext4_warning(sb, "Error opening resize inode");
1611 return PTR_ERR(inode);

--- 202 unchanged lines hidden (view full) ---

1814 if (IS_ERR(handle))
1815 return PTR_ERR(handle);
1816
1817 BUFFER_TRACE(sbi->s_sbh, "get_write_access");
1818 err = ext4_journal_get_write_access(handle, sbi->s_sbh);
1819 if (err)
1820 goto errout;
1821
1828 EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
1829 EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1822 ext4_clear_feature_resize_inode(sb);
1823 ext4_set_feature_meta_bg(sb);
1830 sbi->s_es->s_first_meta_bg =
1831 cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
1832
1833 err = ext4_handle_dirty_super(handle, sb);
1834 if (err) {
1835 ext4_std_error(sb, err);
1836 goto errout;
1837 }

--- 75 unchanged lines hidden (view full) ---

1913 ext4_warning(sb, "resize would cause inodes_count overflow");
1914 return -EINVAL;
1915 }
1916 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
1917
1918 n_desc_blocks = num_desc_blocks(sb, n_group + 1);
1919 o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
1920
1824 sbi->s_es->s_first_meta_bg =
1825 cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
1826
1827 err = ext4_handle_dirty_super(handle, sb);
1828 if (err) {
1829 ext4_std_error(sb, err);
1830 goto errout;
1831 }

--- 75 unchanged lines hidden (view full) ---

1907 ext4_warning(sb, "resize would cause inodes_count overflow");
1908 return -EINVAL;
1909 }
1910 ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
1911
1912 n_desc_blocks = num_desc_blocks(sb, n_group + 1);
1913 o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
1914
1921 meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
1915 meta_bg = ext4_has_feature_meta_bg(sb);
1922
1916
1923 if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
1917 if (ext4_has_feature_resize_inode(sb)) {
1924 if (meta_bg) {
1925 ext4_error(sb, "resize_inode and meta_bg enabled "
1926 "simultaneously");
1927 return -EINVAL;
1928 }
1929 if (n_desc_blocks > o_desc_blocks +
1930 le16_to_cpu(es->s_reserved_gdt_blocks)) {
1931 n_blocks_count_retry = n_blocks_count;

--- 93 unchanged lines hidden ---
1918 if (meta_bg) {
1919 ext4_error(sb, "resize_inode and meta_bg enabled "
1920 "simultaneously");
1921 return -EINVAL;
1922 }
1923 if (n_desc_blocks > o_desc_blocks +
1924 le16_to_cpu(es->s_reserved_gdt_blocks)) {
1925 n_blocks_count_retry = n_blocks_count;

--- 93 unchanged lines hidden ---