All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] f2fs: recovering broken superblock during mount
@ 2015-05-20  7:01 hujianyang
  2015-05-21  1:07 ` Jaegeuk Kim
  0 siblings, 1 reply; 5+ messages in thread
From: hujianyang @ 2015-05-20  7:01 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-f2fs-devel

Hi Jaegeuk,

There are two superblocks in f2fs. I wrapped one of them by 'dd' in
a reliability test. After this, the polluted f2fs partition can be
mounted with an error message:

F2FS-fs (sdd3): Magic Mismatch, valid(0xf2f52010) - read(0x0)
F2FS-fs (sdd3): Can't find valid F2FS filesystem in 1th superblock

Seems the broken superblock can't be recovered by f2fs driver or
fsck.f2fs. Tell me how to recover if I was wrong.:)

So I'd like to provide a patch to recover broken f2fs superblock
during mount. But I'm not pleased with my patch. I wish you and
others could give me some suggestions.

Do you think it's necessary to recover the superblock? and can
we change 'f2fs_commit_super' a little to reuse this function
during superblock recovery?

Thanks,
Hu


diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ae14fc4..126f8fa 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -965,6 +965,33 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
 	clear_sbi_flag(sbi, SBI_NEED_FSCK);
 }

+static int get_valid_super_block(struct super_block *sb,
+			struct buffer_head **buffer, int block)
+{
+	struct f2fs_super_block *super;
+
+	*buffer = sb_bread(sb, block);
+	if (!*buffer) {
+		f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock",
+				block + 1);
+		return -EIO;
+	}
+
+	super = (struct f2fs_super_block *)
+		((char *)(*buffer)->b_data + F2FS_SUPER_OFFSET);
+
+	/* sanity checking of raw super */
+	if (sanity_check_raw_super(sb, super)) {
+		brelse(*buffer);
+		f2fs_msg(sb, KERN_ERR,
+			"Can't find valid F2FS filesystem in %dth superblock",
+								block + 1);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /*
  * Read f2fs raw super block.
  * Because we have two copies of super block, so read the first one at first,
@@ -975,37 +1002,41 @@ static int read_raw_super_block(struct super_block *sb,
 			struct buffer_head **raw_super_buf)
 {
 	int block = 0;
-
-retry:
-	*raw_super_buf = sb_bread(sb, block);
-	if (!*raw_super_buf) {
-		f2fs_msg(sb, KERN_ERR, "Unable to read %dth superblock",
-				block + 1);
-		if (block == 0) {
-			block++;
-			goto retry;
-		} else {
-			return -EIO;
-		}
+	struct buffer_head *buffer0 = NULL, *buffer1 = NULL;
+	bool readonly = f2fs_readonly(sb) || bdev_read_only(sb->s_bdev);
+	int err0, err1;
+
+	err0 = get_valid_super_block(sb, &buffer0, 0);
+	if (!err0 && readonly)
+		goto set_raw_super;
+
+	err1 = get_valid_super_block(sb, &buffer1, 1);
+	if (err0 && err1)
+		return err1;
+
+	if (err0 && !err1) {
+		buffer0 = buffer1;
+		if (readonly)
+			goto set_raw_super;
+	} else if (!err0 && !err1) {
+		brelse(buffer1);
+		goto set_raw_super;
 	}

+	f2fs_msg(sb, KERN_INFO, "Recover superblock");
+	block = buffer0->b_blocknr;
+	buffer0->b_blocknr = block ? 0 : 1;
+	mark_buffer_dirty(buffer0);
+	sync_dirty_buffer(buffer0);
+	buffer0->b_blocknr = block;
+	clear_buffer_write_io_error(buffer0);
+	set_buffer_uptodate(buffer0);
+
+set_raw_super:
+	*raw_super_buf = buffer0;
 	*raw_super = (struct f2fs_super_block *)
 		((char *)(*raw_super_buf)->b_data + F2FS_SUPER_OFFSET);

-	/* sanity checking of raw super */
-	if (sanity_check_raw_super(sb, *raw_super)) {
-		brelse(*raw_super_buf);
-		f2fs_msg(sb, KERN_ERR,
-			"Can't find valid F2FS filesystem in %dth superblock",
-								block + 1);
-		if (block == 0) {
-			block++;
-			goto retry;
-		} else {
-			return -EINVAL;
-		}
-	}
-
 	return 0;
 }


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-22  0:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-20  7:01 [PATCH RFC] f2fs: recovering broken superblock during mount hujianyang
2015-05-21  1:07 ` Jaegeuk Kim
2015-05-21  6:42   ` hujianyang
2015-05-21 22:44     ` Jaegeuk Kim
2015-05-22  0:19       ` hujianyang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.