From owner-freebsd-hackers Sat Feb 8 18:50:40 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id SAA20490 for hackers-outgoing; Sat, 8 Feb 1997 18:50:40 -0800 (PST) Received: from dg-rtp.dg.com (dg-rtp.rtp.dg.com [128.222.1.2]) by freefall.freebsd.org (8.8.5/8.8.5) with SMTP id SAA20485 for ; Sat, 8 Feb 1997 18:50:36 -0800 (PST) Received: by dg-rtp.dg.com (5.4R3.10/dg-rtp-v02) id AA11335; Sat, 8 Feb 1997 21:50:05 -0500 Received: from ponds by dg-rtp.dg.com.rtp.dg.com; Sat, 8 Feb 1997 21:50 EST Received: from lakes.water.net (lakes [10.0.0.3]) by ponds.water.net (8.8.3/8.7.3) with ESMTP id VAA06145; Sat, 8 Feb 1997 21:22:13 -0500 (EST) Received: (from rivers@localhost) by lakes.water.net (8.8.3/8.6.9) id VAA22081; Sat, 8 Feb 1997 21:26:35 -0500 (EST) Date: Sat, 8 Feb 1997 21:26:35 -0500 (EST) From: Thomas David Rivers Message-Id: <199702090226.VAA22081@lakes.water.net> To: ponds!root.com!dg, ponds!freefall.cdrom.com!freebsd-hackers, ponds!lambert.org!terry Subject: Copious information on panic: ffs_valloc: dup alloc - IDEAS??? Content-Type: text Sender: owner-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk Ok - Here's the evaluation of the panic: ffs_valloc: dup alloc. When I say evaluation; I mean I've examined all the macros, and (using kernel printf's) determined what values are being used. I've written everything down... Although I can readily do this; I have no idea if something is erroneous here; I'm just plugging in values. Again, this is all with 2.1.6.1 sources. But, I'm wondering what the ino_to_fsba() macro [used in the bread() to obtain the disk block in ffs_vget] is going to do when the inode is the same as fs->fs_ipg (inodes per group). Another interesting item I've discovered is that the fs->cgmask is 0xffffffff, rendering most of the macro below unused... here's the logic I've evaluated. These macros are in /sys/ufs/ffs/fs.h: #define ino_to_fsba(fs, x) \ ((daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \ (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) Doesn't that become the same as: ((daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + (blkstofrags((fs), 0))) [since ((x) % (fs) -> fs_ipg) is zero when x == (fs)->fs_ipg] blkstofrags((fs),0) then evaluates to 0; so you get ((daddr_t)(cgimin(fs, ino_to_cg(fs, x))) Now, ino_to_cg is simply ((x) / (fs)->fs_ipg), which is 1 when x == (fs)->fs_ipg. Giving: cgimin(fs, 1) {This seems write so far; we indicated we want cylinder #1.} This becomes: cgstart(fs, 1) + (fs->fs_iblkno); which is: (cgbase(fs, 1) + ((fs)->fs_cgoffset * 1) & ~((fs)->fs_cgmask)) + fs->fs_iblockno Which, in turn is: ((fs)->fs_fpg * (1) + ((fs)->fs_cgoffset * 1) & ~((fs)->fs_cgmask)) + fs->fs_blkno; or, eliminating the multiplication of 1: ((fs)->fs_fpg + ((fs)->fs_cgoffset & ~(fs)->fs_cgmask)) + fs->fs_iblkno Now - here's a strangeness - fs->cgmask (as evidenced by my printf()s), is 0xfffffff, the logical compliment of that is 0; giving: (fs->fs_fpg) + fs->fs_iblkno; So, the calculation of ino_to_fsba(fs, x) becomes (fs->fs_fpg + fs->fs_iblkno) For some reason; we've lost fs_cgoffset (because the cgmask was "strange.") I'm not sure if that's intended. Now, the bread() to retrieve the 'din' info from the disk looks like (from ffs_vfsops.c): /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), (int)fs->fs_bsize, NOCRED, &bp); Replacing our evaluation of ino_to_fsba(); we have: error = bread(ump->um_devvp, fsbtodb(fs, (fs->fs_fpg + fs->fs_iblkno), (int)fs->fs_bsize, NOCRED, &bp); which is: error = bread(ump->um_devvp, (fs->fs_fpg + fs->fs_iblkno) << (fs)->fs_fsbtodb), (int)fs->fs_bsize, NOCRED, &bp); Now, fs->fpg is 0x8000, fs->fs_iblkno is 0x20 and fs->fsbtodb is 1, so this give a block number of 0x10040 (65600). Ok - that's the logic behind what happens; here's the actual "screen" of the panic - showing my kernel printf()s that /dev/rsd0a: 20480 100.0MB in 4 cyl groups (16 c/g, 32.00MB/g, 7680 i/g) super-block backups (for fsck -b #) at: 32, 65568, 131104, 196640, ffs_vget: ip 0xf0765a00 allocated for ino #7680; ip->i_mode = 0x0 ffs_vget: after i_din assigned, ip->i_mode = 0xc674 fs->fs_cgoffset is 0x800, fs->fs_cgmask is 0xffffffff fs->fs_fsbtodb = 0x1, fs->fs_fpg = 0x8000 fs->fs_ipg = 7680, fs->fs_inopb = 64 fs->fs_iblkno = 0x20 ino_to_cg(fs, 7680) is 0x1 blkstofrags((fs), (((ino) % (fs)->fs_ipg) / INOPB(fs))) = 0 ino_to_cg(fs,ino) = 0x1 cgimin(fs, ino_to-cg(fs,ino)) = 0x8020 cgbase(fs, 1) = 0x8000 ino_to_fsba(fs,ino) is 0x8020 fsbtodb(fs, ino_to_fsba(fs,ino)) is 0x10040 ino_to-fsbo(fs,ino) is 0 ffs_alloc: VTOI returns ip for #7680, 0xf0765a00 mode = 0143164, inum = 7680, fs = /mnt ip=0xf0765a00ip->i_number=7680, ino=7680 All of this printf() output verifies the evaluation above. The question is - something is wrong here (because of the panic: ffs_valloc: dup alloc) - just what is it? Can some knowledgable FFS person examine what I've got here and find something strange? Is the disk block number (0x10040) anywhere near right for inode #7680 on this file system? Does the fact that the inode number is the same is inodes/group matter? - Thanks - - Dave Rivers -