From 6338a8467564c3a0a12e9fcb08bdd748d736ac2f Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Sun, 17 May 2020 23:05:11 -0400
Subject: [PATCH] libext2fs: retry reading superblock on open when checksum is
 bad

When opening a file system which is mounted, it's possible that when
ext2fs_open2() is racing with the kernel modifying the orphaned inode
list, the superblock's checksum could be incorrect.  So retry reading
the superblock in the hopes that the problem will self-correct.

Google-Bug-Id: 151453112
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 lib/ext2fs/openfs.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index 51b54a44..ae54870e 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -134,6 +134,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
 	int		j;
 #endif
 	char		*time_env;
+	int		csum_retries = 0;
 
 	EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
 
@@ -221,6 +222,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
 		if (retval)
 			goto cleanup;
 	}
+retry:
 	retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
 				     fs->super);
 	if (retval)
@@ -232,8 +234,11 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
 		retval = 0;
 		if (!ext2fs_verify_csum_type(fs, fs->super))
 			retval = EXT2_ET_UNKNOWN_CSUM;
-		if (!ext2fs_superblock_csum_verify(fs, fs->super))
+		if (!ext2fs_superblock_csum_verify(fs, fs->super)) {
+			if (csum_retries++ < 3)
+				goto retry;
 			retval = EXT2_ET_SB_CSUM_INVALID;
+		}
 	}
 
 #ifdef WORDS_BIGENDIAN
-- 
2.25.1

