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 --- |