Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > 087c07ba1119dc259cb65abc62ef69e9 > files > 20

e2fsprogs-1.39-20.el5.src.rpm

From: Kalpak Shah <kalpak@clusterfs.com>
Date: Thu, 21 Jun 2007 15:59:06 +0000 (-0400)
Subject: Write the updated journal inode if s_jnl_blocks was successfully used
X-Git-Tag: E2FSPROGS-1_40~15
X-Git-Url: http://git.kernel.org/?p=fs%2Fext2%2Fe2fsprogs.git;a=commitdiff_plain;h=ded28ac2ab67300f39783184a8f8930b548fc5f0

Write the updated journal inode if s_jnl_blocks was successfully used

If the journal inode was corrected from s_jnl_blocks, write the fixed
journal inode back to disk.

Signed-off-by: Kalpak Shah <kalpak@clusterfs.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>

From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 21 Jun 2007 15:59:06 +0000 (-0400)
Subject: e2fsck: Check the all of journal blocks for validity
X-Git-Tag: E2FSPROGS-1_40~14
X-Git-Url: http://git.kernel.org/?p=fs%2Fext2%2Fe2fsprogs.git;a=commitdiff_plain;h=051afbe0d7f49429c26d2a7a33f1f3857d07c3d0

e2fsck: Check the all of journal blocks for validity

The original code only checked the direct blocks to make sure the
journal inode was sane.  Unfortunately, if some or all of the indirect
or doubly indirect blocks were corrupted, this would not be caught.
Thanks to Andreas Dilger and Kalpak Shah for noticing this problem.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>

---

Index: e2fsprogs-1.39/e2fsck/journal.c
===================================================================
--- e2fsprogs-1.39.orig/e2fsck/journal.c
+++ e2fsprogs-1.39/e2fsck/journal.c
@@ -189,8 +189,37 @@ static void e2fsck_clear_recover(e2fsck_
 	ext2fs_mark_super_dirty(ctx->fs);
 }
 
+/*
+ * This is a helper function to check the validity of the journal.
+ */
+struct process_block_struct {
+	e2_blkcnt_t	last_block;
+};
+
+static int process_journal_block(ext2_filsys fs,
+				 blk_t	*block_nr,
+				 e2_blkcnt_t blockcnt,
+				 blk_t ref_block EXT2FS_ATTR((unused)),
+				 int ref_offset EXT2FS_ATTR((unused)),
+				 void *priv_data)
+{
+	struct process_block_struct *p;
+	blk_t	blk = *block_nr;
+
+	p = (struct process_block_struct *) priv_data;
+
+	if (blk < fs->super->s_first_data_block ||
+	    blk >= fs->super->s_blocks_count)
+		return BLOCK_ABORT;
+
+	if (blockcnt >= 0)
+		p->last_block = blockcnt;
+	return 0;
+}
+
 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
 {
+	struct process_block_struct pb;
 	struct ext2_super_block *sb = ctx->fs->super;
 	struct ext2_super_block jsuper;
 	struct problem_context	pctx;
@@ -202,10 +231,8 @@ static errcode_t e2fsck_get_journal(e2fs
 	errcode_t		retval = 0;
 	io_manager		io_ptr = 0;
 	unsigned long		start = 0;
-	blk_t			blk;
 	int			ext_journal = 0;
 	int			tried_backup_jnl = 0;
-	int			i;
 
 	clear_problem_context(&pctx);
 
@@ -258,6 +285,9 @@ static errcode_t e2fsck_get_journal(e2fs
 			j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
 			j_inode->i_ext2.i_links_count = 1;
 			j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
+			e2fsck_use_inode_shortcuts(ctx, 1);
+			ctx->stashed_ino = j_inode->i_ino;
+			ctx->stashed_inode = &j_inode->i_ext2;
 			tried_backup_jnl++;
 		}
 		if (!j_inode->i_ext2.i_links_count ||
@@ -270,21 +300,22 @@ static errcode_t e2fsck_get_journal(e2fs
 			retval = EXT2_ET_JOURNAL_TOO_SMALL;
 			goto try_backup_journal;
 		}
-		for (i=0; i < EXT2_N_BLOCKS; i++) {
-			blk = j_inode->i_ext2.i_block[i];
-			if (!blk) {
-				if (i < EXT2_NDIR_BLOCKS) {
-					retval = EXT2_ET_JOURNAL_TOO_SMALL;
-					goto try_backup_journal;
-				}
-				continue;
-			}
-			if (blk < sb->s_first_data_block ||
-			    blk >= sb->s_blocks_count) {
-				retval = EXT2_ET_BAD_BLOCK_NUM;
-				goto try_backup_journal;
-			}
+		pb.last_block = -1;
+		retval = ext2fs_block_iterate2(ctx->fs, j_inode->i_ino,
+					       BLOCK_FLAG_HOLE, 0, 
+					       process_journal_block, &pb);
+		if ((pb.last_block+1) * ctx->fs->blocksize < 
+		    j_inode->i_ext2.i_size) {
+			retval = EXT2_ET_JOURNAL_TOO_SMALL;
+			goto try_backup_journal;
 		}
+		if (tried_backup_jnl && !(ctx->options & E2F_OPT_READONLY)) {
+			retval = ext2fs_write_inode(ctx->fs, sb->s_journal_inum,
+						    &j_inode->i_ext2);
+			if (retval)
+				goto errout;
+		}
+
 		journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
 
 #ifdef USE_INODE_IO
@@ -390,9 +421,11 @@ static errcode_t e2fsck_get_journal(e2fs
 #endif
 
 	*ret_journal = journal;
+	e2fsck_use_inode_shortcuts(ctx, 0);
 	return 0;
 
 errout:
+	e2fsck_use_inode_shortcuts(ctx, 0);
 	if (dev_fs)
 		ext2fs_free_mem(&dev_fs);
 	if (j_inode)