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; } /*