[comp.unix.sysv386] Inode Bug Fix for ISC 2.0.2

scjones@thor.UUCP (Larry Jones) (01/10/91)

Due to popular demand, here's the fix for ISC 2.0.2 as originally
posted by Bill Wells:

I made a similar patch for Microport SysV/386 3.0e and have been
running it for most of this year without problems. I was asked to
solve this for Interactive 2.0.2 and did so. However, I did the work
on my Microport system, and the enclosed shell script works on that;
it ought to work on an Interactive system but I've not tried this.

With that caveat, here is what you do to patch your kernel. First,
run the shell script. Make sure that it behaved correctly. Then save
a copy of your good kernel and /etc/conf/pack.d/s5/Driver.o. If you
are really paranoid, back up your whole system, though this shouldn't
be necessary. Replace the Driver.o file with the one on /tmp.
Finally, rebuild your kernel. That particular bug should never bite
you again. Further kernel builds will have the bug fixed as well. If
you have any problems, send me e-mail. I'll try to get back to you
quicker than I did with this! If the patch causes some nasty kind of
crash, please post immediately in hopes that others will read your
message before having tried the patch.

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"50880 81 $in" ]; then
	echo "sum failed"
	exit 1
fi
if [ x"`sum -r $in`" != x"33908    81 $in" ]; then
	echo "sum -r failed"
	exit 1
fi

# copy the file and make an appropriate fix

{
	dd ibs=1 obs=1k count=1977
	dd bs=19 count=1 of=/dev/null
	echo '\074\0144\017\0204\0327\0376\0377\0377\0146\c'
	echo '\0307\0207\0324\00\00\00\0144\00\0353\0151\c'
	dd bs=16k
} <$in >$out

# compare the list of differences against the expected differences

cat <<\+ >/tmp/fix$$
  1978  75  74
  1980   0  17
  1981   0 204
  1982   0 327
  1983 164 376
  1984  14 377
  1985 146 377
  1986 307 146
  1987 207 307
  1988 324 207
  1989   0 324
  1992 144   0
  1993   0 144
  1994 353   0
  1995 152 353
  1996 220 151
+
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

---
Bill                    { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com
----
Larry Jones                         UUCP: uunet!sdrc!thor!scjones
SDRC                                      scjones@thor.UUCP
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
This sounds suspiciously like one of Dad's plots to build my character.
-- Calvin

chris@alderan.uucp (Christoph Splittgerber) (01/15/91)

In article <109@thor.UUCP> scjones@thor.UUCP (Larry Jones) writes:
>Due to popular demand, here's the fix for ISC 2.0.2 as originally
>posted by Bill Wells:
>[]

First off all, thank you for the posting and for bringing some light
in this discussion.

I tried the patch for ISC 2.0.2 on two of our machines. On one machine
the script did run through without any errors. On the other machine
(ISC 2.0.2 as well but this license in newer) the script fails at the
checksum test.

>if [ x"`sum $in`" != x"50880 81 $in" ]; then
>	echo "sum failed"
>	exit 1
>fi
>if [ x"`sum -r $in`" != x"33908    81 $in" ]; then
>	echo "sum -r failed"
>	exit 1
>fi

Anyway, I removed this two checksum test, just to see what happens.
The script runs through and the "compare the list of differences
against the expected differences" passes without any problems.

So, what do you think ? Do you think the patch is ok anyway ?
Anyway, could some kind of soul tell me what the patch actually
does ?

    Thanks in advance,       Chris
-- 
************************ Brain fault (core dumped) *************************
Replies-To:  chris@alderan.uucp        UUCP: uunet!mcsun!unido!alderan!chris 
Phone:       +49 711 344375            Fax:  +49 711 3460684

scjones@thor.UUCP (Larry Jones) (01/18/91)

In article <285@alderan.uucp>, chris@alderan.uucp (Christoph Splittgerber) writes:
> I tried the patch for ISC 2.0.2 on two of our machines. On one machine
> the script did run through without any errors. On the other machine
> (ISC 2.0.2 as well but this license in newer) the script fails at the
> checksum test.
> 
> Anyway, I removed this two checksum test, just to see what happens.
> The script runs through and the "compare the list of differences
> against the expected differences" passes without any problems.
> 
> So, what do you think ? Do you think the patch is ok anyway ?

If the differences match the expected differences, the patch is
almost certainly successful.  Checksumming the file first (twice!)
is sort of a belt-and-suspenders approach to making sure that the
patch doesn't screw up someone's system.  If you verify that the
patch does work, perhaps you could post the checksums from your
system so that others with the save version of the code can use
the patch with less concern.

> Anyway, could some kind of soul tell me what the patch actually
> does ?

When you try to allocate an inode, the kernel code first looks at
the field in the file system superblock which records the number
of free inodes.  If this field is zero, then it writes an error
message to the console and returns a failure status.  Otherwise,
it looks at an in-core list of free inodes and, if the list is
not empty, it removes an element from the list and returns it.
If the list is empty, it scans the filesystem looking for free
inodes and adding any it finds to the in-core list until the
list is full or the end of the file system is reached.  If the
end of the file system in reached without finding any free inodes,
the code assumes that the free inode count in the superblock was
wrong and fails; otherwise, it returns a free inode as before.

Instead of always starting the scan at the first inode, there is
an optimization that keeps track of where to start scanning --
there should not be any free inodes before this point.  The bug
is that this condition is not correctly maintained -- it is
possible for there to be many free inodes before the starting
point.  What the 2.0.2 patch does is it changes what happens when
the scan fails -- instead of assuming that the free inode count
in the superblock was wrong, it assumes that it was right so it
resets the scan start point to the beginning of the file system
and redoes the scan.  Thus, if there are any free inodes, it will
find them.

There is a potential problem with this -- if the free inode count
in the superblock is greater than the true number of free inodes
and you really do allocate all of the inodes, the fixed code will
go into an infinite loop scanning for free inodes.  Since this is
kernel code, your system will be locked up until you reboot.  This
is almost certainly an acceptable trade-off, however, since the
bug is known to make the scan start point incorrect, but there are
no known bugs maintaining the free inode count.  The free inode
count can be corrupted by system crashes, but that almost always
causes the count to be too low (which is OK) rather than too high.

Note that the 2.2 patch does not have this problem -- the code
changes ISC made for 2.2 made it possible to have a completely
correct fix so that an incorrect inode count is detected and
reported rather than causing a loop.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH  45150-2789  513-576-2070
Domain: scjones@thor.UUCP  Path: uunet!sdrc!thor!scjones
Bad news, Mom.  I promised my soul to the Devil this afternoon. -- Calvin