[Ocfs2-tools-devel] [PATCH] fsck.ocfs2, fswreck: Fix EXTENT_MARKED_UNWRITTEN error.

Joel Becker Joel.Becker at oracle.com
Tue Aug 25 17:02:17 PDT 2009


Filesystems without OCFS2_FEATURE_RO_COMPAT_UNWRITTEN should not have
extent records with the OCFS2_EXT_UNWRITTEN flag set.  Teach fsck to
check for them and correct them.  Teach fswreck to create them.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 fsck.ocfs2/extent.c               |   11 +++++++++++
 fsck.ocfs2/fsck.ocfs2.checks.8.in |    7 +++++++
 fswreck/corrupt.c                 |    1 +
 fswreck/extent.c                  |   16 ++++++++++++++++
 fswreck/include/fsck_type.h       |    3 ++-
 fswreck/main.c                    |    3 +++
 6 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/fsck.ocfs2/extent.c b/fsck.ocfs2/extent.c
index 5f6639c..17f5981 100644
--- a/fsck.ocfs2/extent.c
+++ b/fsck.ocfs2/extent.c
@@ -176,6 +176,17 @@ static errcode_t check_er(o2fsck_state *ost, struct extent_info *ei,
 		goto out;
 	}
 
+	if (!ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(ost->ost_fs->fs_super)) &&
+	    (er->e_flags & OCFS2_EXT_UNWRITTEN) &&
+	    prompt(ost, PY, PR_EXTENT_MARKED_UNWRITTEN,
+		   "The extent record for cluster offset %"PRIu32" "
+		   "in inode %"PRIu64" has the UNWRITTEN flag set, but "
+		   "this filesystem does not support unwritten extents.  "
+		   "Clear the UNWRITTEN flag?", er->e_cpos,
+		   (uint64_t)di->i_blkno)) {
+		er->e_flags &= ~OCFS2_EXT_UNWRITTEN;
+	}
+
 	first_block = ocfs2_blocks_to_clusters(ost->ost_fs, er->e_blkno);
 	first_block = ocfs2_clusters_to_blocks(ost->ost_fs, first_block);
 
diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
index c053329..0e984a2 100644
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
@@ -47,6 +47,13 @@ Answering yes implies that the generation number in the extent block is
 incorrect and that the extent block is valid.  The generation number in the
 block is updated to match the generation number in the volume.
 
+.SS "EXTENT_MARKED_UNWRITTEN"
+An extent record has the UNWRITTEN flag set, but the filesystem
+feature set does not include unwritten extents.
+
+Answering yes clears the UNWRITTEN flag.  This is safe to do; as the
+feature is disabled anyway.
+
 .SS "EXTENT_BLKNO_UNALIGNED"
 The block that marks the start of an extent should always fall on the start
 of a cluster.  An extent was found that starts part-way into a cluster.
diff --git a/fswreck/corrupt.c b/fswreck/corrupt.c
index 146e1c2..e6f2bf3 100644
--- a/fswreck/corrupt.c
+++ b/fswreck/corrupt.c
@@ -126,6 +126,7 @@ void corrupt_file(ocfs2_filesys *fs, enum fsck_type type, uint16_t slotnum)
 	case EXTENT_EB_INVALID:
 		func = mess_up_extent_block;
 		break;
+	case EXTENT_MARKED_UNWRITTEN:
 	case EXTENT_BLKNO_UNALIGNED:
 		func = mess_up_extent_record;
 		break;
diff --git a/fswreck/extent.c b/fswreck/extent.c
index e3fe020..9b5c9de 100644
--- a/fswreck/extent.c
+++ b/fswreck/extent.c
@@ -288,12 +288,28 @@ static void mess_up_record(ocfs2_filesys *fs, uint64_t blkno,
 	if (!(di->i_flags & OCFS2_VALID_FL))
 		FSWRK_COM_FATAL(progname, ret);	
 
+	/* We don't want fsck complaining about i_size */
+	if (!di->i_size)
+		di->i_size = 1;
+
 	el = &(di->id2.i_list);
 
 	if (el->l_next_free_rec > 0) {
 		er = el->l_recs;
 		oldno = er->e_blkno;
 		switch (type) {
+		case EXTENT_MARKED_UNWRITTEN:
+			if (ocfs2_writes_unwritten_extents(OCFS2_RAW_SB(fs->fs_super)))
+				FSWRK_FATAL("Cannot exercise "
+					    "EXTENT_MARKED_UNWRITTEN on a "
+					    "filesystem with unwritten "
+					    "extents supported (obviously)");
+			er->e_flags |= OCFS2_EXT_UNWRITTEN;
+			fprintf(stdout, "EXTENT_MARKED_UNWRITTEN: "
+				"Corrupt inode#%"PRIu64", mark extent "
+				"at cpos %"PRIu32" unwritten\n",
+				blkno, er->e_cpos);
+			break;
 		case EXTENT_BLKNO_UNALIGNED: 
 			er->e_blkno += 1;
 			fprintf(stdout, "EXTENT_BLKNO_UNALIGNED: "
diff --git a/fswreck/include/fsck_type.h b/fswreck/include/fsck_type.h
index 77ff1fa..c385383 100644
--- a/fswreck/include/fsck_type.h
+++ b/fswreck/include/fsck_type.h
@@ -36,6 +36,7 @@ enum fsck_type
 { 	EB_BLKNO = 0,
 	EB_GEN,
 	EB_GEN_FIX,
+	EXTENT_MARKED_UNWRITTEN,
 	EXTENT_BLKNO_UNALIGNED,
 	EXTENT_CLUSTERS_OVERRUN,
 	EXTENT_EB_INVALID,
@@ -141,7 +142,7 @@ enum fsck_type
  * Extent list error: EB_LIST_DEPTH, EXTENT_LIST_COUNT, EXTENT_LIST_FREE 
  *
  * Extent record error: EXTENT_BLKNO_UNALIGNED, EXTENT_CLUSTERS_OVERRUN, 
- *			EXTENT_BLKNO_RANGE
+ *			EXTENT_BLKNO_RANGE, EXTENT_MARKED_UNWRITTEN
  *
  * Chain list error:	CHAIN_COUNT, CHAIN_NEXT_FREE
  *
diff --git a/fswreck/main.c b/fswreck/main.c
index d08f51a..85b0472 100644
--- a/fswreck/main.c
+++ b/fswreck/main.c
@@ -59,6 +59,9 @@ static struct prompt_code prompt_codes[NUM_FSCK_TYPE] = {
 			   "so that fsck.ocfs2 can fix it"),
 	define_prompt_code(EXTENT_EB_INVALID, corrupt_file,
 			   "Corrupt an extent block's generation number"),
+	define_prompt_code(EXTENT_MARKED_UNWRITTEN, corrupt_file,
+			   "Mark an extent unwritten when the filesystem "
+			   "does not support it"),
 	define_prompt_code(EXTENT_BLKNO_UNALIGNED, corrupt_file,
 			   "Corrupt extent record's e_blkno"),
 	define_prompt_code(EXTENT_CLUSTERS_OVERRUN, corrupt_file,
-- 
1.6.3.3


-- 

"One of the symptoms of an approaching nervous breakdown is the
 belief that one's work is terribly important."
         - Bertrand Russell 

Joel Becker
Principal Software Developer
Oracle
E-mail: joel.becker at oracle.com
Phone: (650) 506-8127



More information about the Ocfs2-tools-devel mailing list