shithub: lwext4

Download patch

ref: 1a96ef0a24a443094ad3c0293387a70e607227ee
parent: fb6fd61f3ec5bc98fab5ad8e0d6fec95c70d643a
author: Kaho Ng <ngkaho1234@gmail.com>
date: Tue Nov 22 00:24:18 EST 2016

ext4_journal: some reworks to stale metadata protection

--- a/src/ext4_journal.c
+++ b/src/ext4_journal.c
@@ -1157,11 +1157,13 @@
 			ext4_dbg(DEBUG_JBD, "Commit block: %" PRIu32", "
 					    "trans_id: %" PRIu32"\n",
 					    this_block, this_trans_id);
-			/* This is the end of a transaction,
+			/*
+			 * This is the end of a transaction,
 			 * we may now proceed to the next transaction.
 			 */
 			this_trans_id++;
-			info->trans_cnt++;
+			if (action == ACTION_SCAN)
+				info->trans_cnt++;
 			break;
 		case JBD_REVOKE_BLOCK:
 			if (!jbd_verify_meta_csum(jbd_fs, header)) {
@@ -1236,6 +1238,7 @@
 			ext4_get32(&jbd_fs->inode_ref.fs->sb,
 				   features_incompatible);
 		jbd_set32(&jbd_fs->sb, start, 0);
+		jbd_set32(&jbd_fs->sb, sequence, info.last_trans_id);
 		features_incompatible &= ~EXT4_FINCOM_RECOVER;
 		ext4_set32(&jbd_fs->inode_ref.fs->sb,
 			   features_incompatible,
@@ -1267,7 +1270,6 @@
 	uint32_t features_incompatible =
 			ext4_get32(&jbd_fs->inode_ref.fs->sb,
 				   features_incompatible);
-	struct ext4_block block = EXT4_BLOCK_ZERO();
 	features_incompatible |= EXT4_FINCOM_RECOVER;
 	ext4_set32(&jbd_fs->inode_ref.fs->sb,
 			features_incompatible,
@@ -1280,26 +1282,16 @@
 	journal->first = jbd_get32(&jbd_fs->sb, first);
 	journal->start = journal->first;
 	journal->last = journal->first;
-	journal->trans_id = 1;
-	journal->alloc_trans_id = 1;
+	/*
+	 * To invalidate any stale records we need to start from
+	 * the checkpoint transaction ID of the previous journalling session
+	 * plus 1.
+	 */
+	journal->trans_id = jbd_get32(&jbd_fs->sb, sequence) + 1;
+	journal->alloc_trans_id = journal->trans_id;
 
 	journal->block_size = jbd_get32(&jbd_fs->sb, blocksize);
 
-	r = jbd_block_get_noread(jbd_fs,
-			 &block,
-			 journal->start);
-	if (r != EOK) {
-		memset(journal, 0, sizeof(struct jbd_journal));
-		return r;
-	}
-	memset(block.data, 0, journal->block_size);
-	ext4_bcache_set_dirty(block.buf);
-	r = jbd_block_set(jbd_fs, &block);
-	if (r != EOK) {
-		memset(journal, 0, sizeof(struct jbd_journal));
-		return r;
-	}
-
 	TAILQ_INIT(&journal->cp_queue);
 	RB_INIT(&journal->block_rec_root);
 	journal->jbd_fs = jbd_fs;
@@ -1773,29 +1765,12 @@
 	int rc;
 	struct ext4_block block;
 	struct jbd_commit_header *header;
-	uint32_t commit_iblock, orig_commit_iblock;
+	uint32_t commit_iblock;
 	struct jbd_journal *journal = trans->journal;
 
 	commit_iblock = jbd_journal_alloc_block(journal, trans);
-	orig_commit_iblock = commit_iblock;
-	commit_iblock++;
-	wrap(&journal->jbd_fs->sb, commit_iblock);
 
-	/* To prevent accidental reference to stale journalling metadata. */
-	if (orig_commit_iblock < commit_iblock) {
-		rc = jbd_block_get_noread(journal->jbd_fs, &block, commit_iblock);
-		if (rc != EOK)
-			return rc;
-
-		memset(block.data, 0, journal->block_size);
-		ext4_bcache_set_dirty(block.buf);
-		ext4_bcache_set_flag(block.buf, BC_TMP);
-		rc = jbd_block_set(journal->jbd_fs, &block);
-		if (rc != EOK)
-			return rc;
-	}
-
-	rc = jbd_block_get_noread(journal->jbd_fs, &block, orig_commit_iblock);
+	rc = jbd_block_get_noread(journal->jbd_fs, &block, commit_iblock);
 	if (rc != EOK)
 		return rc;