Linus/Alan, please accept the following patch for knfsd in 2.4.0-prerelease. What it does is extend the protection offered by s_nfsd_free_path_sem to cover the first call to nfsd_iget. I had previously avoided this as I didn't think it was necessary and it ment that the semaphore wasn't claimed at all on the common path. However Chip Salzenberg managed to convince me that it is needed. I think that his case-in-point is mentioned towards the end of http://www.cnn.com/2001/TECH/computing/01/03/linux.mission.idg/index.html under "Taking the plunge". There is actually more that I would like to do to this code, but I don't think now is the right time. This is the minimal change that will fix a real bug. NeilBrown --- ./fs/nfsd/nfsfh.c 2001/01/04 00:09:13 1.1 +++ ./fs/nfsd/nfsfh.c 2001/01/04 00:09:37 1.2 @@ -346,7 +346,7 @@ struct dentry *dentry, *result = NULL; struct dentry *tmp; int found =0; - int err; + int err = -ESTALE; /* the sb->s_nfsd_free_path_sem semaphore is needed to make sure that only one unconnected (free) * dcache path ever exists, as otherwise two partial paths might get * joined together, which would be very confusing. @@ -360,19 +360,18 @@ * Attempt to find the inode. */ retry: + down(&sb->s_nfsd_free_path_sem); result = nfsd_iget(sb, ino, generation); - err = PTR_ERR(result); - if (IS_ERR(result)) - goto err_out; - err = -ESTALE; - if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) - return result; - - /* result is now an anonymous dentry, which may be adequate as it stands, or else - * will get spliced into the dcache tree */ - - if (!S_ISDIR(result->d_inode->i_mode) && ! needpath) { - nfsdstats.fh_anon++; + if (IS_ERR(result) + || !(result->d_flags & DCACHE_NFSD_DISCONNECTED) + || (!S_ISDIR(result->d_inode->i_mode) && ! needpath)) { + up(&sb->s_nfsd_free_path_sem); + + err = PTR_ERR(result); + if (IS_ERR(result)) + goto err_out; + if ((result->d_flags & DCACHE_NFSD_DISCONNECTED)) + nfsdstats.fh_anon++; return result; } @@ -380,14 +379,6 @@ * location in the tree. */ dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino); - down(&sb->s_nfsd_free_path_sem); - - /* claiming the semaphore might have allowed things to get fixed up */ - if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { - up(&sb->s_nfsd_free_path_sem); - return result; - } - found = 0; if (!S_ISDIR(result->d_inode->i_mode)) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] Please read the FAQ at http://www.tux.org/lkml/