Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!wuarchive!uunet!sdrc!thor!scjones From: scjones@thor.UUCP (Larry Jones) Newsgroups: comp.unix.sysv386 Subject: Inode Bug Fix for ISC 2.2 (and probably 2.2.1) Message-ID: <110@thor.UUCP> Date: 9 Jan 91 21:52:27 GMT Organization: SDRC, Cincinnati Lines: 104 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@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