Bug 491385

Summary: after resize2fs, e2fsck reports wrong block count for resize inode
Product: Red Hat Enterprise Linux 5 Reporter: Valerie Aurora Henson <vaurora>
Component: e2fsprogsAssignee: Lukáš Czerner <lczerner>
Status: CLOSED ERRATA QA Contact: BaseOS QE <qe-baseos-auto>
Severity: low Docs Contact:
Priority: low    
Version: 5.2CC: bnater, esandeen, rwheeler, sct
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: e2fsprogs-1.39-29.el5 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-07-21 09:07:53 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Valerie Aurora Henson 2009-03-20 17:59:25 UTC
Description of problem:

After an offline resize of a 8TB fs -> 16TB fs (which is not officially supported), I ran fsck and got the following error:

[root@bear-05 ~]# e2fsck -fn /mnt/test/16TB_minus_4KB_exactly 
e2fsck 1.39 (29-May-2006)
Resize_inode not enabled, but the resize inode is non-zero.  Clear? no

Pass 1: Checking inodes, blocks, and sizes
Inode 7, i_blocks is 94216, should be 2106320.  Fix? no

Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

/mnt/test/16TB_minus_4KB_exactly: ********** WARNING: Filesystem still has errors **********

/mnt/test/16TB_minus_4KB_exactly: 72735/20971520 files (0.0% non-contiguous), 1436821/4294967295 blocks

Another one:

[root@bear-05 ~]# e2fsck -fp /mnt/test/16TB_minus_4KB_exactly 
/mnt/test/16TB_minus_4KB_exactly: Resize_inode not enabled, but the resize inode is non-zero.  

/mnt/test/16TB_minus_4KB_exactly: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
	(i.e., without -a or -p options)

Looks like the resize inode is not being properly cleared?

Version-Release number of selected component (if applicable):

e2fsprogs-1.39-15.el5

How reproducible:

Resize an 8TB file system to 16TB and fsck.  Don't know how related the file system size is.

Steps to Reproduce:

Create a 16TB - 4KB size loopback file:

(Get yourself an XFS partition mounted on /mnt/test)

# dd if=/dev/zero of=/mnt/test/16TB_minus_4KB_exactly bs=4096 seek=4294967294 count=1

Create an 8TB file system (fewer inodes makes it go faster):

# mkfs.ext3 -N 100000 /mnt/test/16TB_minus_4KB_exactly 2147483647

Resize it to the full 16TB:

# resize2fs -pf /mnt/test/16TB_minus_4KB_exactly

Run fsck:

# e2fsck -fp /mnt/test/16TB_minus_4KB_exactly

I've done this twice and gotten errors both times.

Actual results:

Errors from e2fsck.

Expected results:

No errors reported from e2fsck.

Additional info:

Comment 1 Valerie Aurora Henson 2009-03-20 18:30:05 UTC
This might be the fix:

commit 8ade268cf2fde8629b51bfd1c044a83db88234cd
Author: Theodore Ts'o <tytso>
Date:   Thu Jul 10 14:18:41 2008 -0400

    resize2fs: Clean up the resize inode properly if necessary
    
    If the filesystem is grown to the point where the resize_inode is no
    longer needed, clean it up properly so e2fsck doesn't have to.
    
    Signed-off-by: "Theodore Ts'o" <tytso>

diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index 05650a8..84db121 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -310,9 +310,6 @@ retry:
 		if (new > (int) fs->blocksize/4)
 			new = fs->blocksize/4;
 		fs->super->s_reserved_gdt_blocks = new;
-		if (new == 0)
-			fs->super->s_feature_compat &= 
-				~EXT2_FEATURE_COMPAT_RESIZE_INODE;
 	}
 
 	/*
@@ -1536,6 +1533,7 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
 	struct ext2_inode	inode;
 	errcode_t		retval;
 	char *			block_buf;
+	blk_t			blk;
 
 	if (!(fs->super->s_feature_compat & 
 	      EXT2_FEATURE_COMPAT_RESIZE_INODE))
@@ -1547,6 +1545,20 @@ static errcode_t fix_resize_inode(ext2_filsys fs)
 	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
 	if (retval) goto errout;
 
+	if (fs->super->s_reserved_gdt_blocks == 0) {
+		fs->super->s_feature_compat &= 
+			~EXT2_FEATURE_COMPAT_RESIZE_INODE;
+		ext2fs_mark_super_dirty(fs);
+
+		if ((blk = inode.i_block[EXT2_DIND_BLOCK]) != 0)
+			ext2fs_block_alloc_stats(fs, blk, -1);
+
+		memset(&inode, 0, sizeof(inode));
+
+		retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
+		goto errout;
+	}
+
 	ext2fs_iblk_set(fs, &inode, 1);
 
 	retval = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);

Comment 2 Valerie Aurora Henson 2009-03-20 18:50:43 UTC
Retested with e4fsprogs 1.41.4-2.el5 and it's fixed:

[root@bear-05 ~]# resize4fs -fp /mnt/test/16TB_minus_4KB_exactly 
resize4fs 1.41.4 (27-Jan-2009)
Resizing the filesystem on /mnt/test/16TB_minus_4KB_exactly to 4294967295 (4k) blocks.
Begin pass 1 (max = 65536)
Extending the inode table     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The filesystem on /mnt/test/16TB_minus_4KB_exactly is now 4294967295 blocks long.

[root@bear-05 ~]# e4fsck -fn /mnt/test/16TB_minus_4KB_exactly 
e4fsck 1.41.4 (27-Jan-2009)
Pass 1: Checking inodes, blocks, and sizes

[... not finished but would have barfed immediately on this bug]

Comment 10 Eric Sandeen 2011-01-14 22:20:24 UTC
If the commit in comment #1 goes in, need to look at this one too:

commit d16db7d9ded85f4a7f8d91562246cc2f59bf204d
Author: Eric Sandeen <sandeen>
Date:   Tue Dec 21 15:32:05 2010 -0600

    resize2fs: do not clear resize inode for 0 resvd blocks
    
    I ran into odd behavior where mkfs.ext4 of a 16T filesystem would
    create a resize inode with 0 reserved blocks, and mark the resize_inode
    feature.
    
    A subsequent slight downward resize of the filesystem would remove
    the resize inode, making any further offline resizing impossible.
    
    This is especially odd in light of the fact that a large downward
    resize (say, to 8T) will actually add blocks to the resize inode -
    so a small resize removes it, a large resize expands it ...
    
    commit 8ade268cf2fde8629b51bfd1c044a83db88234cd had added this:
    
      If the filesystem is grown to the point where the resize_inode is no
      longer needed, clean it up properly so e2fsck doesn't have to.
    
    but, it seems e2fsck does not care about this situation, either.
    
    So, simply leave the resize_inode intact in this case, and everything
    seems to be happy.
    
    Note, this is for the 1.41.xx branch.
    
    Signed-off-by: Eric Sandeen <sandeen>
    Signed-off-by: Theodore Ts'o <tytso>

which... takes most of it back out ;)  Hope I didn't regress -this- case again.

Comment 11 Lukáš Czerner 2011-02-04 16:14:34 UTC
It has been fixed with upstream commits 

8ade268cf2fde8629b51bfd1c044a83db88234cd
d16db7d9ded85f4a7f8d91562246cc2f59bf204d

committed and built as e2fsprogs-1.39-29.el5

Comment 14 errata-xmlrpc 2011-07-21 09:07:53 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-1080.html

Comment 15 errata-xmlrpc 2011-07-21 12:35:55 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-1080.html