Skip site navigation (1)Skip section navigation (2)
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>