resize.c (ccec4a4a4f27b22e51ec6a143319db49b7570581) | resize.c (8a363970d1dc38c4ec4ad575c862f776f468d057) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/ext4/resize.c 4 * 5 * Support for resizing an ext4 filesystem while it is mounted. 6 * 7 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com> 8 * --- 113 unchanged lines hidden (view full) --- 122 if (offset != 0) 123 ext4_warning(sb, "Last group not full"); 124 else if (input->reserved_blocks > input->blocks_count / 5) 125 ext4_warning(sb, "Reserved blocks too high (%u)", 126 input->reserved_blocks); 127 else if (free_blocks_count < 0) 128 ext4_warning(sb, "Bad blocks count %u", 129 input->blocks_count); | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/fs/ext4/resize.c 4 * 5 * Support for resizing an ext4 filesystem while it is mounted. 6 * 7 * Copyright (C) 2001, 2002 Andreas Dilger <adilger@clusterfs.com> 8 * --- 113 unchanged lines hidden (view full) --- 122 if (offset != 0) 123 ext4_warning(sb, "Last group not full"); 124 else if (input->reserved_blocks > input->blocks_count / 5) 125 ext4_warning(sb, "Reserved blocks too high (%u)", 126 input->reserved_blocks); 127 else if (free_blocks_count < 0) 128 ext4_warning(sb, "Bad blocks count %u", 129 input->blocks_count); |
130 else if (!(bh = sb_bread(sb, end - 1))) | 130 else if (IS_ERR(bh = ext4_sb_bread(sb, end - 1, 0))) { 131 err = PTR_ERR(bh); 132 bh = NULL; |
131 ext4_warning(sb, "Cannot read last block (%llu)", 132 end - 1); | 133 ext4_warning(sb, "Cannot read last block (%llu)", 134 end - 1); |
133 else if (outside(input->block_bitmap, start, end)) | 135 } else if (outside(input->block_bitmap, start, end)) |
134 ext4_warning(sb, "Block bitmap not in group (block %llu)", 135 (unsigned long long)input->block_bitmap); 136 else if (outside(input->inode_bitmap, start, end)) 137 ext4_warning(sb, "Inode bitmap not in group (block %llu)", 138 (unsigned long long)input->inode_bitmap); 139 else if (outside(input->inode_table, start, end) || 140 outside(itend - 1, start, end)) 141 ext4_warning(sb, "Inode table not in group (blocks %llu-%llu)", --- 634 unchanged lines hidden (view full) --- 776 */ 777static int add_new_gdb(handle_t *handle, struct inode *inode, 778 ext4_group_t group) 779{ 780 struct super_block *sb = inode->i_sb; 781 struct ext4_super_block *es = EXT4_SB(sb)->s_es; 782 unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); 783 ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; | 136 ext4_warning(sb, "Block bitmap not in group (block %llu)", 137 (unsigned long long)input->block_bitmap); 138 else if (outside(input->inode_bitmap, start, end)) 139 ext4_warning(sb, "Inode bitmap not in group (block %llu)", 140 (unsigned long long)input->inode_bitmap); 141 else if (outside(input->inode_table, start, end) || 142 outside(itend - 1, start, end)) 143 ext4_warning(sb, "Inode table not in group (blocks %llu-%llu)", --- 634 unchanged lines hidden (view full) --- 778 */ 779static int add_new_gdb(handle_t *handle, struct inode *inode, 780 ext4_group_t group) 781{ 782 struct super_block *sb = inode->i_sb; 783 struct ext4_super_block *es = EXT4_SB(sb)->s_es; 784 unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); 785 ext4_fsblk_t gdblock = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + gdb_num; |
784 struct buffer_head **o_group_desc, **n_group_desc; 785 struct buffer_head *dind; 786 struct buffer_head *gdb_bh; | 786 struct buffer_head **o_group_desc, **n_group_desc = NULL; 787 struct buffer_head *dind = NULL; 788 struct buffer_head *gdb_bh = NULL; |
787 int gdbackups; | 789 int gdbackups; |
788 struct ext4_iloc iloc; | 790 struct ext4_iloc iloc = { .bh = NULL }; |
789 __le32 *data; 790 int err; 791 792 if (test_opt(sb, DEBUG)) 793 printk(KERN_DEBUG 794 "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", 795 gdb_num); 796 | 791 __le32 *data; 792 int err; 793 794 if (test_opt(sb, DEBUG)) 795 printk(KERN_DEBUG 796 "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", 797 gdb_num); 798 |
797 gdb_bh = sb_bread(sb, gdblock); 798 if (!gdb_bh) 799 return -EIO; | 799 gdb_bh = ext4_sb_bread(sb, gdblock, 0); 800 if (IS_ERR(gdb_bh)) 801 return PTR_ERR(gdb_bh); |
800 801 gdbackups = verify_reserved_gdb(sb, group, gdb_bh); 802 if (gdbackups < 0) { 803 err = gdbackups; | 802 803 gdbackups = verify_reserved_gdb(sb, group, gdb_bh); 804 if (gdbackups < 0) { 805 err = gdbackups; |
804 goto exit_bh; | 806 goto errout; |
805 } 806 807 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; | 807 } 808 809 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; |
808 dind = sb_bread(sb, le32_to_cpu(*data)); 809 if (!dind) { 810 err = -EIO; 811 goto exit_bh; | 810 dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); 811 if (IS_ERR(dind)) { 812 err = PTR_ERR(dind); 813 dind = NULL; 814 goto errout; |
812 } 813 814 data = (__le32 *)dind->b_data; 815 if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) { 816 ext4_warning(sb, "new group %u GDT block %llu not reserved", 817 group, gdblock); 818 err = -EINVAL; | 815 } 816 817 data = (__le32 *)dind->b_data; 818 if (le32_to_cpu(data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)]) != gdblock) { 819 ext4_warning(sb, "new group %u GDT block %llu not reserved", 820 group, gdblock); 821 err = -EINVAL; |
819 goto exit_dind; | 822 goto errout; |
820 } 821 822 BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); 823 err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); 824 if (unlikely(err)) | 823 } 824 825 BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access"); 826 err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh); 827 if (unlikely(err)) |
825 goto exit_dind; | 828 goto errout; |
826 827 BUFFER_TRACE(gdb_bh, "get_write_access"); 828 err = ext4_journal_get_write_access(handle, gdb_bh); 829 if (unlikely(err)) | 829 830 BUFFER_TRACE(gdb_bh, "get_write_access"); 831 err = ext4_journal_get_write_access(handle, gdb_bh); 832 if (unlikely(err)) |
830 goto exit_dind; | 833 goto errout; |
831 832 BUFFER_TRACE(dind, "get_write_access"); 833 err = ext4_journal_get_write_access(handle, dind); 834 if (unlikely(err)) 835 ext4_std_error(sb, err); 836 837 /* ext4_reserve_inode_write() gets a reference on the iloc */ 838 err = ext4_reserve_inode_write(handle, inode, &iloc); 839 if (unlikely(err)) | 834 835 BUFFER_TRACE(dind, "get_write_access"); 836 err = ext4_journal_get_write_access(handle, dind); 837 if (unlikely(err)) 838 ext4_std_error(sb, err); 839 840 /* ext4_reserve_inode_write() gets a reference on the iloc */ 841 err = ext4_reserve_inode_write(handle, inode, &iloc); 842 if (unlikely(err)) |
840 goto exit_dind; | 843 goto errout; |
841 842 n_group_desc = ext4_kvmalloc((gdb_num + 1) * 843 sizeof(struct buffer_head *), 844 GFP_NOFS); 845 if (!n_group_desc) { 846 err = -ENOMEM; 847 ext4_warning(sb, "not enough memory for %lu groups", 848 gdb_num + 1); | 844 845 n_group_desc = ext4_kvmalloc((gdb_num + 1) * 846 sizeof(struct buffer_head *), 847 GFP_NOFS); 848 if (!n_group_desc) { 849 err = -ENOMEM; 850 ext4_warning(sb, "not enough memory for %lu groups", 851 gdb_num + 1); |
849 goto exit_inode; | 852 goto errout; |
850 } 851 852 /* 853 * Finally, we have all of the possible failures behind us... 854 * 855 * Remove new GDT block from inode double-indirect block and clear out 856 * the new GDT block for use (which also "frees" the backup GDT blocks 857 * from the reserved inode). We don't need to change the bitmaps for 858 * these blocks, because they are marked as in-use from being in the 859 * reserved inode, and will become GDT blocks (primary and backup). 860 */ 861 data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0; 862 err = ext4_handle_dirty_metadata(handle, NULL, dind); 863 if (unlikely(err)) { 864 ext4_std_error(sb, err); | 853 } 854 855 /* 856 * Finally, we have all of the possible failures behind us... 857 * 858 * Remove new GDT block from inode double-indirect block and clear out 859 * the new GDT block for use (which also "frees" the backup GDT blocks 860 * from the reserved inode). We don't need to change the bitmaps for 861 * these blocks, because they are marked as in-use from being in the 862 * reserved inode, and will become GDT blocks (primary and backup). 863 */ 864 data[gdb_num % EXT4_ADDR_PER_BLOCK(sb)] = 0; 865 err = ext4_handle_dirty_metadata(handle, NULL, dind); 866 if (unlikely(err)) { 867 ext4_std_error(sb, err); |
865 goto exit_inode; | 868 goto errout; |
866 } 867 inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 868 (9 - EXT4_SB(sb)->s_cluster_bits); 869 ext4_mark_iloc_dirty(handle, inode, &iloc); 870 memset(gdb_bh->b_data, 0, sb->s_blocksize); 871 err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); 872 if (unlikely(err)) { 873 ext4_std_error(sb, err); | 869 } 870 inode->i_blocks -= (gdbackups + 1) * sb->s_blocksize >> 871 (9 - EXT4_SB(sb)->s_cluster_bits); 872 ext4_mark_iloc_dirty(handle, inode, &iloc); 873 memset(gdb_bh->b_data, 0, sb->s_blocksize); 874 err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); 875 if (unlikely(err)) { 876 ext4_std_error(sb, err); |
874 iloc.bh = NULL; 875 goto exit_inode; | 877 goto errout; |
876 } 877 brelse(dind); 878 879 o_group_desc = EXT4_SB(sb)->s_group_desc; 880 memcpy(n_group_desc, o_group_desc, 881 EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *)); 882 n_group_desc[gdb_num] = gdb_bh; 883 EXT4_SB(sb)->s_group_desc = n_group_desc; 884 EXT4_SB(sb)->s_gdb_count++; 885 kvfree(o_group_desc); 886 887 le16_add_cpu(&es->s_reserved_gdt_blocks, -1); 888 err = ext4_handle_dirty_super(handle, sb); 889 if (err) 890 ext4_std_error(sb, err); | 878 } 879 brelse(dind); 880 881 o_group_desc = EXT4_SB(sb)->s_group_desc; 882 memcpy(n_group_desc, o_group_desc, 883 EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *)); 884 n_group_desc[gdb_num] = gdb_bh; 885 EXT4_SB(sb)->s_group_desc = n_group_desc; 886 EXT4_SB(sb)->s_gdb_count++; 887 kvfree(o_group_desc); 888 889 le16_add_cpu(&es->s_reserved_gdt_blocks, -1); 890 err = ext4_handle_dirty_super(handle, sb); 891 if (err) 892 ext4_std_error(sb, err); |
891 | |
892 return err; | 893 return err; |
893 894exit_inode: | 894errout: |
895 kvfree(n_group_desc); 896 brelse(iloc.bh); | 895 kvfree(n_group_desc); 896 brelse(iloc.bh); |
897exit_dind: | |
898 brelse(dind); | 897 brelse(dind); |
899exit_bh: | |
900 brelse(gdb_bh); 901 902 ext4_debug("leaving with error %d\n", err); 903 return err; 904} 905 906/* 907 * add_new_gdb_meta_bg is the sister of add_new_gdb. 908 */ 909static int add_new_gdb_meta_bg(struct super_block *sb, 910 handle_t *handle, ext4_group_t group) { 911 ext4_fsblk_t gdblock; 912 struct buffer_head *gdb_bh; 913 struct buffer_head **o_group_desc, **n_group_desc; 914 unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); 915 int err; 916 917 gdblock = ext4_meta_bg_first_block_no(sb, group) + 918 ext4_bg_has_super(sb, group); | 898 brelse(gdb_bh); 899 900 ext4_debug("leaving with error %d\n", err); 901 return err; 902} 903 904/* 905 * add_new_gdb_meta_bg is the sister of add_new_gdb. 906 */ 907static int add_new_gdb_meta_bg(struct super_block *sb, 908 handle_t *handle, ext4_group_t group) { 909 ext4_fsblk_t gdblock; 910 struct buffer_head *gdb_bh; 911 struct buffer_head **o_group_desc, **n_group_desc; 912 unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb); 913 int err; 914 915 gdblock = ext4_meta_bg_first_block_no(sb, group) + 916 ext4_bg_has_super(sb, group); |
919 gdb_bh = sb_bread(sb, gdblock); 920 if (!gdb_bh) 921 return -EIO; | 917 gdb_bh = ext4_sb_bread(sb, gdblock, 0); 918 if (IS_ERR(gdb_bh)) 919 return PTR_ERR(gdb_bh); |
922 n_group_desc = ext4_kvmalloc((gdb_num + 1) * 923 sizeof(struct buffer_head *), 924 GFP_NOFS); 925 if (!n_group_desc) { 926 brelse(gdb_bh); 927 err = -ENOMEM; 928 ext4_warning(sb, "not enough memory for %lu groups", 929 gdb_num + 1); --- 40 unchanged lines hidden (view full) --- 970 int res, i; 971 int err; 972 973 primary = kmalloc_array(reserved_gdb, sizeof(*primary), GFP_NOFS); 974 if (!primary) 975 return -ENOMEM; 976 977 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; | 920 n_group_desc = ext4_kvmalloc((gdb_num + 1) * 921 sizeof(struct buffer_head *), 922 GFP_NOFS); 923 if (!n_group_desc) { 924 brelse(gdb_bh); 925 err = -ENOMEM; 926 ext4_warning(sb, "not enough memory for %lu groups", 927 gdb_num + 1); --- 40 unchanged lines hidden (view full) --- 968 int res, i; 969 int err; 970 971 primary = kmalloc_array(reserved_gdb, sizeof(*primary), GFP_NOFS); 972 if (!primary) 973 return -ENOMEM; 974 975 data = EXT4_I(inode)->i_data + EXT4_DIND_BLOCK; |
978 dind = sb_bread(sb, le32_to_cpu(*data)); 979 if (!dind) { 980 err = -EIO; | 976 dind = ext4_sb_bread(sb, le32_to_cpu(*data), 0); 977 if (IS_ERR(dind)) { 978 err = PTR_ERR(dind); 979 dind = NULL; |
981 goto exit_free; 982 } 983 984 blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count; 985 data = (__le32 *)dind->b_data + (EXT4_SB(sb)->s_gdb_count % 986 EXT4_ADDR_PER_BLOCK(sb)); 987 end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb); 988 989 /* Get each reserved primary GDT block and verify it holds backups */ 990 for (res = 0; res < reserved_gdb; res++, blk++) { 991 if (le32_to_cpu(*data) != blk) { 992 ext4_warning(sb, "reserved block %llu" 993 " not at offset %ld", 994 blk, 995 (long)(data - (__le32 *)dind->b_data)); 996 err = -EINVAL; 997 goto exit_bh; 998 } | 980 goto exit_free; 981 } 982 983 blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count; 984 data = (__le32 *)dind->b_data + (EXT4_SB(sb)->s_gdb_count % 985 EXT4_ADDR_PER_BLOCK(sb)); 986 end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb); 987 988 /* Get each reserved primary GDT block and verify it holds backups */ 989 for (res = 0; res < reserved_gdb; res++, blk++) { 990 if (le32_to_cpu(*data) != blk) { 991 ext4_warning(sb, "reserved block %llu" 992 " not at offset %ld", 993 blk, 994 (long)(data - (__le32 *)dind->b_data)); 995 err = -EINVAL; 996 goto exit_bh; 997 } |
999 primary[res] = sb_bread(sb, blk); 1000 if (!primary[res]) { 1001 err = -EIO; | 998 primary[res] = ext4_sb_bread(sb, blk, 0); 999 if (IS_ERR(primary[res])) { 1000 err = PTR_ERR(primary[res]); 1001 primary[res] = NULL; |
1002 goto exit_bh; 1003 } 1004 gdbackups = verify_reserved_gdb(sb, group, primary[res]); 1005 if (gdbackups < 0) { 1006 brelse(primary[res]); 1007 err = gdbackups; 1008 goto exit_bh; 1009 } --- 616 unchanged lines hidden (view full) --- 1626 1627 if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) < 1628 le32_to_cpu(es->s_inodes_count)) { 1629 ext4_warning(sb, "inodes_count overflow"); 1630 return -EINVAL; 1631 } 1632 1633 if (reserved_gdb || gdb_off == 0) { | 1002 goto exit_bh; 1003 } 1004 gdbackups = verify_reserved_gdb(sb, group, primary[res]); 1005 if (gdbackups < 0) { 1006 brelse(primary[res]); 1007 err = gdbackups; 1008 goto exit_bh; 1009 } --- 616 unchanged lines hidden (view full) --- 1626 1627 if (le32_to_cpu(es->s_inodes_count) + EXT4_INODES_PER_GROUP(sb) < 1628 le32_to_cpu(es->s_inodes_count)) { 1629 ext4_warning(sb, "inodes_count overflow"); 1630 return -EINVAL; 1631 } 1632 1633 if (reserved_gdb || gdb_off == 0) { |
1634 if (ext4_has_feature_resize_inode(sb) || | 1634 if (!ext4_has_feature_resize_inode(sb) || |
1635 !le16_to_cpu(es->s_reserved_gdt_blocks)) { 1636 ext4_warning(sb, 1637 "No reserved GDT blocks, can't resize"); 1638 return -EPERM; 1639 } | 1635 !le16_to_cpu(es->s_reserved_gdt_blocks)) { 1636 ext4_warning(sb, 1637 "No reserved GDT blocks, can't resize"); 1638 return -EPERM; 1639 } |
1640 inode = ext4_iget(sb, EXT4_RESIZE_INO); | 1640 inode = ext4_iget(sb, EXT4_RESIZE_INO, EXT4_IGET_SPECIAL); |
1641 if (IS_ERR(inode)) { 1642 ext4_warning(sb, "Error opening resize inode"); 1643 return PTR_ERR(inode); 1644 } 1645 } 1646 1647 1648 err = verify_group_input(sb, input); --- 311 unchanged lines hidden (view full) --- 1960 le16_to_cpu(es->s_reserved_gdt_blocks); 1961 n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb); 1962 n_blocks_count = (ext4_fsblk_t)n_group * 1963 EXT4_BLOCKS_PER_GROUP(sb); 1964 n_group--; /* set to last group number */ 1965 } 1966 1967 if (!resize_inode) | 1641 if (IS_ERR(inode)) { 1642 ext4_warning(sb, "Error opening resize inode"); 1643 return PTR_ERR(inode); 1644 } 1645 } 1646 1647 1648 err = verify_group_input(sb, input); --- 311 unchanged lines hidden (view full) --- 1960 le16_to_cpu(es->s_reserved_gdt_blocks); 1961 n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb); 1962 n_blocks_count = (ext4_fsblk_t)n_group * 1963 EXT4_BLOCKS_PER_GROUP(sb); 1964 n_group--; /* set to last group number */ 1965 } 1966 1967 if (!resize_inode) |
1968 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO); | 1968 resize_inode = ext4_iget(sb, EXT4_RESIZE_INO, 1969 EXT4_IGET_SPECIAL); |
1969 if (IS_ERR(resize_inode)) { 1970 ext4_warning(sb, "Error opening resize inode"); 1971 return PTR_ERR(resize_inode); 1972 } 1973 } 1974 1975 if ((!resize_inode && !meta_bg) || n_blocks_count == o_blocks_count) { 1976 err = ext4_convert_meta_bg(sb, resize_inode); --- 100 unchanged lines hidden --- | 1970 if (IS_ERR(resize_inode)) { 1971 ext4_warning(sb, "Error opening resize inode"); 1972 return PTR_ERR(resize_inode); 1973 } 1974 } 1975 1976 if ((!resize_inode && !meta_bg) || n_blocks_count == o_blocks_count) { 1977 err = ext4_convert_meta_bg(sb, resize_inode); --- 100 unchanged lines hidden --- |