2.9BSD inode locking fix

Vic Abell abe at j.cc.purdue.edu
Sat Oct 11 06:52:18 AEST 1986


Here is a fix to an inode locking problem in 2.9BSD that occurs when
you have UCB_SYMLINKS defined and do not have UCB_QUOTAS defined.  The
bug is revealed by /etc/fsck as unreferenced inodes.  The unreferenced
inodes are created when two processes are trying to create a file in
the same directory, and a third process is issuing lstat() calls on
the directory (e. g., "ls -l").  The lstat() can release a directory
inode lock, held by one of the creat() or link() callers that may be
sleeping for some other resource, allowing the other creat()/link()
caller to spot and record the same open slot in the directory.  The
last of the two to write in the directory will cause the first one's
directory entry to be overwritten and lost.

In finding this bug I spotted and corrected several other minor problems
in nami.c, bio.c, sys2.c and sys3.c.  There are other places in nami.c
(namei() and symbolic links) and sys2.c (link() and the existing file
inode lock) where an iput() should be avoided if someone else has acquired
the inode lock during a sleep.  Bio.c has some incorrect interrupt blocking
when manipulating the hash list.  Sys3.c fails to use a function symbol
when calling namei().  These less important fixes can be obtained from Greg
Travis at ISR <isrnix!greg> or via anonymous/guest ftp to j.cc.purdue.edu
or asc.purdue.edu in the directory pub/BSD2_9.

Vic Abell


=========================================================
fix to namei() in nami.c to correct inode locking problem
=========================================================

----- old ------------------------------------------------
		#ifndef UCB_QUOTAS
			else {
wrong! =========>		iput(dp);
				dp = (struct inode *)temp;
			}
		#endif	not UCB_QUOTAS

----- new ------------------------------------------------
		#ifndef UCB_QUOTAS
			else {
correct ========>		if (dp->i_flag & ILOCK)
correct ========>			dp->i_count--;
correct ========>		else
correct ========>			iput(dp);
				dp = (struct inode *)temp;
			}
		#endif	not UCB_QUOTAS



More information about the Comp.bugs.2bsd mailing list