⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jbd-journal-chksum-2.6.18-vanilla.patch

📁 lustre 1.6.5 source code
💻 PATCH
📖 第 1 页 / 共 2 页
字号:
+	__be32          h_blocktype;+	__be32          h_sequence;+	unsigned char   h_chksum_type;+	unsigned char   h_chksum_size;+	unsigned char 	h_padding[2];+	__be32 		h_chksum[JFS_CHECKSUM_BYTES];+};  /*   * The block tag: used to describe a single buffer in the journal @@ -234,12 +257,16 @@ typedef struct journal_superblock_s 	((j)->j_format_version >= 2 &&					\ 	 ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) -#define JFS_FEATURE_INCOMPAT_REVOKE	0x00000001+#define JFS_FEATURE_COMPAT_CHECKSUM  	0x00000001++#define JFS_FEATURE_INCOMPAT_REVOKE		0x00000001+#define JFS_FEATURE_INCOMPAT_ASYNC_COMMIT    	0x00000004  /* Features known to this kernel version: */-#define JFS_KNOWN_COMPAT_FEATURES	0+#define JFS_KNOWN_COMPAT_FEATURES	JFS_FEATURE_COMPAT_CHECKSUM #define JFS_KNOWN_ROCOMPAT_FEATURES	0-#define JFS_KNOWN_INCOMPAT_FEATURES	JFS_FEATURE_INCOMPAT_REVOKE+#define JFS_KNOWN_INCOMPAT_FEATURES	(JFS_FEATURE_INCOMPAT_REVOKE | \+					JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)  #ifdef __KERNEL__ @@ -1053,6 +1080,8 @@ extern int	   journal_check_available_fe 		   (journal_t *, unsigned long, unsigned long, unsigned long); extern int	   journal_set_features  		   (journal_t *, unsigned long, unsigned long, unsigned long);+extern int	   journal_clear_features+		   (journal_t *, unsigned long, unsigned long, unsigned long); extern int	   journal_create     (journal_t *); extern int	   journal_load       (journal_t *journal); extern void	   journal_destroy    (journal_t *);Index: linux-2.6.18.8/fs/jbd/recovery.c===================================================================--- linux-2.6.18.8.orig/fs/jbd/recovery.c+++ linux-2.6.18.8/fs/jbd/recovery.c@@ -21,6 +21,7 @@ #include <linux/jbd.h> #include <linux/errno.h> #include <linux/slab.h>+#include <linux/crc32.h> #endif  /*@@ -307,6 +308,37 @@ int journal_skip_recovery(journal_t *jou 	return err; } +/*+ * calc_chksums calculates the checksums for the blocks described in the+ * descriptor block.+ */+static int calc_chksums(journal_t *journal, struct buffer_head *bh,+		       unsigned long *next_log_block, __u32 *crc32_sum)+{+	int i, num_blks, err;+	unsigned long io_block;+	struct buffer_head *obh;++	num_blks = count_tags(bh, journal->j_blocksize);+	/* Calculate checksum of the descriptor block. */+	*crc32_sum = crc32_be(*crc32_sum, (void *)bh->b_data, bh->b_size);++	for (i = 0; i < num_blks; i++) {+		io_block = (*next_log_block)++;+		wrap(journal, *next_log_block);+		err = jread(&obh, journal, io_block);+		if (err) {+			printk(KERN_ERR "JBD: IO error %d recovering block "+				"%lu in log\n", err, io_block);+			return 1;+		} else {+			*crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data,+				     obh->b_size);+		}+	}+	return 0;+}+ static int do_one_pass(journal_t *journal, 			struct recovery_info *info, enum passtype pass) {@@ -318,6 +350,7 @@ static int do_one_pass(journal_t *journa 	struct buffer_head *	bh; 	unsigned int		sequence; 	int			blocktype;+	__u32			crc32_sum = ~0; /* Transactional Checksums */  	/* Precompute the maximum metadata descriptors in a descriptor block */ 	int			MAX_BLOCKS_PER_DESC;@@ -409,9 +442,24 @@ static int do_one_pass(journal_t *journa 		switch(blocktype) { 		case JFS_DESCRIPTOR_BLOCK: 			/* If it is a valid descriptor block, replay it-			 * in pass REPLAY; otherwise, just skip over the-			 * blocks it describes. */+			 * in pass REPLAY; if journal_checksums enabled, then+			 * calculate checksums in PASS_SCAN, otherwise,+			 * just skip over the blocks it describes. */ 			if (pass != PASS_REPLAY) {+				if (pass == PASS_SCAN &&+				    JFS_HAS_COMPAT_FEATURE(journal,+					    JFS_FEATURE_COMPAT_CHECKSUM) &&+				    !info->end_transaction) {+					if (calc_chksums(journal, bh,+							&next_log_block,+							&crc32_sum)) {+						put_bh(bh);+						break;+					}+					put_bh(bh);+					continue;+				}+ 				next_log_block += 					count_tags(bh, journal->j_blocksize); 				wrap(journal, next_log_block);@@ -506,9 +554,97 @@ static int do_one_pass(journal_t *journa 			continue;  		case JFS_COMMIT_BLOCK:-			/* Found an expected commit block: not much to-			 * do other than move on to the next sequence+			/*     How to differentiate between interrupted commit+			 *               and journal corruption ?+			 *+			 * {nth transaction}+			 *        Checksum Verification Failed+			 *			 |+			 *		 ____________________+			 *		|		     |+			 * 	async_commit             sync_commit+			 *     		|                    |+			 *		| GO TO NEXT    "Journal Corruption"+			 *		| TRANSACTION+			 *		|+			 * {(n+1)th transanction}+			 *		|+			 * 	 _______|______________+			 * 	|	 	      |+			 * Commit block found	Commit block not found+			 *      |		      |+			 * "Journal Corruption"       |+			 *		 _____________|__________+			 *     		|	           	|+			 *	nth trans corrupt	OR   nth trans+			 *	and (n+1)th interrupted     interrupted	+			 *	before commit block+			 *      could reach the disk.+			 *	(Cannot find the difference in above+			 *	 mentioned conditions. Hence assume+			 *	 "Interrupted Commit".)+			 */++			/* Found an expected commit block: if checksums+			 * are present verify them in PASS_SCAN; else not+			 * much to do other than move on to the next sequence 			 * number. */+			if (pass == PASS_SCAN &&+			    JFS_HAS_COMPAT_FEATURE(journal,+				    JFS_FEATURE_COMPAT_CHECKSUM)) {+				int chksum_err, chksum_seen;+				struct commit_header *cbh =+					(struct commit_header *)bh->b_data;+				unsigned found_chksum =+						be32_to_cpu(cbh->h_chksum[0]);++				chksum_err = chksum_seen = 0;++				if (info->end_transaction) {+					printk(KERN_ERR "JBD: Transaction %u "+						"found to be corrupt.\n",+						next_commit_ID - 1);+					brelse(bh);+					break;+				}++				if (crc32_sum == found_chksum &&+				    cbh->h_chksum_type == JFS_CRC32_CHKSUM &&+				    cbh->h_chksum_size ==+						JFS_CRC32_CHKSUM_SIZE) {+				       chksum_seen = 1;+				} else if (!(cbh->h_chksum_type == 0 &&+					     cbh->h_chksum_size == 0 &&+					     found_chksum == 0 &&+					     !chksum_seen)) {+				/*+				 * If fs is mounted using an old kernel and then+				 * kernel with journal_chksum is used then we+				 * get a situation where the journal flag has+				 * checksum flag set but checksums are not+				 * present i.e chksum = 0, in the individual+				 * commit blocks.+				 * Hence to avoid checksum failures, in this+				 * situation, this extra check is added.+				 */+						chksum_err = 1;+				}++				if (chksum_err) {+					info->end_transaction = next_commit_ID;++					if (!JFS_HAS_INCOMPAT_FEATURE(journal,+					    JFS_FEATURE_INCOMPAT_ASYNC_COMMIT)){+						printk(KERN_ERR+						       "JBD: Transaction %u "+						       "found to be corrupt.\n",+						       next_commit_ID);+						brelse(bh);+						break;+					}+				}+				crc32_sum = ~0;+			} 			brelse(bh); 			next_commit_ID++; 			continue;@@ -544,9 +680,10 @@ static int do_one_pass(journal_t *journa 	 * transaction marks the end of the valid log. 	 */ -	if (pass == PASS_SCAN)-		info->end_transaction = next_commit_ID;-	else {+	if (pass == PASS_SCAN) {+		if (!info->end_transaction)+			info->end_transaction = next_commit_ID;+	} else { 		/* It's really bad news if different passes end up at 		 * different places (but possible due to IO errors). */ 		if (info->end_transaction != next_commit_ID) {Index: linux-2.6.18.8/fs/jbd/journal.c===================================================================--- linux-2.6.18.8.orig/fs/jbd/journal.c+++ linux-2.6.18.8/fs/jbd/journal.c@@ -67,6 +67,7 @@ EXPORT_SYMBOL(journal_update_format); EXPORT_SYMBOL(journal_check_used_features); EXPORT_SYMBOL(journal_check_available_features); EXPORT_SYMBOL(journal_set_features);+EXPORT_SYMBOL(journal_clear_features); EXPORT_SYMBOL(journal_create); EXPORT_SYMBOL(journal_load); EXPORT_SYMBOL(journal_destroy);@@ -1573,6 +1574,33 @@ int journal_set_features (journal_t *jou 	return 1; } +/**+ * int journal_clear_features () - Clear a given journal feature in the superblock+ * @journal: Journal to act on.+ * @compat: bitmask of compatible features+ * @ro: bitmask of features that force read-only mount+ * @incompat: bitmask of incompatible features+ *+ * Clear a given journal feature as present on the+ * superblock.  Returns true if the requested features could be reset.+ *+ */+int journal_clear_features (journal_t *journal, unsigned long compat,+			  unsigned long ro, unsigned long incompat)+{+	journal_superblock_t *sb;++	jbd_debug(1, "Clear features 0x%lx/0x%lx/0x%lx\n",+		  compat, ro, incompat);++	sb = journal->j_superblock;++	sb->s_feature_compat    &= ~cpu_to_be32(compat);+	sb->s_feature_ro_compat &= ~cpu_to_be32(ro);+	sb->s_feature_incompat  &= ~cpu_to_be32(incompat);++	return 1;+}  /**  * int journal_update_format () - Update on-disk journal structure.Index: linux-2.6.18.8/fs/Kconfig===================================================================--- linux-2.6.18.8.orig/fs/Kconfig+++ linux-2.6.18.8/fs/Kconfig@@ -140,6 +140,7 @@ config EXT3_FS_SECURITY  config JBD 	tristate+	select CRC32 	help 	  This is a generic journaling layer for block devices.  It is 	  currently used by the ext3 and OCFS2 file systems, but it couldIndex: linux-2.6.18.8/Documentation/filesystems/ext3.txt===================================================================--- linux-2.6.18.8.orig/Documentation/filesystems/ext3.txt+++ linux-2.6.18.8/Documentation/filesystems/ext3.txt@@ -14,6 +14,16 @@ Options When mounting an ext3 filesystem, the following option are accepted: (*) == default +journal_checksum	Enable checksumming of the journal transactions.+			This will allow the recovery code in e2fsck and the+			kernel to detect corruption in the kernel.  It is a+			compatible change and will be ignored by older kernels.++journal_async_commit	Commit block can be written to disk without waiting+			for descriptor blocks. If enabled older kernels cannot+			mount the device. This will enable 'journal_checksum'+			internally.+ journal=update		Update the ext3 file system's journal to the current 			format. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -