Inode Bug Fix for ISC 2.2 (and probably 2.2.1)

Larry Jones scjones at thor.UUCP
Thu Jan 10 08:52:27 AEST 1991


Here's the fix I originally posted for ISC 2.2 which probably applies
to ISC 2.2.1 as well.  If the test from the description I posted says
that 2.2.1 still has the bug and this patch doesn't work, let me know
and I'll try to develop a new fix for it.

Well, despite rumors to the contrary, the dreaded System V inode
bug isn't quite fixed in ISC 2.2.  Someone did make a valiant
attempt, but they didn't quite get it.  Thanks to all of the
other people who have posted on this subject before (particularly
Bill Wells and Mayer Ilovitz), I was able to analyze the problem
and come up with a definitive fix.  The critical section of code
now looks something like:

	Read inodes into cache
	If cache not completely full then
		Set sentinal in cache
		Set place to start reading to inode 0
	If cache not empty, go allocate inode and return
	If the total number of free inodes == 0 or
	place to start reading is inode 0 then
		Out of inodes error
	Set place to start reading to inode 0
	Go read more inodes

Where this fails is when it reads all the way to the end of the
inode list without finding any free inodes to put in the cache.
Since the cache is not completely full, it sets the sentinal and
also sets the place to start reading to zero.  If there was at
least one inode found and put into the cache, it would go and
allocate it and, when the cache empties, it will start reading at
inode zero and hence find any other free inodes.  However, when
there were none found, even if there are still free inodes, it
thinks there aren't because the place to start reading is set to
zero.  The problem is not the test since, if it had really read
from inode zero without finding any free inodes, there aren't
any and the free inode count in the superblock is wrong.  The
problem is setting the place to start reading when the cache
isn't completely filled.  There's no reason to do it anymore
since the failure code sets it and rereads.  So the fix is to
simply remove that assignment.

So, here's how to fix it once and for all.  First, run the
following shell script to create /tmp/Driver.o and make sure that
it worked correctly.  Save a copy of your kernel and
/etc/conf/pack.d/s5/Driver.o.  Move /tmp/Driver.o to
/etc/conf/pack.d/s5/Driver.o and rebuild your kernel.  The inode
bug is now really and truely gone.

If anyone has problems, you can send me email and I'll try to
help out.

# ----- cut here -----
:
in=/etc/conf/pack.d/s5/Driver.o
out=/tmp/Driver.o

# check that we have the right Driver.o file

if [ x"`sum $in`" != x"24406 96 $in" ]; then
	echo "sum failed"
	exit 1
fi
if [ x"`sum -r $in`" != x"27711    96 $in" ]; then
	echo "sum -r failed"
	exit 1
fi

# copy the file and make an appropriate fix

{
	dd ibs=1 obs=1k count=2141
	dd bs=9 count=1 of=/dev/null
	echo '\0353\0007\0220\0220\0220\0220\0220\0220\0220\c'
	dd bs=16k
} <$in >$out

# compare the list of differences against the expected differences

cat <<\+ >/tmp/fix$$
  2142 146 353
  2143 307   7
  2144 207 220
  2145 326 220
  2146   0 220
  2147   0 220
  2148   0 220
  2149   0 220
  2150   0 220
+
if cmp -l $in $out | cmp -s - /tmp/fix$$; then
	rm /tmp/fix$$
	exit 0
else
	rm /tmp/fix$$
	echo "patch failed"
	exit 1
fi
----
Larry Jones                         UUCP: uunet!sdrc!thor!scjones
SDRC                                      scjones at thor.UUCP
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"This probably just goes to show something, but I sure don't know what."
-Calvin



More information about the Comp.unix.sysv386 mailing list