[comp.bugs.sys5] Free inode-list exhaustion

awy@concurrent.co.uk (Alan Young) (01/16/89)

Some time ago (about a year) there was considerable discussion about a
problem with exhaustion of the free-inode list of a mounted file system.
This was most commonly observed on file systems supporting Usenet News. 
As I recall the basis of the problem was a flaw in the algorithm for
refreshing the in-core free list from the disk and that this was only
exercised on file systems with a high turnover of inodes. 

I need to fix this.  I believe that the original discussion included
source fixes to the relevant kernel module.  Would some knowledgeable
soul please enlighten me, preferably by e-mail. 

wescott@sauron.Columbia.NCR.COM (Mike Wescott) (01/17/89)

In article <778@sl10c.concurrent.co.uk> Alan Young <awy@concurrent.co.uk> writes:
> Some time ago (about a year) there was considerable discussion about a
> problem with exhaustion of the free-inode list of a mounted file system.
> This was most commonly observed on file systems supporting Usenet News. 
> As I recall the basis of the problem was a flaw in the algorithm for
> refreshing the in-core free list from the disk and that this was only
> exercised on file systems with a high turnover of inodes. 

Correct.  The following diff should be of some help.  Your line numbers
will certainly not be the same.  The fix shown here is to rescan the whole
inode list whenever it runs out.  The code fragments are from a V.2.2
port with the fix vs V.2.2 for the VAX.

*** /tmp/alloc.c.orig	Tue Jan 17 10:28:36 1989
--- /tmp/alloc.c	Tue Jan 17 10:28:07 1989
***************
*** 187,192 ****
--- 231,238 ----
  		goto loop;
  	}
  	fp->s_ilock++;
+ 
+ again:	/* come back here if necessary to re-search from beginning */
  	fp->s_ninode = NICINOD;
  	ino = FsINOS(dev, fp->s_inode[0]);
  	for(adr = FsITOD(dev, ino); adr < fp->s_isize; adr++) {
***************
*** 207,212 ****
--- 253,267 ----
  		if (fp->s_ninode <= 0)
  			break;
  	}
+ 	/*
+ 	 *	If we didn't find any and we didn't start at the beginning,
+ 	 *	look again starting at the beginning
+ 	 */
+ 	if (fp->s_ninode == NICINOD && fp->s_inode[0] != 0) {
+ 		fp->s_inode[0] = 0;
+ 		goto again;
+ 	}
+ 
  	fp->s_ilock = 0;
  	wakeup((caddr_t)&fp->s_ilock);
  	if (fp->s_ninode > 0) {
-- 
	-Mike Wescott
	 mike.wescott@ncrcae.Columbia.NCR.COM

jimv@radix (Jim Valerio) (01/19/89)

In article <1525@sauron.Columbia.NCR.COM> wescott@sauron.Columbia.NCR.COM
(Mike Wescott) supplies a source code fix for the free-inode bug in the
System V filesystem.  I have effectively the same workaround available as
a binary patch, if you're running a 386 AT-style System V Release 3.

The patch is applied by a program which creates a modified /unix.  I've been
running this patch for well over a month now, and I am certain that it has
solved the free-inode bug (which used to hit my system as often as several
times a day).

The downside here is that the program which applies the patch is really a
hack I threw together quite some time ago to apply a number of bug fixes to
a pre-release of Sys V Rel 3.0.  (I've toyed with the idea of turning this
into a generalized SysVr3/386 patching utility, but I've never simulataneously
had the time and energy.)  However, if you're suffering from this problem
and feel comfortable with potentially modifying the patch program to apply
the patch to your system, I'd be happy to send you the program.
--
Jim Valerio	{verdix,tektronix,omepd}!radix!jimv, jimv@omepd.intel.com