Subject: Re: details of panic with binary-1.1-alpha2
To: Arne H. Juul <arnej@pvv.unit.no>
From: Chris G Demetriou <Chris_G_Demetriou@BALVENIE.PDL.CS.CMU.EDU>
List: port-pmax
Date: 11/20/1995 20:38:21
> d) A bug somewhere else entirely is trashing filesystem data structures.

This is probably it.  I ran into a repeatable problem that would cause
my alphas to go belly-up in ffs_clusteracct, and only fixed it a week
or two ago.  This bug was fixed in Lite2, but Lite2 hasn't been
integrated into NetBSD yet.

The panic would happen to me immediately, and repeatably (for a given
kernel) when i tried writing a new file on my root file system.  it
turns out that if the kernel that your superblock was last updated
with is similar enough to the one you're currently running (in terms
of memory allocation addresses, etc.), you can get lucky and not
lose.  it was sort of bizarre figuring out that the bug really wasn't
in the alpha code...  8-)

please tell me if it solves the problem you're having.


chris
--- cut here ---
Index: ffs_vfsops.c
===================================================================
RCS file: /usr/users/cgd/NetBSD/cvs/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -c -r1.9 -r1.10
*** 1.9	1995/06/20 17:09:53
--- 1.10	1995/11/10 00:50:45
***************
*** 297,305 ****
  	struct inode *ip;
  	struct csum *space;
  	struct buf *bp;
! 	struct fs *fs;
  	struct partinfo dpart;
  	int i, blks, size, error;
  
  	if ((mountp->mnt_flag & MNT_RDONLY) == 0)
  		return (EINVAL);
--- 297,306 ----
  	struct inode *ip;
  	struct csum *space;
  	struct buf *bp;
! 	struct fs *fs, *newfs;
  	struct partinfo dpart;
  	int i, blks, size, error;
+ 	int32_t *lp;
  
  	if ((mountp->mnt_flag & MNT_RDONLY) == 0)
  		return (EINVAL);
***************
*** 318,333 ****
  		size = dpart.disklab->d_secsize;
  	if (error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, NOCRED, &bp))
  		return (error);
! 	fs = (struct fs *)bp->b_data;
! 	if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
! 	    fs->fs_bsize < sizeof(struct fs)) {
  		brelse(bp);
  		return (EIO);		/* XXX needs translation */
  	}
  	fs = VFSTOUFS(mountp)->um_fs;
! 	bcopy(&fs->fs_csp[0], &((struct fs *)bp->b_data)->fs_csp[0],
! 	    sizeof(fs->fs_csp));
! 	bcopy(bp->b_data, fs, (u_int)fs->fs_sbsize);
  	if (fs->fs_sbsize < SBSIZE)
  		bp->b_flags |= B_INVAL;
  	brelse(bp);
--- 319,339 ----
  		size = dpart.disklab->d_secsize;
  	if (error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, NOCRED, &bp))
  		return (error);
! 	newfs = (struct fs *)bp->b_data;
! 	if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE ||
! 	    newfs->fs_bsize < sizeof(struct fs)) {
  		brelse(bp);
  		return (EIO);		/* XXX needs translation */
  	}
  	fs = VFSTOUFS(mountp)->um_fs;
! 	/* 
! 	 * Copy pointer fields back into superblock before copying in	XXX
! 	 * new superblock. These should really be in the ufsmount.	XXX
! 	 * Note that important parameters (eg fs_ncg) are unchanged.
! 	 */
! 	bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp));
! 	newfs->fs_maxcluster = fs->fs_maxcluster;
! 	bcopy(newfs, fs, (u_int)fs->fs_sbsize);
  	if (fs->fs_sbsize < SBSIZE)
  		bp->b_flags |= B_INVAL;
  	brelse(bp);
***************
*** 348,353 ****
--- 354,368 ----
  		bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size);
  		brelse(bp);
  	}
+ 	/*
+ 	 * We no longer know anything about clusters per cylinder group.
+ 	 */
+ 	if (fs->fs_contigsumsize > 0) {
+ 		lp = fs->fs_maxcluster;
+ 		for (i = 0; i < fs->fs_ncg; i++)
+ 			*lp++ = fs->fs_contigsumsize;
+ 	}
+ 
  loop:
  	for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
  		nvp = vp->v_mntvnodes.le_next;