lock status of dvp in lookup error return?
Benjamin Kaduk
kaduk at MIT.EDU
Wed Oct 19 14:53:52 UTC 2011
On Wed, 19 Oct 2011, Kostik Belousov wrote:
> On Wed, Oct 19, 2011 at 02:07:17AM -0400, Benjamin Kaduk wrote:
>> 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);
> Did you missed line 1234 ?
>
> The code is the copy of the vn_vget_ino(). The logic in the function
> might be slightly easier to follow.
Ah, I did miss that, thanks.
Maybe 0200h is not the best time to do these things ...
-Ben
More information about the freebsd-fs
mailing list