Skip to contentSkip to conversation

e2fsprogs: exit from preenhalt if IO errors were encountered

PATCH In review Eric Sandeen 1 participant 2 messages Oct 10, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 e2fsprogs: exit from preenhalt if IO errors were encountered

Resolves RH Bug 465679- e2fsck -p crashes with read-only DM device (e.g. logical volume)

If a block device is unwritable, e2fsck -p gets into an infinite loop trying to preenhalt, close & flush the fs, which tries to flush the cache, which gets a write error and calls preenhalt which tries to close & flush the fs ... ad infinitum.

Per Ted's suggestion just flag the ctx as "exiting" and short-circuit the infinite loop.

Tested by running e2fsck -p on a block device set read-only by BLKROSET.

e2fsck/e2fsck.h +1 -0
Index: e2fsprogs/e2fsck/e2fsck.h
===================================================================
@@ -174,6 +174,7 @@ struct resource_track {
 #define E2F_FLAG_RESTARTED	0x0200 /* E2fsck has been restarted */
 #define E2F_FLAG_RESIZE_INODE	0x0400 /* Request to recreate resize inode */
 #define E2F_FLAG_GOT_DEVSIZE	0x0800 /* Device size has been fetched */
+#define E2F_FLAG_EXITING	0x1000 /* E2fsck exiting due to errors */
 
 /*
  * Defines for indicating the e2fsck pass number
e2fsck/ehandler.c +4 -1
Index: e2fsprogs/e2fsck/ehandler.c
===================================================================
@@ -33,7 +33,8 @@ static errcode_t e2fsck_handle_read_erro
 	e2fsck_t ctx;
 
 	ctx = (e2fsck_t) fs->priv_data;
-
+	if (ctx->flags & E2F_FLAG_EXITING)
+		return 0;
 	/*
 	 * If more than one block was read, try reading each block
 	 * separately.  We could use the actual bytes read to figure
@@ -79,6 +80,8 @@ static errcode_t e2fsck_handle_write_err
 	e2fsck_t ctx;
 
 	ctx = (e2fsck_t) fs->priv_data;
+	if (ctx->flags & E2F_FLAG_EXITING)
+		return 0;
 
 	/*
 	 * If more than one block was written, try writing each block
e2fsck/util.c +1 -0
Index: e2fsprogs/e2fsck/util.c
===================================================================
@@ -257,6 +257,7 @@ void preenhalt(e2fsck_t ctx)
 	fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
 		"RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
 	       ctx->device_name);
+	ctx->flags |= E2F_FLAG_EXITING;
 	if (fs != NULL) {
 		fs->super->s_state |= EXT2_ERROR_FS;
 		ext2fs_mark_super_dirty(fs);
#1 lore raw
Quoted 11 lines · Eric Sandeen

Resolves RH Bug 465679- e2fsck -p crashes with read-only DM device (e.g. logical volume)

If a block device is unwritable, e2fsck -p gets into an infinite loop trying to preenhalt, close & flush the fs, which tries to flush the cache, which gets a write error and calls preenhalt which tries to close & flush the fs ... ad infinitum.

Per Ted's suggestion just flag the ctx as "exiting" and short-circuit the infinite loop.

Tested by running e2fsck -p on a block device set read-only by BLKROSET.

Oh, thanks to Vlado Potisk for reporting this.

-Eric