resize.c (989a4222c13a3e148772730d362fceb0727852f5) resize.c (e647e29196b7f802f8242c39ecb7cc937f5ef217)
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 }
1640 inode = ext4_iget(sb, EXT4_RESIZE_INO);
1641 if (IS_ERR(inode)) {
1642 ext4_warning(sb, "Error opening resize inode");

--- 434 unchanged lines hidden ---
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);
1641 if (IS_ERR(inode)) {
1642 ext4_warning(sb, "Error opening resize inode");

--- 434 unchanged lines hidden ---