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);

Reply via email to