Date: Sat, 8 Feb 1997 21:26:35 -0500 (EST) From: Thomas David Rivers <ponds!rivers@dg-rtp.dg.com> 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??? Message-ID: <199702090226.VAA22081@lakes.water.net>
next in thread | raw e-mail | index | archive | help
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 -
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199702090226.VAA22081>
