Hi,
The following diff removes LOCKLEAF from NDINIT. The code doesn't
doesn't need it: the returned vnode is released immediately. The
string path is built from the namei() call using REALPATH, during
directories traversal.
Without LOCKLEAF, calling vrele() only is enough if namei() found a
file, instead of calling VOP_UNLOCK() + vrele().
Comments or OK ?
--
Sebastien Marie
diff dca1bd8d5621788b92aad3f944ac9999965773e2
545f8aacd74a1f793d1289475eb1c3f84d649e06
blob - 840ea5453e13604cb38b6a5d580370053386ce71
blob + fe240bb520b142726f358dfec4eaf6f26de151c1
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -916,36 +916,35 @@ sys___realpath(struct proc *p, void *v, register_t *re
}
free(cwdbuf, M_TEMP, cwdlen);
}
/* find root "/" or "//" */
for (c = pathname; *c != '\0'; c++) {
if (*c != '/')
break;
}
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | SAVENAME | REALPATH,
- UIO_SYSSPACE, pathname, p);
+ NDINIT(&nd, LOOKUP, FOLLOW | SAVENAME | REALPATH, UIO_SYSSPACE,
+ pathname, p);
nd.ni_cnd.cn_rpbuf = rpbuf;
nd.ni_cnd.cn_rpi = strlen(rpbuf);
nd.ni_pledge = PLEDGE_RPATH;
nd.ni_unveil = UNVEIL_READ;
if ((error = namei(&nd)) != 0)
goto end;
- /* release lock and reference from namei */
- if (nd.ni_vp) {
- VOP_UNLOCK(nd.ni_vp);
+ /* release reference from namei */
+ if (nd.ni_vp)
vrele(nd.ni_vp);
- }
+
error = copyoutstr(nd.ni_cnd.cn_rpbuf, SCARG(uap, resolved),
MAXPATHLEN, NULL);
#ifdef KTRACE
if (KTRPOINT(p, KTR_NAMEI))
ktrnamei(p, nd.ni_cnd.cn_rpbuf);
#endif
pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
end:
pool_put(&namei_pool, rpbuf);