Another fix for the SYSV inode problem
T. William Wells
bill at twwells.uucp
Mon Jan 30 00:01:28 AEST 1989
Two things happened today (really yesterday, but this fix took all
night): first, my system crashed twice due to the inode bug, and
second, I received Jim Valerio's stuff on fixing the inode problem for
System V/386 Release 3. I'm running Microport's 3.0e; and here is
what is going on.
S5ialloc (aka ialloc) has a bug. It seems that the code is dependent
on the condition that the inode cache always contains the lowest free
inode. This is a condition that just can't be met.
Jim Valerio's fix is to always scan the inode list when the cache
runs out. I didn't like that; my system is already disk-bound and I
don't want to add more load on the disk, so I disassembled the code
and found a fix. My fix is to ignore a failure to read inodes and
try again. This has the advantage of not requiring a rescan except
when the inode pointer gets screwed up.
The following is relevant code from the disassembly:
define(`NICINOD', 100)
define(`s_ninode', 212(%edi)) # short number of i-nodes in s_inode
define(`s_inode', 214(%edi)) # ushort free i-node list
define(`s_tinode', 436(%edi)) # ushort total free inodes
.readinodes: .0xFC
movw s_tinode,%ax / check to see that there are some free inodes
testw %ax,%ax
je .noinodes / no, branch to the error handler
movw $NICINOD,s_ninode / this is the number of inodes we can read
movzwl s_inode,%eax / the first inode to read from the disk
...
.0x209:
movw s_ninode,%ax / did we get enough inodes for the cache?
testw %ax,%ax
jle .0x236 / yes, proceed
leal s_inode,%eax / this is the address of the inode table
movswl s_ninode,%edx / this is how many inodes we couldn't get
decl %edx / stick a zero before the inodes to force
movw $0,(%eax,%edx,2) / a reread when they are all used up
movw $0,s_inode / zero the first inode in the cache
.0x236:
movswl s_ninode,%eax / if no inodes were read into the cache
cmpl $NICINOD,%eax
je .noinodes / fail due to lack no inodes
movw $NICINOD,s_ninode / otherwise set the cache pointer to its end
jmp .0x2C5 / and then go back to allocating
---
Note these two key facts:
1) .readinodes checks s_tinode before reading from the disk.
2) If nothing gets put into the cache, the first entry of s_inode
is zeroed.
Therefore, if the last `je .noinodes' is changed to `je .readinodes',
the bug goes away! Does anyone see any problem with this patch?
---
On my system, I patched s5.o (/etc/atconf/modules/s5/s5.o) with the
following:
adb -w s5.o <<+
s5ialloc+244?W0fffffeb4
+
REMEMBER. MAKE A BACKUP COPY OF S5.O AND VERIFY THAT THE CODE LOOKS
SOMETHING LIKE MINE!!!!
Then rebuild your kernel. All kernels made after this change will
have the fix.
---
Bill
{ uunet!proxftl | novavax } !twwells!bill
More information about the Comp.unix.microport
mailing list