summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2009-06-17 20:55:39 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-06-18 07:47:54 -0400
commit8a6ede8b7a8d5be0d49d6bfa7616537b61dfdc1b (patch)
treefc506898f6e97571c23fbdf836fbe9c39db6862a
parent827c1887118eb68a64f8455d0b7cbbbed65e714a (diff)
downloade2fsprogs-8a6ede8b7a8d5be0d49d6bfa7616537b61dfdc1b.tar.gz
resize2fs: update sb journal backup if journal was moved
This was reported in Fedora, since the livecd creator does a lot of resizing. If we've moved the journal blocks during resize (more likely now, due to the journal being in the middle) the backup blocks in the superblock don't get updated, and a subsequent e2fsck will find issues: e2fsck 1.41.6 (30-May-2009) Backing up journal inode block information. Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information /mnt/test/img: ***** FILE SYSTEM WAS MODIFIED ***** /mnt/test/img: 11/16000 files (0.0% non-contiguous), 17789/38400 blocks This can be shown in a simple test: # dd if=/dev/zero of=img bs=1 count=0 seek=3000M # mke2fs -t ext4 -F img # resize2fs img 150M # e2fsck -f img (thanks to the Fedora reporter Mads Kiilerich for the testcase! https://bugzilla.redhat.com/show_bug.cgi?id=506105#c2) So, update the backup journal in the superblock before resize2fs exits. Addresses-RedHat-Bugzilla: #505339 Signed-off-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
-rw-r--r--resize/resize2fs.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/resize/resize2fs.c b/resize/resize2fs.c
index e87a2343..d907c9c2 100644
--- a/resize/resize2fs.c
+++ b/resize/resize2fs.c
@@ -49,6 +49,7 @@ static errcode_t inode_ref_fix(ext2_resize_t rfs);
static errcode_t move_itables(ext2_resize_t rfs);
static errcode_t fix_resize_inode(ext2_filsys fs);
static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs);
+static errcode_t fix_sb_journal_backup(ext2_filsys fs);
/*
* Some helper CPP macros
@@ -148,6 +149,10 @@ errcode_t resize_fs(ext2_filsys fs, blk_t *new_size, int flags,
if (retval)
goto errout;
+ retval = fix_sb_journal_backup(rfs->new_fs);
+ if (retval)
+ goto errout;
+
rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
retval = ext2fs_close(rfs->new_fs);
if (retval)
@@ -1861,6 +1866,28 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs)
}
/*
+ * Journal may have been relocated; update the backup journal blocks
+ * in the superblock.
+ */
+static errcode_t fix_sb_journal_backup(ext2_filsys fs)
+{
+ errcode_t retval;
+ struct ext2_inode inode;
+
+ if (!(fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
+ return 0;
+
+ retval = ext2fs_read_inode(fs, fs->super->s_journal_inum, &inode);
+ if (retval)
+ return retval;
+ memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
+ fs->super->s_jnl_blocks[16] = inode.i_size;
+ fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
+ ext2fs_mark_super_dirty(fs);
+ return 0;
+}
+
+/*
* calcluate the minimum number of blocks the given fs can be resized to
*/
blk_t calculate_minimum_resize_size(ext2_filsys fs)