abe@j.cc.purdue.edu (Vic Abell) (10/10/86)
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