Attached is the reject file. It looks like hunk 10 removes 27 lines from super.c around line 594, but these were not getting removed in 2.4.18. Also attached is what I think the 2.4.18 patch should be. -Ian On Wed, 2002-06-19 at 14:47, Andreas Dilger wrote: > On Jun 19, 2002 14:10 -0700, Ian Prowell wrote: > > Andreas, > > Thanks for the prompt reply. To be more specific I am using RedHat's > > 2.4.18-4 kernel. When I apply the patch I get the following output. > > > > [root@metaverse src]# cat /root/online-ext2-2.4.17.diff | patch -p0 > > patching file linux/fs/ext2/super.c > > Hunk #9 succeeded at 730 (offset -1 lines). > > Hunk #10 FAILED at 883. > > Hunk #11 succeeded at 893 (offset 1 line). > > Hunk #12 succeeded at 917 (offset -1 lines). > > Hunk #13 succeeded at 979 (offset 1 line). > > Hunk #14 succeeded at 987 (offset -1 lines). > > Hunk #15 succeeded at 1024 (offset 1 line). > > 1 out of 15 hunks FAILED -- saving rejects to file > > linux/fs/ext2/super.c.rej > > > > It looks like most of the patch is working, but I am not a kernel > > developer and really have no idea what failed on hunk 10. If it would > > be useful I can send the rejects file. > > It won't really be useful for you to send the failed hunk, because I > have no idea why it is failing. I would suggest firing up a text editor > with fs/ext2/super.c and fs/ext2/super.c.rej and just manually cut-paste > the failed parts in. > > Unified diffs are rather simple to understand. > > Lines like "@@ -123,6 +234,8 @@" are telling you that the original file > had this hunk at line 123 and the modified file had the replacement > hunk at line 234. > > Lines like "- blah" are removing that line from the > original file and replacing it with "+ blarg" in the new file. > > Hopefully hunk #10 isn't too large... Sadly, the larger the hunk, the > more likely it is to not apply cleanly... > > Cheers, Andreas > -- > Andreas Dilger > http://www-mddsp.enel.ucalgary.ca/People/adilger/ > http://sourceforge.net/projects/ext2resize/
Attachment:
super.c.rej
Description: application/reject
diff -ru linux-2.4.18.orig/CREDITS linux/CREDITS --- linux-2.4.18.orig/CREDITS Mon Feb 25 11:37:50 2002 +++ linux/CREDITS Wed Jun 19 14:56:34 2002 @@ -694,6 +694,15 @@ S: Warrendale, Pennsylvania 15086 S: USA +N: Andreas Dilger +E: adilger@turbolinux.com +W: http://www-mddsp.enel.ucalgary.ca/People/adilger/ +D: Ext2 filesystem online resize capability +D: Ext3/LVM hacking +S: 630 Schooner Cove N.W. +S: Calgary, AB +S: Canada T3L 1Z1 + N: Alex deVries E: adevries@thepuffingroup.com D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux. diff -ru linux-2.4.18.orig/Documentation/Configure.help linux/Documentation/Configure.help --- linux-2.4.18.orig/Documentation/Configure.help Mon Feb 25 11:37:51 2002 +++ linux/Documentation/Configure.help Wed Jun 19 14:56:34 2002 @@ -14016,6 +14016,20 @@ be compiled as a module, and so this could be dangerous. Most everyone wants to say Y here. +Online resize for ext2 filesystems +CONFIG_EXT2_RESIZE + This option gives you the ability to increase the size of an ext2 + filesystem while it is mounted (in use). In order to do this, you + must also be able to resize the underlying disk partition, probably + via a Logical Volume Manager (LVM), metadevice (MD), or hardware + RAID device - none of that capability is included in this feature. + If you don't know what any of these things are, or you haven't + configured your kernel for them, you should probably say N here. If + you choose Y, then your kernel will be about 3k larger, and you need + to get some more software (http://ext2resize.sourceforge.net/) in + order to actually resize your filesystem, otherwise this feature + will just sit unused inside the kernel. + Ext3 journalling file system support (EXPERIMENTAL) CONFIG_EXT3_FS This is the journalling version of the Second extended file system diff -ru linux-2.4.18.orig/fs/Config.in linux/fs/Config.in --- linux-2.4.18.orig/fs/Config.in Mon Feb 25 11:38:07 2002 +++ linux/fs/Config.in Wed Jun 19 14:56:34 2002 @@ -77,6 +77,7 @@ tristate 'ROM file system support' CONFIG_ROMFS_FS tristate 'Second extended fs support' CONFIG_EXT2_FS +dep_mbool ' Online ext2 resize support (DANGEROUS)' CONFIG_EXT2_RESIZE $CONFIG_EXT2_FS $CONFIG_EXPERIMENTAL tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS diff -ru linux-2.4.18.orig/fs/ext2/balloc.c linux/fs/ext2/balloc.c --- linux-2.4.18.orig/fs/ext2/balloc.c Mon Feb 25 11:38:08 2002 +++ linux/fs/ext2/balloc.c Wed Jun 19 14:56:34 2002 @@ -616,13 +616,13 @@ unsigned long ext2_count_free_blocks (struct super_block * sb) { -#ifdef EXT2FS_DEBUG struct ext2_super_block * es; unsigned long desc_count, bitmap_count, x; int bitmap_nr; struct ext2_group_desc * gdp; int i; - + + if (test_opt(sb, DEBUG) && test_opt(sb, CHECK)) { lock_super (sb); es = sb->u.ext2_sb.s_es; desc_count = 0; @@ -643,13 +643,12 @@ i, le16_to_cpu(gdp->bg_free_blocks_count), x); bitmap_count += x; } - printk("ext2_count_free_blocks: stored = %lu, computed = %lu, %lu\n", + printk(__FUNCTION__": stored = %u, computed gdt = %lu, bitmap = %lu\n", le32_to_cpu(es->s_free_blocks_count), desc_count, bitmap_count); unlock_super (sb); return bitmap_count; -#else + } else return le32_to_cpu(sb->u.ext2_sb.s_es->s_free_blocks_count); -#endif } static inline int block_in_use (unsigned long block, diff -ru linux-2.4.18.orig/fs/ext2/super.c linux/fs/ext2/super.c --- linux-2.4.18.orig/fs/ext2/super.c Mon Feb 25 11:38:08 2002 +++ linux/fs/ext2/super.c Wed Jun 19 15:16:33 2002 @@ -14,6 +14,7 @@ * * Big-endian to little-endian byte-swapping/bitmaps by * David S. Miller (davem@caip.rutgers.edu), 1995 + * Online resize by Andreas Dilger (adilger@turbolinux.com), July 1999 */ #include <linux/config.h> @@ -163,7 +164,9 @@ */ static int parse_options (char * options, unsigned long * sb_block, unsigned short *resuid, unsigned short * resgid, - unsigned long * mount_options) + unsigned long *mount_options, + unsigned long *n_blocks_count, + unsigned long *resgdt) { char * this_char; char * value; @@ -229,6 +232,31 @@ else if (!strcmp (this_char, "nogrpid") || !strcmp (this_char, "sysvgroups")) clear_opt (*mount_options, GRPID); +#ifdef CONFIG_EXT2_RESIZE + else if (!strcmp(this_char, "resize")) { + printk("EXT2-fs: parse_options: resize=%s\n", value); + if (!n_blocks_count) { + printk("EXT2-fs: resize option only available " + "for remount\n"); + return 0; + } + if (!value || !*value) { + printk("EXT2-fs: resize requires number of " + "blocks\n"); + return 0; + } + *n_blocks_count = simple_strtoul(value, &value, 0); + if (*value == ':') { + value++; + *resgdt = simple_strtoul(value, &value, 0); + } + if (*value) { + printk("EXT2-fs: invalid resize option: %s\n", + value); + return 0; + } + } +#endif /* CONFIG_EXT2_RESIZE */ else if (!strcmp (this_char, "resgid")) { if (!value || !*value) { printk ("EXT2-fs: the resgid option requires " @@ -314,10 +342,10 @@ es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1); ext2_write_super(sb); if (test_opt (sb, DEBUG)) - printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " + printk ("[EXT II FS %s, %s, bs=%lu, bc=%u, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, - sb->u.ext2_sb.s_frag_size, + le32_to_cpu(es->s_blocks_count), sb->u.ext2_sb.s_groups_count, EXT2_BLOCKS_PER_GROUP(sb), EXT2_INODES_PER_GROUP(sb), @@ -331,7 +359,9 @@ return res; } -static int ext2_check_descriptors (struct super_block * sb) +static int ext2_check_descriptors(struct super_block *sb, + struct buffer_head **group_desc, + unsigned long groups_count) { int i; int desc_block = 0; @@ -340,10 +370,10 @@ ext2_debug ("Checking group descriptors"); - for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) + for (i = 0; i < groups_count; i++) { if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext2_group_desc *) sb->u.ext2_sb.s_group_desc[desc_block++]->b_data; + gdp = (struct ext2_group_desc *)group_desc[desc_block++]->b_data; if (le32_to_cpu(gdp->bg_block_bitmap) < block || le32_to_cpu(gdp->bg_block_bitmap) >= block + EXT2_BLOCKS_PER_GROUP(sb)) { @@ -378,6 +408,267 @@ return 1; } +static int ext2_read_descriptors(struct super_block *sb, + unsigned long blocks_count) +{ + struct buffer_head **group_desc; + struct buffer_head **o_group_desc; + unsigned long groups_count; + unsigned long o_groups_count; + unsigned long gdb_count; + unsigned long o_gdb_count; + + o_group_desc = EXT2_SB(sb)->s_group_desc; + o_groups_count = EXT2_SB(sb)->s_groups_count; + o_gdb_count = EXT2_SB(sb)->s_gdb_count; + + groups_count = (blocks_count - + le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) + + EXT2_BLOCKS_PER_GROUP(sb) - 1) / + EXT2_BLOCKS_PER_GROUP(sb); + gdb_count = (groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / + EXT2_DESC_PER_BLOCK(sb); + if (test_opt(sb, DEBUG)) { + printk("EXT2-fs: ext2_read_descriptors: o_groups_count=%lu, " + "groups_count=%lu, blocks_count=%lu\n", o_groups_count, + groups_count, blocks_count); + printk("EXT2-fs: ext2_read_descriptors: o_gdb_count=%lu, " + "gdb_count=%lu\n", o_gdb_count, gdb_count); + } + + if (o_gdb_count != gdb_count) { + unsigned long logic_gd_block = EXT2_SB(sb)->s_sbh->b_blocknr +1; + unsigned long i; + + group_desc = (struct buffer_head **)kmalloc(gdb_count * + sizeof(struct buffer_head *), GFP_KERNEL); + if (group_desc == NULL) { + ext2_warning(sb, __FUNCTION__, + "not enough memory for %ld group blocks", + gdb_count); + return -ENOMEM; + } + for (i = o_gdb_count; i < gdb_count; i++) { /* Add blocks */ + group_desc[i] = bread(sb->s_dev, logic_gd_block + i, + sb->s_blocksize); + if (!group_desc[i]) { + unsigned long j; + + for (j = o_gdb_count; j < i; j++) + brelse(group_desc[j]); + kfree(group_desc); + ext2_warning(sb, __FUNCTION__, + "can't read group block %ld", + i); + return -EIO; + } + } + + /* + * Copy over pointers to old descriptor blocks already loaded. + */ + memcpy(group_desc, o_group_desc, + (o_gdb_count < gdb_count ? o_gdb_count : gdb_count) * + sizeof(struct buffer_head *)); + } else + group_desc = o_group_desc; /* this will never be NULL */ + + if (!ext2_check_descriptors(sb, group_desc, groups_count)) { + unsigned long j; + + for (j = o_gdb_count; j < gdb_count; j++) + brelse(group_desc[j]); + if (group_desc != o_group_desc) + kfree(group_desc); + return -EINVAL; + } + + EXT2_SB(sb)->s_group_desc = group_desc; + EXT2_SB(sb)->s_groups_count = groups_count; + EXT2_SB(sb)->s_gdb_count = gdb_count; + + if (o_group_desc && o_group_desc != EXT2_SB(sb)->s_group_desc) + kfree(o_group_desc); + + return 0; +} /* ext2_read_descriptors */ + +#ifdef CONFIG_EXT2_RESIZE +/* Make the disk blocks in a new group available to the filesystem */ +static int ext2_update_group(struct super_block *sb, unsigned int block_group, + unsigned int reserved, unsigned int resgdt) +{ + struct ext2_group_desc *gdp; + struct ext2_super_block *es; + int blocks; + int m_blocks; + int inodes; + unsigned long gdb; + int shrink = reserved > 100 ? 1 : 0; + + es = EXT2_SB(sb)->s_es; + gdp = ext2_get_group_desc(sb, block_group, NULL); + gdb = ext2_bg_num_gdb(sb, block_group); + + inodes = le32_to_cpu(gdp->bg_free_inodes_count); + blocks = le32_to_cpu(gdp->bg_free_blocks_count); + m_blocks = EXT2_SB(sb)->s_itb_per_group + 2 + + ext2_bg_has_super(sb, block_group) + + (gdb ? gdb + resgdt : 0) + blocks; + + if (block_group < EXT2_SB(sb)->s_groups_count - 1 && + m_blocks != EXT2_BLOCKS_PER_GROUP(sb)) { + ext2_warning(sb, __FUNCTION__, + "bad group size for %s group %d (%d blocks) " + "(iblk = %ld, GDT blk %ld, resgdt %d, blocks %d\n", + ext2_bg_has_super(sb, block_group) ? "normal" : + "no-backup", block_group, m_blocks, + EXT2_SB(sb)->s_itb_per_group, gdb, resgdt, blocks); + return -EINVAL; + } + + es->s_free_inodes_count = + cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + inodes); + es->s_inodes_count = cpu_to_le32(le32_to_cpu(es->s_inodes_count) + + inodes); + + es->s_free_blocks_count = + cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) + blocks); + es->s_blocks_count = cpu_to_le32(le32_to_cpu(es->s_blocks_count) + + m_blocks); + es->s_r_blocks_count = cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) + + m_blocks * reserved / 100); + + mark_buffer_dirty(EXT2_SB(sb)->s_sbh); + sb->s_dirt = 1; + + if (test_opt(sb, DEBUG)) { + printk("EXT2-fs: ext2_update_group: %s %s group %u: " + "%u inodes, %u blocks (%u free), %d (%d%%) reserved\n", + shrink ? "removing" : "adding", + ext2_bg_has_super(sb, block_group) ? "normal" : + "no-super", block_group, inodes, m_blocks, blocks, + m_blocks * reserved / 100, reserved); + printk("EXT2-fs: ext2_update_group: %u inodes (%u free), " + "%u blocks (%u free)\n", + le32_to_cpu(es->s_inodes_count), + le32_to_cpu(es->s_free_inodes_count), + le32_to_cpu(es->s_blocks_count), + le32_to_cpu(es->s_free_blocks_count)); + } + + return 0; +} /* ext2_update_group */ + +/* Resize the filesystem to the new number of blocks specified. If required, + * the new group descriptors should have already been configured for us (we + * only check that they are valid). + */ +static int ext2_resize_fs(struct super_block *sb, + struct ext2_super_block *es, + unsigned long n_blocks_count, unsigned long resgdt) +{ + unsigned long o_blocks_count; + unsigned long o_groups_count; + unsigned long last, add; + unsigned long reserved; + struct buffer_head *bh; + unsigned long i; + int err = 0; + + o_blocks_count = le32_to_cpu(es->s_blocks_count); + o_groups_count = EXT2_SB(sb)->s_groups_count; + + if (test_opt(sb, DEBUG)) + printk("EXT2-fs: ext2_resize_fs: from %lu to %lu blocks\n", + o_blocks_count, n_blocks_count); + + if (n_blocks_count == 0 || n_blocks_count == o_blocks_count) + return 0; + + if (n_blocks_count < o_blocks_count) { + ext2_warning(sb, __FUNCTION__, "error: can't shrink FS!"); + return -EBUSY; + } + + /* See if the device is actually as big as what was requested */ + bh = bread(sb->s_dev, n_blocks_count - 1, EXT2_BLOCK_SIZE(sb)); + if (!bh) { + ext2_warning(sb, __FUNCTION__, + "unable to read last block, resize aborted"); + return -ENOSPC; + } + brelse(bh); + + /* For reserved percentage calculation, we avoid 32-bit overflow. */ + reserved = o_blocks_count > 10000000 ? + (le32_to_cpu(es->s_r_blocks_count) + o_blocks_count / 200) / + (o_blocks_count / 100) : + (le32_to_cpu(es->s_r_blocks_count) * 100 + o_blocks_count / 2) / + o_blocks_count; + + if ((err = ext2_read_descriptors(sb, n_blocks_count))) { + ext2_warning(sb, __FUNCTION__, + "group descriptor error %d, resize aborted", err); + return err; + } + + /* Handle the remaining blocks in the last partial group. */ + last = (o_blocks_count - le32_to_cpu(es->s_first_data_block)) % + EXT2_BLOCKS_PER_GROUP(sb); + if (last != 0) { /* The last group isn't full yet */ + struct inode inode; + add = EXT2_BLOCKS_PER_GROUP(sb) - last; + if (add + o_blocks_count > n_blocks_count) + add = n_blocks_count - o_blocks_count; + es->s_blocks_count = + cpu_to_le32(le32_to_cpu(es->s_blocks_count) + add); + es->s_r_blocks_count = + cpu_to_le32(le32_to_cpu(es->s_r_blocks_count) + + add * reserved / 100); + mark_buffer_dirty(EXT2_SB(sb)->s_sbh); + sb->s_dirt = 1; + unlock_super(sb); + /* + * Fake out an inode enough to "free" the new blocks in this + * group. Turn off quotas for this inode so it doesn't get + * confused by freeing blocks that don't really exist yet. + */ + inode.i_sb = sb; + inode.i_state = I_DIRTY; + INIT_LIST_HEAD(&inode.i_hash); + for (i = 0; i < MAXQUOTAS; i++) + inode.i_dquot[i] = NODQUOT; + ext2_free_blocks(&inode, o_blocks_count, add); + if (test_opt(sb, DEBUG)) + printk("EXT2-fs: ext2_resize_fs: added %lu new blocks " + "to %lu blocks in last group\n", + add, o_blocks_count); + lock_super(sb); + } + + /* + * Update superblock with remaining new group block/inode counts + */ + for (i = o_groups_count; i < EXT2_SB(sb)->s_groups_count && + !(err = ext2_update_group(sb, i, reserved, resgdt)); i++) + /* empty loop */; + + if (err || le32_to_cpu(es->s_blocks_count) != n_blocks_count) { + ext2_warning(sb, __FUNCTION__, + "specified size does not match new block count " + "(%lu != %u) (err %d)", n_blocks_count, + le32_to_cpu(es->s_blocks_count), err); + EXT2_SB(sb)->s_mount_state &= ~EXT2_VALID_FS; + } else + EXT2_SB(sb)->s_mount_state |= EXT2_VALID_FS; + + return err; +} /* ext2_resize_fs */ +#else /* !CONFIG_EXT2_RESIZE */ +#define ext2_resize_fs(sb, es, n_blocks_count, resgdt) 0 +#endif /* CONFIG_EXT2_RESIZE */ + #define log2(n) ffz(~(n)) /* @@ -409,8 +700,7 @@ unsigned long offset = 0; kdev_t dev = sb->s_dev; int blocksize = BLOCK_SIZE; - int db_count; - int i, j; + int i; /* * See what the current blocksize for the device is, and @@ -425,7 +715,7 @@ sb->u.ext2_sb.s_mount_opt = 0; if (!parse_options ((char *) data, &sb_block, &resuid, &resgid, - &sb->u.ext2_sb.s_mount_opt)) { + &sb->u.ext2_sb.s_mount_opt, NULL, NULL)) { return NULL; } @@ -596,32 +886,6 @@ goto failed_mount; } - sb->u.ext2_sb.s_groups_count = (le32_to_cpu(es->s_blocks_count) - - le32_to_cpu(es->s_first_data_block) + - EXT2_BLOCKS_PER_GROUP(sb) - 1) / - EXT2_BLOCKS_PER_GROUP(sb); - db_count = (sb->u.ext2_sb.s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / - EXT2_DESC_PER_BLOCK(sb); - sb->u.ext2_sb.s_group_desc = kmalloc (db_count * sizeof (struct buffer_head *), GFP_KERNEL); - if (sb->u.ext2_sb.s_group_desc == NULL) { - printk ("EXT2-fs: not enough memory\n"); - goto failed_mount; - } - for (i = 0; i < db_count; i++) { - sb->u.ext2_sb.s_group_desc[i] = sb_bread(sb, logic_sb_block + i + 1); - if (!sb->u.ext2_sb.s_group_desc[i]) { - for (j = 0; j < i; j++) - brelse (sb->u.ext2_sb.s_group_desc[j]); - kfree(sb->u.ext2_sb.s_group_desc); - printk ("EXT2-fs: unable to read group descriptors\n"); - goto failed_mount; - } - } - if (!ext2_check_descriptors (sb)) { - printk ("EXT2-fs: group descriptors corrupted!\n"); - db_count = i; - goto failed_mount2; - } for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { sb->u.ext2_sb.s_inode_bitmap_number[i] = 0; sb->u.ext2_sb.s_inode_bitmap[i] = NULL; @@ -630,11 +894,18 @@ } sb->u.ext2_sb.s_loaded_inode_bitmaps = 0; sb->u.ext2_sb.s_loaded_block_bitmaps = 0; - sb->u.ext2_sb.s_gdb_count = db_count; /* * set up enough so that it can read an inode */ sb->s_op = &ext2_sops; + sb->u.ext2_sb.s_group_desc = NULL; + sb->u.ext2_sb.s_groups_count = 0; + sb->u.ext2_sb.s_gdb_count = 0; + if ((i = ext2_read_descriptors(sb, le32_to_cpu(es->s_blocks_count)))) { + ext2_error(sb, __FUNCTION__, + "group descriptor error %d, unable to mount", i); + goto failed_mount; + } sb->s_root = d_alloc_root(iget(sb, EXT2_ROOT_INO)); if (!sb->s_root || !S_ISDIR(sb->s_root->d_inode->i_mode) || !sb->s_root->d_inode->i_blocks || !sb->s_root->d_inode->i_size) { @@ -649,7 +920,7 @@ ext2_setup_super (sb, es, sb->s_flags & MS_RDONLY); return sb; failed_mount2: - for (i = 0; i < db_count; i++) + for (i = 0; i < sb->u.ext2_sb.s_gdb_count; i++) brelse(sb->u.ext2_sb.s_group_desc[i]); kfree(sb->u.ext2_sb.s_group_desc); failed_mount: @@ -709,6 +980,8 @@ struct ext2_super_block * es; unsigned short resuid = sb->u.ext2_sb.s_resuid; unsigned short resgid = sb->u.ext2_sb.s_resgid; + unsigned long n_blocks_count = 0; + unsigned long resgdt = 0; unsigned long new_mount_opt; unsigned long tmp; @@ -717,14 +990,16 @@ */ new_mount_opt = sb->u.ext2_sb.s_mount_opt; if (!parse_options (data, &tmp, &resuid, &resgid, - &new_mount_opt)) + &new_mount_opt, &n_blocks_count, &resgdt)) return -EINVAL; sb->u.ext2_sb.s_mount_opt = new_mount_opt; sb->u.ext2_sb.s_resuid = resuid; sb->u.ext2_sb.s_resgid = resgid; es = sb->u.ext2_sb.s_es; - if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) + if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY) && + (n_blocks_count == 0 || + n_blocks_count == le32_to_cpu(es->s_blocks_count))) return 0; if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || @@ -751,6 +1026,8 @@ * by e2fsck since we originally mounted the partition.) */ sb->u.ext2_sb.s_mount_state = le16_to_cpu(es->s_state); + if ((ret = ext2_resize_fs(sb, es, n_blocks_count, resgdt))) + return ret; if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; } diff -ru linux-2.4.18.orig/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h --- linux-2.4.18.orig/include/linux/ext2_fs.h Thu Nov 22 11:46:52 2001 +++ linux/include/linux/ext2_fs.h Wed Jun 19 14:56:34 2002 @@ -26,6 +26,7 @@ * Define EXT2FS_DEBUG to produce debug messages */ #undef EXT2FS_DEBUG +#define CONFIG_EXT2_CHECK /* * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files @@ -61,6 +62,7 @@ #define EXT2_ACL_DATA_INO 4 /* ACL inode */ #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ +#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */ /* First non-reserved inode for old ext2 filesystems */ #define EXT2_GOOD_OLD_FIRST_INO 11