lock status of dvp in lookup error return?
Benjamin Kaduk
kaduk at MIT.EDU
Wed Oct 19 06:07:21 UTC 2011
Hi Rick,
In tracking down a panic trying to recursively lock a vnode in openafs, I
started questioning my behavior in the ISDOTDOT case, in particular
whether to drop the dvp lock before the actual call over the network; this
naturally led me to look at the NFS code as a reference.
Unfortunately, this left me more confused than when I began ...
sys/fs/nfs_clvnops.c, in nfs_lookup():
1211 if (flags & ISDOTDOT) {
1212 ltype = NFSVOPISLOCKED(dvp);
1213 error = vfs_busy(mp, MBF_NOWAIT);
1214 if (error != 0) {
1215 vfs_ref(mp);
1216 NFSVOPUNLOCK(dvp, 0);
1217 error = vfs_busy(mp, 0);
1218 NFSVOPLOCK(dvp, ltype | LK_RETRY);
If we fail to busy the mountpoint, drop the directory lock and try again,
then relock dvp afterward.
1219 vfs_rel(mp);
1220 if (error == 0 && (dvp->v_iflag & VI_DOOMED)) {
1221 vfs_unbusy(mp);
1222 error = ENOENT;
1223 }
1224 if (error != 0)
1225 return (error);
But if the second vfs_busy failed, or dvp is DOOMED, return with dvp
locked.
1226 }
1227 NFSVOPUNLOCK(dvp, 0);
But now we always unlock dvp.
1228 error = nfscl_nget(mp, dvp, nfhp, cnp, td, &np, NULL,
1229 cnp->cn_lkflags);
The call to the network (?)
1230 if (error == 0)
1231 newvp = NFSTOV(np);
1232 vfs_unbusy(mp);
1233 if (newvp != dvp)
1234 NFSVOPLOCK(dvp, ltype | LK_RETRY);
1235 if (dvp->v_iflag & VI_DOOMED) {
1236 if (error == 0) {
1237 if (newvp == dvp)
1238 vrele(newvp);
1239 else
1240 vput(newvp);
1241 }
1242 error = ENOENT;
1243 }
1244 if (error != 0)
1245 return (error);
And here if there was an error hearing from the network, we return with
dvp still unlocked.
1246 if (attrflag)
1247 (void) nfscl_loadattrcache(&newvp, &nfsva, NULL, NULL,
1248 0, 1);
So, I'm still confused about whether I should be unlocking dvp in the
error case for ISDOTDOT (though presumably looking at other filesystems
would help). This inconsistency in the NFS client looks like a bug at my
current level of understanding -- what do you think?
Thanks,
Ben Kaduk
More information about the freebsd-fs
mailing list