diff mbox

[20/51] e2fsck: Verify extent tree blocks and clear the bad ones

Message ID 20111214011531.20947.535.stgit@elm3c44.beaverton.ibm.com
State Superseded, archived
Headers show

Commit Message

Darrick J. Wong Dec. 14, 2011, 1:15 a.m. UTC
When we encounter an extent tree block that passes the header check but fails
the checksum, offer to clear just that extent block instead of failing the
whole tree, which results in the entire inode being wiped out.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
 e2fsck/pass1.c   |   11 +++++++++--
 e2fsck/problem.c |    6 ++++++
 e2fsck/problem.h |    3 +++
 3 files changed, 18 insertions(+), 2 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Andreas Dilger Dec. 19, 2011, 6:50 a.m. UTC | #1
On 2011-12-14, at 2:15, "Darrick J. Wong" <djwong@us.ibm.com> wrote:

> When we encounter an extent tree block that passes the header check but fails
> the checksum, offer to clear just that extent block instead of failing the
> whole tree, which results in the entire inode being wiped out.
> 
> diff --git a/e2fsck/problem.c b/e2fsck/problem.c
> index e74ad79..96b0de5 100644
> --- a/e2fsck/problem.c
> +++ b/e2fsck/problem.c
> @@ -946,6 +946,12 @@ static struct e2fsck_problem problem_table[] = {
>      N_("The bad @b @i looks @n.  "),
>      PROMPT_CLEAR, 0 },
> 
> +    /* Extent block does not match extent */
> +    { PR_1_EXTENT_CSUM_INVALID,
> +      N_("@i %i extent block checksum does not match extent\n\t(logical @b "
> +         "%c, @n physical @b %b, len %N)\n"),
> +      PROMPT_CLEAR, 0 },

Since the comment above the problem definition is the only place that the full string can be found, it should match the printed string exactly. In this case it is missing "inode" at the start and "checksum" in the middle of the comment. 

Cheers, Andreas--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Darrick J. Wong Dec. 19, 2011, 7:47 p.m. UTC | #2
On Mon, Dec 19, 2011 at 07:50:07AM +0100, Andreas Dilger wrote:
> On 2011-12-14, at 2:15, "Darrick J. Wong" <djwong@us.ibm.com> wrote:
> 
> > When we encounter an extent tree block that passes the header check but fails
> > the checksum, offer to clear just that extent block instead of failing the
> > whole tree, which results in the entire inode being wiped out.
> > 
> > diff --git a/e2fsck/problem.c b/e2fsck/problem.c
> > index e74ad79..96b0de5 100644
> > --- a/e2fsck/problem.c
> > +++ b/e2fsck/problem.c
> > @@ -946,6 +946,12 @@ static struct e2fsck_problem problem_table[] = {
> >      N_("The bad @b @i looks @n.  "),
> >      PROMPT_CLEAR, 0 },
> > 
> > +    /* Extent block does not match extent */
> > +    { PR_1_EXTENT_CSUM_INVALID,
> > +      N_("@i %i extent block checksum does not match extent\n\t(logical @b "
> > +         "%c, @n physical @b %b, len %N)\n"),
> > +      PROMPT_CLEAR, 0 },
> 
> Since the comment above the problem definition is the only place that the
> full string can be found, it should match the printed string exactly. In this
> case it is missing "inode" at the start and "checksum" in the middle of the
> comment. 

Ok.

--D
> 
> Cheers, Andreas--
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 15320c6..7cfc739 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1761,7 +1761,9 @@  static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 
 	pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
 					  &extent);
-	while (!pctx->errcode && info.num_entries-- > 0) {
+	while ((pctx->errcode == 0 ||
+		pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID) &&
+	       info.num_entries-- > 0) {
 		is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
 		is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
 
@@ -1776,6 +1778,8 @@  static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 			 (extent.e_pblk + extent.e_len) >
 			 ext2fs_blocks_count(ctx->fs->super))
 			problem = PR_1_EXTENT_ENDS_BEYOND;
+		else if (pctx->errcode == EXT2_ET_EXTENT_CSUM_INVALID)
+			problem = PR_1_EXTENT_CSUM_INVALID;
 
 		if (problem) {
 		report_problem:
@@ -1809,7 +1813,10 @@  static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 			if (pctx->errcode) {
 				pctx->str = "EXT2_EXTENT_DOWN";
 				problem = PR_1_EXTENT_HEADER_INVALID;
-				if (pctx->errcode == EXT2_ET_EXTENT_HEADER_BAD)
+				if (pctx->errcode ==
+					EXT2_ET_EXTENT_HEADER_BAD ||
+				    pctx->errcode ==
+					EXT2_ET_EXTENT_CSUM_INVALID)
 					goto report_problem;
 				return;
 			}
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index e74ad79..96b0de5 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -946,6 +946,12 @@  static struct e2fsck_problem problem_table[] = {
 	  N_("The bad @b @i looks @n.  "),
 	  PROMPT_CLEAR, 0 },
 
+	/* Extent block does not match extent */
+	{ PR_1_EXTENT_CSUM_INVALID,
+	  N_("@i %i extent block checksum does not match extent\n\t(logical @b "
+	     "%c, @n physical @b %b, len %N)\n"),
+	  PROMPT_CLEAR, 0 },
+
 	/* Pass 1b errors */
 
 	/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 1d63598..a1e7ffb 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -553,6 +553,9 @@  struct problem_context {
 /* inode checksum does not match inode */
 #define PR_1_INODE_CSUM_INVALID		0x010066
 
+/* extent block checksum does not match extent block */
+#define PR_1_EXTENT_CSUM_INVALID	0x010067
+
 /*
  * Pass 1b errors
  */