mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-11 14:10:34 +00:00
- Apply a big giant lock around the namecache. This has been sitting in
my tree since BSDcon.
This commit is contained in:
parent
bdcfcdecea
commit
98d7d155c1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=120792
@ -113,6 +113,12 @@ SYSCTL_ULONG(_debug, OID_AUTO, numcachepl, CTLFLAG_RD, &numcachepl, 0, "");
|
|||||||
#endif
|
#endif
|
||||||
struct nchstats nchstats; /* cache effectiveness statistics */
|
struct nchstats nchstats; /* cache effectiveness statistics */
|
||||||
|
|
||||||
|
struct mtx cache_lock;
|
||||||
|
MTX_SYSINIT(vfscache, &cache_lock, "Name Cache", MTX_DEF);
|
||||||
|
|
||||||
|
#define CACHE_LOCK() mtx_lock(&cache_lock)
|
||||||
|
#define CACHE_UNLOCK() mtx_unlock(&cache_lock)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UMA zones for the VFS cache.
|
* UMA zones for the VFS cache.
|
||||||
*
|
*
|
||||||
@ -166,7 +172,7 @@ SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD, &nchstats,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void cache_zap(struct namecache *ncp);
|
static void cache_zap(struct namecache *ncp, int locked);
|
||||||
|
|
||||||
static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
|
static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
|
||||||
|
|
||||||
@ -261,13 +267,19 @@ SYSCTL_PROC(_debug_hashstat, OID_AUTO, nchash, CTLTYPE_INT|CTLFLAG_RD,
|
|||||||
* pointer to a vnode or if it is just a negative cache entry.
|
* pointer to a vnode or if it is just a negative cache entry.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
cache_zap(ncp)
|
cache_zap(ncp, locked)
|
||||||
struct namecache *ncp;
|
struct namecache *ncp;
|
||||||
|
int locked;
|
||||||
{
|
{
|
||||||
|
struct vnode *vp;
|
||||||
|
|
||||||
|
vp = NULL;
|
||||||
|
if (!locked)
|
||||||
|
CACHE_LOCK();
|
||||||
LIST_REMOVE(ncp, nc_hash);
|
LIST_REMOVE(ncp, nc_hash);
|
||||||
LIST_REMOVE(ncp, nc_src);
|
LIST_REMOVE(ncp, nc_src);
|
||||||
if (LIST_EMPTY(&ncp->nc_dvp->v_cache_src)) {
|
if (LIST_EMPTY(&ncp->nc_dvp->v_cache_src)) {
|
||||||
vdrop(ncp->nc_dvp);
|
vp = ncp->nc_dvp;
|
||||||
numcachehv--;
|
numcachehv--;
|
||||||
}
|
}
|
||||||
if (ncp->nc_vp) {
|
if (ncp->nc_vp) {
|
||||||
@ -277,7 +289,12 @@ cache_zap(ncp)
|
|||||||
numneg--;
|
numneg--;
|
||||||
}
|
}
|
||||||
numcache--;
|
numcache--;
|
||||||
|
CACHE_UNLOCK();
|
||||||
cache_free(ncp);
|
cache_free(ncp);
|
||||||
|
if (vp)
|
||||||
|
vdrop(vp);
|
||||||
|
if (locked)
|
||||||
|
CACHE_LOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -294,15 +311,21 @@ int
|
|||||||
cache_leaf_test(struct vnode *vp)
|
cache_leaf_test(struct vnode *vp)
|
||||||
{
|
{
|
||||||
struct namecache *ncpc;
|
struct namecache *ncpc;
|
||||||
|
int leaf;
|
||||||
|
|
||||||
|
leaf = 0;
|
||||||
|
CACHE_LOCK();
|
||||||
for (ncpc = LIST_FIRST(&vp->v_cache_src);
|
for (ncpc = LIST_FIRST(&vp->v_cache_src);
|
||||||
ncpc != NULL;
|
ncpc != NULL;
|
||||||
ncpc = LIST_NEXT(ncpc, nc_src)
|
ncpc = LIST_NEXT(ncpc, nc_src)
|
||||||
) {
|
) {
|
||||||
if (ncpc->nc_vp != NULL && ncpc->nc_vp->v_type == VDIR)
|
if (ncpc->nc_vp != NULL && ncpc->nc_vp->v_type == VDIR) {
|
||||||
return(-1);
|
leaf = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
CACHE_UNLOCK();
|
||||||
|
return (leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -330,12 +353,14 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CACHE_LOCK();
|
||||||
numcalls++;
|
numcalls++;
|
||||||
|
|
||||||
if (cnp->cn_nameptr[0] == '.') {
|
if (cnp->cn_nameptr[0] == '.') {
|
||||||
if (cnp->cn_namelen == 1) {
|
if (cnp->cn_namelen == 1) {
|
||||||
*vpp = dvp;
|
*vpp = dvp;
|
||||||
dothits++;
|
dothits++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
|
if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') {
|
||||||
@ -343,9 +368,11 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
if (dvp->v_dd->v_id != dvp->v_ddid ||
|
if (dvp->v_dd->v_id != dvp->v_ddid ||
|
||||||
(cnp->cn_flags & MAKEENTRY) == 0) {
|
(cnp->cn_flags & MAKEENTRY) == 0) {
|
||||||
dvp->v_ddid = 0;
|
dvp->v_ddid = 0;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
*vpp = dvp->v_dd;
|
*vpp = dvp->v_dd;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,6 +394,7 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
nummiss++;
|
nummiss++;
|
||||||
}
|
}
|
||||||
nchstats.ncs_miss++;
|
nchstats.ncs_miss++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,7 +402,8 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
if ((cnp->cn_flags & MAKEENTRY) == 0) {
|
if ((cnp->cn_flags & MAKEENTRY) == 0) {
|
||||||
numposzaps++;
|
numposzaps++;
|
||||||
nchstats.ncs_badhits++;
|
nchstats.ncs_badhits++;
|
||||||
cache_zap(ncp);
|
CACHE_UNLOCK();
|
||||||
|
cache_zap(ncp, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,6 +412,7 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
numposhits++;
|
numposhits++;
|
||||||
nchstats.ncs_goodhits++;
|
nchstats.ncs_goodhits++;
|
||||||
*vpp = ncp->nc_vp;
|
*vpp = ncp->nc_vp;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +420,8 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
if (cnp->cn_nameiop == CREATE) {
|
if (cnp->cn_nameiop == CREATE) {
|
||||||
numnegzaps++;
|
numnegzaps++;
|
||||||
nchstats.ncs_badhits++;
|
nchstats.ncs_badhits++;
|
||||||
cache_zap(ncp);
|
CACHE_UNLOCK();
|
||||||
|
cache_zap(ncp, 0);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,6 +437,7 @@ cache_lookup(dvp, vpp, cnp)
|
|||||||
nchstats.ncs_neghits++;
|
nchstats.ncs_neghits++;
|
||||||
if (ncp->nc_flag & NCF_WHITE)
|
if (ncp->nc_flag & NCF_WHITE)
|
||||||
cnp->cn_flags |= ISWHITEOUT;
|
cnp->cn_flags |= ISWHITEOUT;
|
||||||
|
CACHE_UNLOCK();
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,6 +453,8 @@ cache_enter(dvp, vp, cnp)
|
|||||||
struct namecache *ncp;
|
struct namecache *ncp;
|
||||||
struct nchashhead *ncpp;
|
struct nchashhead *ncpp;
|
||||||
u_int32_t hash;
|
u_int32_t hash;
|
||||||
|
int hold;
|
||||||
|
int zap;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (!doingcache)
|
if (!doingcache)
|
||||||
@ -442,8 +476,10 @@ cache_enter(dvp, vp, cnp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hold = 0;
|
||||||
|
zap = 0;
|
||||||
ncp = cache_alloc(cnp->cn_namelen);
|
ncp = cache_alloc(cnp->cn_namelen);
|
||||||
/* XXX can uma_zalloc(..., M_WAITOK) fail? */
|
CACHE_LOCK();
|
||||||
numcache++;
|
numcache++;
|
||||||
if (!vp) {
|
if (!vp) {
|
||||||
numneg++;
|
numneg++;
|
||||||
@ -467,7 +503,7 @@ cache_enter(dvp, vp, cnp)
|
|||||||
ncpp = NCHHASH(hash);
|
ncpp = NCHHASH(hash);
|
||||||
LIST_INSERT_HEAD(ncpp, ncp, nc_hash);
|
LIST_INSERT_HEAD(ncpp, ncp, nc_hash);
|
||||||
if (LIST_EMPTY(&dvp->v_cache_src)) {
|
if (LIST_EMPTY(&dvp->v_cache_src)) {
|
||||||
vhold(dvp);
|
hold = 1;
|
||||||
numcachehv++;
|
numcachehv++;
|
||||||
}
|
}
|
||||||
LIST_INSERT_HEAD(&dvp->v_cache_src, ncp, nc_src);
|
LIST_INSERT_HEAD(&dvp->v_cache_src, ncp, nc_src);
|
||||||
@ -483,8 +519,13 @@ cache_enter(dvp, vp, cnp)
|
|||||||
}
|
}
|
||||||
if (numneg * ncnegfactor > numcache) {
|
if (numneg * ncnegfactor > numcache) {
|
||||||
ncp = TAILQ_FIRST(&ncneg);
|
ncp = TAILQ_FIRST(&ncneg);
|
||||||
cache_zap(ncp);
|
zap = 1;
|
||||||
}
|
}
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
if (hold)
|
||||||
|
vhold(dvp);
|
||||||
|
if (zap)
|
||||||
|
cache_zap(ncp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -522,16 +563,21 @@ SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL)
|
|||||||
* XXX: using the global v_id.
|
* XXX: using the global v_id.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX This is sometimes called when a vnode may still be re-used, in which
|
||||||
|
* case v_dd may be invalid. Need to look this up.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
cache_purge(vp)
|
cache_purge(vp)
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
{
|
{
|
||||||
static u_long nextid;
|
static u_long nextid;
|
||||||
|
|
||||||
|
CACHE_LOCK();
|
||||||
while (!LIST_EMPTY(&vp->v_cache_src))
|
while (!LIST_EMPTY(&vp->v_cache_src))
|
||||||
cache_zap(LIST_FIRST(&vp->v_cache_src));
|
cache_zap(LIST_FIRST(&vp->v_cache_src), 1);
|
||||||
while (!TAILQ_EMPTY(&vp->v_cache_dst))
|
while (!TAILQ_EMPTY(&vp->v_cache_dst))
|
||||||
cache_zap(TAILQ_FIRST(&vp->v_cache_dst));
|
cache_zap(TAILQ_FIRST(&vp->v_cache_dst), 1);
|
||||||
|
|
||||||
do
|
do
|
||||||
nextid++;
|
nextid++;
|
||||||
@ -539,6 +585,7 @@ cache_purge(vp)
|
|||||||
vp->v_id = nextid;
|
vp->v_id = nextid;
|
||||||
vp->v_dd = vp;
|
vp->v_dd = vp;
|
||||||
vp->v_ddid = 0;
|
vp->v_ddid = 0;
|
||||||
|
CACHE_UNLOCK();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -553,16 +600,25 @@ cache_purgevfs(mp)
|
|||||||
{
|
{
|
||||||
struct nchashhead *ncpp;
|
struct nchashhead *ncpp;
|
||||||
struct namecache *ncp, *nnp;
|
struct namecache *ncp, *nnp;
|
||||||
|
struct nchashhead mplist;
|
||||||
|
|
||||||
|
LIST_INIT(&mplist);
|
||||||
|
ncp = NULL;
|
||||||
|
|
||||||
/* Scan hash tables for applicable entries */
|
/* Scan hash tables for applicable entries */
|
||||||
|
CACHE_LOCK();
|
||||||
for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
|
for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) {
|
||||||
for (ncp = LIST_FIRST(ncpp); ncp != 0; ncp = nnp) {
|
for (ncp = LIST_FIRST(ncpp); ncp != 0; ncp = nnp) {
|
||||||
nnp = LIST_NEXT(ncp, nc_hash);
|
nnp = LIST_NEXT(ncp, nc_hash);
|
||||||
if (ncp->nc_dvp->v_mount == mp) {
|
if (ncp->nc_dvp->v_mount == mp) {
|
||||||
cache_zap(ncp);
|
LIST_REMOVE(ncp, nc_hash);
|
||||||
|
LIST_INSERT_HEAD(&mplist, ncp, nc_hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
while (!LIST_EMPTY(&mplist))
|
||||||
|
cache_zap(LIST_FIRST(&mplist), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -774,7 +830,6 @@ kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen)
|
|||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
slash_prefixed = 0;
|
slash_prefixed = 0;
|
||||||
FILEDESC_LOCK(fdp);
|
FILEDESC_LOCK(fdp);
|
||||||
mp_fixme("No vnode locking done!");
|
|
||||||
for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
|
for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
|
||||||
if (vp->v_vflag & VV_ROOT) {
|
if (vp->v_vflag & VV_ROOT) {
|
||||||
if (vp->v_mount == NULL) { /* forced unmount */
|
if (vp->v_mount == NULL) { /* forced unmount */
|
||||||
@ -791,37 +846,43 @@ kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen)
|
|||||||
free(tmpbuf, M_TEMP);
|
free(tmpbuf, M_TEMP);
|
||||||
return (ENOTDIR);
|
return (ENOTDIR);
|
||||||
}
|
}
|
||||||
|
CACHE_LOCK();
|
||||||
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
||||||
if (!ncp) {
|
if (!ncp) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numcwdfail2++;
|
numcwdfail2++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(tmpbuf, M_TEMP);
|
free(tmpbuf, M_TEMP);
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
if (ncp->nc_dvp != vp->v_dd) {
|
if (ncp->nc_dvp != vp->v_dd) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numcwdfail3++;
|
numcwdfail3++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(tmpbuf, M_TEMP);
|
free(tmpbuf, M_TEMP);
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
}
|
}
|
||||||
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
||||||
if (bp == tmpbuf) {
|
if (bp == tmpbuf) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numcwdfail4++;
|
numcwdfail4++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(tmpbuf, M_TEMP);
|
free(tmpbuf, M_TEMP);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
*--bp = ncp->nc_name[i];
|
*--bp = ncp->nc_name[i];
|
||||||
}
|
}
|
||||||
if (bp == tmpbuf) {
|
if (bp == tmpbuf) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numcwdfail4++;
|
numcwdfail4++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(tmpbuf, M_TEMP);
|
free(tmpbuf, M_TEMP);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
*--bp = '/';
|
*--bp = '/';
|
||||||
slash_prefixed = 1;
|
slash_prefixed = 1;
|
||||||
vp = vp->v_dd;
|
vp = vp->v_dd;
|
||||||
|
CACHE_UNLOCK();
|
||||||
}
|
}
|
||||||
FILEDESC_UNLOCK(fdp);
|
FILEDESC_UNLOCK(fdp);
|
||||||
if (!slash_prefixed) {
|
if (!slash_prefixed) {
|
||||||
@ -884,9 +945,9 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
|
|||||||
*bp = '\0';
|
*bp = '\0';
|
||||||
fdp = td->td_proc->p_fd;
|
fdp = td->td_proc->p_fd;
|
||||||
slash_prefixed = 0;
|
slash_prefixed = 0;
|
||||||
|
ASSERT_VOP_LOCKED(vn, "vn_fullpath");
|
||||||
FILEDESC_LOCK(fdp);
|
FILEDESC_LOCK(fdp);
|
||||||
for (vp = vn; vp != fdp->fd_rdir && vp != rootvnode;) {
|
for (vp = vn; vp != fdp->fd_rdir && vp != rootvnode;) {
|
||||||
ASSERT_VOP_LOCKED(vp, "vn_fullpath");
|
|
||||||
if (vp->v_vflag & VV_ROOT) {
|
if (vp->v_vflag & VV_ROOT) {
|
||||||
if (vp->v_mount == NULL) { /* forced unmount */
|
if (vp->v_mount == NULL) { /* forced unmount */
|
||||||
FILEDESC_UNLOCK(fdp);
|
FILEDESC_UNLOCK(fdp);
|
||||||
@ -898,46 +959,52 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
|
|||||||
}
|
}
|
||||||
if (vp != vn && vp->v_dd->v_id != vp->v_ddid) {
|
if (vp != vn && vp->v_dd->v_id != vp->v_ddid) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
FILEDESC_UNLOCK(fdp);
|
||||||
numfullpathfail1++;
|
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
|
numfullpathfail1++;
|
||||||
return (ENOTDIR);
|
return (ENOTDIR);
|
||||||
}
|
}
|
||||||
|
CACHE_LOCK();
|
||||||
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
ncp = TAILQ_FIRST(&vp->v_cache_dst);
|
||||||
if (!ncp) {
|
if (!ncp) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numfullpathfail2++;
|
numfullpathfail2++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
}
|
}
|
||||||
if (vp != vn && ncp->nc_dvp != vp->v_dd) {
|
if (vp != vn && ncp->nc_dvp != vp->v_dd) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numfullpathfail3++;
|
numfullpathfail3++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
return (EBADF);
|
return (EBADF);
|
||||||
}
|
}
|
||||||
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
for (i = ncp->nc_nlen - 1; i >= 0; i--) {
|
||||||
if (bp == buf) {
|
if (bp == buf) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numfullpathfail4++;
|
numfullpathfail4++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
*--bp = ncp->nc_name[i];
|
*--bp = ncp->nc_name[i];
|
||||||
}
|
}
|
||||||
if (bp == buf) {
|
if (bp == buf) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numfullpathfail4++;
|
numfullpathfail4++;
|
||||||
|
CACHE_UNLOCK();
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
*--bp = '/';
|
*--bp = '/';
|
||||||
slash_prefixed = 1;
|
slash_prefixed = 1;
|
||||||
vp = ncp->nc_dvp;
|
vp = ncp->nc_dvp;
|
||||||
|
CACHE_UNLOCK();
|
||||||
}
|
}
|
||||||
if (!slash_prefixed) {
|
if (!slash_prefixed) {
|
||||||
if (bp == buf) {
|
if (bp == buf) {
|
||||||
FILEDESC_UNLOCK(fdp);
|
|
||||||
numfullpathfail4++;
|
numfullpathfail4++;
|
||||||
|
FILEDESC_UNLOCK(fdp);
|
||||||
free(buf, M_TEMP);
|
free(buf, M_TEMP);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user