Module Name:    src
Committed By:   reinoud
Date:           Wed Jul 29 17:06:57 UTC 2009

Modified Files:
        src/sys/fs/nilfs: nilfs_subr.c

Log Message:
Re-do nilfs_load_super_root() and implement crc checking of read in super root
to check for consistency.

Since a new crc-seed is chosen on each new nilfs formatting, older structures
will fail the crc check.


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/fs/nilfs/nilfs_subr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/nilfs/nilfs_subr.c
diff -u src/sys/fs/nilfs/nilfs_subr.c:1.3 src/sys/fs/nilfs/nilfs_subr.c:1.4
--- src/sys/fs/nilfs/nilfs_subr.c:1.3	Wed Jul 29 13:23:23 2009
+++ src/sys/fs/nilfs/nilfs_subr.c	Wed Jul 29 17:06:57 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: nilfs_subr.c,v 1.3 2009/07/29 13:23:23 reinoud Exp $ */
+/* $NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud Exp $ */
 
 /*
  * Copyright (c) 2008, 2009 Reinoud Zandijk
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.3 2009/07/29 13:23:23 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -502,13 +502,13 @@
 	struct nilfs_recover_info *ri)
 {
 	struct nilfs_segment_summary *segsum = &ri->segsum;
+	struct nilfs_super_root *super_root;
 	struct buf *bp;
 	uint64_t blocknr, offset;
 	uint32_t segsum_size, size;
 	uint32_t nsumblk, nfileblk;
-	int error;
-
-	bp = NULL;
+	uint32_t super_root_crc, comp_crc;
+	int off, error;
 
 	/* process segment summary */
 	segsum_size = nilfs_rw32(segsum->ss_sumbytes);
@@ -519,29 +519,39 @@
 	if ((nilfs_rw16(segsum->ss_flags) & NILFS_SS_SR) == 0) {
 		DPRINTF(VOLUMES, ("nilfs: no super root in pseg %"PRIu64"\n",
 			ri->pseg));
-		error = ENOENT;
-		goto out;
+		return ENOENT;
 	}
 
 	/* get our super root, located at the end of the pseg */
 	blocknr = ri->pseg + nsumblk + nfileblk - 1;
 	offset = 0;
 	size = sizeof(struct nilfs_super_root);
+	bp = NULL;
 	error = nilfs_get_segment_log(nilfsdev,
 			&blocknr, &offset, &bp,
 			size, (void *) &nilfsdev->super_root);
+	if (bp)
+		brelse(bp, BC_AGE);
 	if (error) {
 		printf("read in of superroot failed\n");
-		error = EIO;
+		return EIO;
 	}
-	/* else got our super root! */
-	DPRINTF(VOLUMES, ("    got superroot\n"));
 
-out:
-	if (bp)
-		brelse(bp, BC_AGE);
+	/* check super root crc */
+	super_root = &nilfsdev->super_root;
+	super_root_crc = nilfs_rw32(super_root->sr_sum);
+	off = sizeof(super_root->sr_sum);
+	comp_crc = crc32_le(nilfs_rw32(nilfsdev->super.s_crc_seed),
+		(uint8_t *) super_root + off,
+		NILFS_SR_BYTES - off);
+	if (super_root_crc != comp_crc) {
+		DPRINTF(VOLUMES, ("    invalid superroot, likely from old format\n"));
+		return EINVAL;
+	}
 
-	return error;
+	DPRINTF(VOLUMES, ("    got valid superroot\n"));
+
+	return 0;
 }
 
 /* 

Reply via email to