Module Name: src
Committed By: hannken
Date: Sun Dec 21 10:48:53 UTC 2014
Modified Files:
src/sys/fs/smbfs: smbfs.h smbfs_node.c smbfs_node.h smbfs_smb.c
smbfs_vfsops.c smbfs_vnops.c
Log Message:
Change smbfs from hashlist to vcache.
- Use (parent_vnode, name, name_len) as key.
- Change smbfs_nget() to return a referenced but unlocked vnode and
adapt smbfs_setroot(), smbfs_create(), smbfs_mkdir() and smbfs_lookup().
To generate a diff of this commit:
cvs rdiff -u -r1.17 -r1.18 src/sys/fs/smbfs/smbfs.h
cvs rdiff -u -r1.52 -r1.53 src/sys/fs/smbfs/smbfs_node.c
cvs rdiff -u -r1.13 -r1.14 src/sys/fs/smbfs/smbfs_node.h
cvs rdiff -u -r1.46 -r1.47 src/sys/fs/smbfs/smbfs_smb.c
cvs rdiff -u -r1.103 -r1.104 src/sys/fs/smbfs/smbfs_vfsops.c
cvs rdiff -u -r1.92 -r1.93 src/sys/fs/smbfs/smbfs_vnops.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/fs/smbfs/smbfs.h
diff -u src/sys/fs/smbfs/smbfs.h:1.17 src/sys/fs/smbfs/smbfs.h:1.18
--- src/sys/fs/smbfs/smbfs.h:1.17 Sun Sep 7 13:13:04 2008
+++ src/sys/fs/smbfs/smbfs.h Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs.h,v 1.17 2008/09/07 13:13:04 tron Exp $ */
+/* $NetBSD: smbfs.h,v 1.18 2014/12/21 10:48:53 hannken Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@@ -82,9 +82,6 @@ struct smbmount {
struct smb_share * sm_share;
struct smbnode * sm_npstack[SMBFS_MAXPATHCOMP];
int sm_caseopt;
- kmutex_t sm_hashlock;
- LIST_HEAD(smbnode_hashhead, smbnode) *sm_hash;
- u_long sm_hashlen;
int sm_didrele;
};
Index: src/sys/fs/smbfs/smbfs_node.c
diff -u src/sys/fs/smbfs/smbfs_node.c:1.52 src/sys/fs/smbfs/smbfs_node.c:1.53
--- src/sys/fs/smbfs/smbfs_node.c:1.52 Tue Nov 25 12:33:13 2014
+++ src/sys/fs/smbfs/smbfs_node.c Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.c,v 1.52 2014/11/25 12:33:13 nakayama Exp $ */
+/* $NetBSD: smbfs_node.c,v 1.53 2014/12/21 10:48:53 hannken Exp $ */
/*
* Copyright (c) 2000-2001 Boris Popov
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.52 2014/11/25 12:33:13 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_node.c,v 1.53 2014/12/21 10:48:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -62,10 +62,6 @@ __KERNEL_RCSID(0, "$NetBSD: smbfs_node.c
#include <fs/smbfs/smbfs_node.h>
#include <fs/smbfs/smbfs_subr.h>
-#define SMBFS_NOHASH(smp, hval) (&(smp)->sm_hash[(hval) & (smp)->sm_hashlen])
-
-MALLOC_JUSTDEFINE(M_SMBNODENAME, "SMBFS nname", "SMBFS node name");
-
extern int (**smbfs_vnodeop_p)(void *);
extern int prtactive;
@@ -75,37 +71,58 @@ static const struct genfs_ops smbfs_genf
struct pool smbfs_node_pool;
-static inline char *
-smbfs_name_alloc(const u_char *name, int nmlen)
+int
+smbfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
{
- u_char *cp;
+ struct smbnode *np;
+
+ np = pool_get(&smbfs_node_pool, PR_WAITOK);
+ memset(np, 0, sizeof(*np));
- cp = malloc(nmlen, M_SMBNODENAME, M_WAITOK);
- memcpy(cp, name, nmlen);
+ vp->v_tag = VT_SMBFS;
+ vp->v_op = smbfs_vnodeop_p;
+ vp->v_type = VNON;
+ vp->v_data = np;
+ genfs_node_init(vp, &smbfs_genfsops);
- return cp;
-}
+ mutex_init(&np->n_lock, MUTEX_DEFAULT, IPL_NONE);
+ np->n_key = kmem_alloc(key_len, KM_SLEEP);
+ memcpy(np->n_key, key, key_len);
+ KASSERT(key_len == SMBFS_KEYSIZE(np->n_nmlen));
+ np->n_vnode = vp;
+ np->n_mount = VFSTOSMBFS(mp);
-static inline void
-smbfs_name_free(u_char *name)
-{
- free(name, M_SMBNODENAME);
+ if (np->n_parent != NULL && (np->n_parent->v_vflag & VV_ROOT) == 0) {
+ vref(np->n_parent);
+ np->n_flag |= NREFPARENT;
+ }
+
+ *new_key = np->n_key;
+
+ return 0;
}
-static int
-smbfs_node_alloc(struct mount *mp, struct vnode *dvp,
- const char *name, int nmlen, struct smbfattr *fap, struct vnode **vpp)
+int
+smbfs_nget(struct mount *mp, struct vnode *dvp, const char *name, int nmlen,
+ struct smbfattr *fap, struct vnode **vpp)
{
- struct vattr vattr;
- struct smbmount *smp = VFSTOSMBFS(mp);
- struct smbnode_hashhead *nhpp;
- struct smbnode *np, *np2;
+ struct smbkey *key;
+ struct smbmount *smp __diagused;
+ struct smbnode *np;
struct vnode *vp;
- u_long hashval;
+ union {
+ struct smbkey u_key;
+ char u_data[64];
+ } small_key;
int error;
+ const int key_len = SMBFS_KEYSIZE(nmlen);
+
+ smp = VFSTOSMBFS(mp);
/* do not allow allocating root vnode twice */
KASSERT(dvp != NULL || smp->sm_root == NULL);
+
/* do not call with dot */
KASSERT(nmlen != 1 || name[0] != '.');
@@ -114,11 +131,8 @@ smbfs_node_alloc(struct mount *mp, struc
return EINVAL;
vp = VTOSMB(VTOSMB(dvp)->n_parent)->n_vnode;
vref(vp);
- if ((error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY)) == 0)
- *vpp = vp;
- else
- vrele(vp);
- return (error);
+ *vpp = vp;
+ return 0;
}
#ifdef DIAGNOSTIC
@@ -126,121 +140,71 @@ smbfs_node_alloc(struct mount *mp, struc
if (dnp == NULL && dvp != NULL)
panic("smbfs_node_alloc: dead parent vnode %p", dvp);
#endif
- hashval = smbfs_hash(name, nmlen);
+
+ if (key_len > sizeof(small_key))
+ key = kmem_alloc(key_len, KM_SLEEP);
+ else
+ key = &small_key.u_key;
+ key->k_parent = dvp;
+ key->k_nmlen = nmlen;
+ memcpy(key->k_name, name, nmlen);
+
retry:
- mutex_enter(&smp->sm_hashlock);
- nhpp = SMBFS_NOHASH(smp, hashval);
- LIST_FOREACH(np, nhpp, n_hash) {
- if (np->n_parent != dvp
- || np->n_nmlen != nmlen
- || memcmp(name, np->n_name, nmlen) != 0)
- continue;
- vp = SMBTOV(np);
- mutex_enter((vp)->v_interlock);
- mutex_exit(&smp->sm_hashlock);
- if (vget(vp, LK_EXCLUSIVE) != 0)
- goto retry;
+ error = vcache_get(mp, key, key_len, &vp);
+ if (error)
+ goto out;
+ mutex_enter(vp->v_interlock);
+ np = VTOSMB(vp);
+ KASSERT(np != NULL);
+ mutex_enter(&np->n_lock);
+ mutex_exit(vp->v_interlock);
+
+ if (vp->v_type == VNON) {
+ /*
+ * If we don't have node attributes, then it is an
+ * explicit lookup for an existing vnode.
+ */
+ if (fap == NULL) {
+ mutex_exit(&np->n_lock);
+ vrele(vp);
+ error = ENOENT;
+ goto out;
+ }
+ vp->v_type = fap->fa_attr & SMB_FA_DIR ? VDIR : VREG;
+ np->n_ino = fap->fa_ino;
+ np->n_size = fap->fa_size;
+
+ /* new file vnode has to have a parent */
+ KASSERT(vp->v_type != VREG || dvp != NULL);
+
+ uvm_vnp_setsize(vp, np->n_size);
+ } else {
+ struct vattr vattr;
+
/* Force cached attributes to be refreshed if stale. */
(void)VOP_GETATTR(vp, &vattr, curlwp->l_cred);
/*
* If the file type on the server is inconsistent with
* what it was when we created the vnode, kill the
- * bogus vnode now and fall through to the code below
- * to create a new one with the right type.
+ * bogus vnode now and retry to create a new one with
+ * the right type.
*/
if ((vp->v_type == VDIR && (np->n_dosattr & SMB_FA_DIR) == 0) ||
(vp->v_type == VREG && (np->n_dosattr & SMB_FA_DIR) != 0)) {
- VOP_UNLOCK(vp);
+ mutex_exit(&np->n_lock);
vgone(vp);
- goto allocnew;
- }
- *vpp = vp;
- return (0);
- }
- mutex_exit(&smp->sm_hashlock);
-
-allocnew:
- /*
- * If we don't have node attributes, then it is an explicit lookup
- * for an existing vnode.
- */
- if (fap == NULL)
- return ENOENT;
-
- np = pool_get(&smbfs_node_pool, PR_WAITOK);
- memset(np, 0, sizeof(*np));
-
- error = getnewvnode(VT_SMBFS, mp, smbfs_vnodeop_p, NULL, &vp);
- if (error) {
- pool_put(&smbfs_node_pool, np);
- return error;
- }
-
- if (dvp) {
- np->n_parent = dvp;
- if (/*vp->v_type == VDIR &&*/ (dvp->v_vflag & VV_ROOT) == 0) {
- vref(dvp);
- np->n_flag |= NREFPARENT;
- }
- }
-
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
-
- mutex_enter(&smp->sm_hashlock);
- /*
- * Check if the vnode wasn't added while we were in getnewvnode/
- * malloc.
- */
- LIST_FOREACH(np2, nhpp, n_hash) {
- if (np2->n_parent != dvp
- || np2->n_nmlen != nmlen
- || memcmp(name, np2->n_name, nmlen) != 0)
- continue;
- mutex_exit(&smp->sm_hashlock);
- if ((np->n_flag & NREFPARENT) != 0)
- vrele(dvp);
- ungetnewvnode(vp);
- pool_put(&smbfs_node_pool, np);
- goto retry;
+ goto retry;
+ }
}
-
- vp->v_type = fap->fa_attr & SMB_FA_DIR ? VDIR : VREG;
- vp->v_data = np;
- genfs_node_init(vp, &smbfs_genfsops);
-
- np->n_vnode = vp;
- np->n_mount = VFSTOSMBFS(mp);
- np->n_nmlen = nmlen;
- np->n_name = smbfs_name_alloc(name, nmlen);
- np->n_ino = fap->fa_ino;
- np->n_size = fap->fa_size;
-
- /* new file vnode has to have a parent */
- KASSERT(vp->v_type != VREG || dvp != NULL);
-
- /* Not on hash list, add it now */
- LIST_INSERT_HEAD(nhpp, np, n_hash);
- uvm_vnp_setsize(vp, np->n_size);
- mutex_exit(&smp->sm_hashlock);
-
- *vpp = vp;
- return 0;
-}
-
-int
-smbfs_nget(struct mount *mp, struct vnode *dvp, const char *name, int nmlen,
- struct smbfattr *fap, struct vnode **vpp)
-{
- struct vnode *vp = NULL; /* XXX gcc 4.8: maybe-uninitialized */
- int error;
-
- error = smbfs_node_alloc(mp, dvp, name, nmlen, fap, &vp);
- if (error)
- return error;
if (fap)
smbfs_attr_cacheenter(vp, fap);
*vpp = vp;
- return 0;
+ mutex_exit(&np->n_lock);
+
+out:
+ if (key != &small_key.u_key)
+ kmem_free(key, key_len);
+ return error;
}
/*
@@ -263,22 +227,25 @@ smbfs_reclaim(void *v)
SMBVDEBUG("%.*s,%d\n", (int) np->n_nmlen, np->n_name, vp->v_usecount);
- mutex_enter(&smp->sm_hashlock);
-
dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ?
np->n_parent : NULL;
- LIST_REMOVE(np, n_hash);
-
if (smp->sm_root == np) {
SMBVDEBUG0("root vnode\n");
smp->sm_root = NULL;
}
+
+ vcache_remove(vp->v_mount, np->n_key, SMBFS_KEYSIZE(np->n_nmlen));
+
genfs_node_destroy(vp);
+
+ /* To interlock with smbfs_nget(). */
+ mutex_enter(vp->v_interlock);
vp->v_data = NULL;
- mutex_exit(&smp->sm_hashlock);
- if (np->n_name)
- smbfs_name_free(np->n_name);
+ mutex_exit(vp->v_interlock);
+
+ mutex_destroy(&np->n_lock);
+ kmem_free(np->n_key, SMBFS_KEYSIZE(np->n_nmlen));
pool_put(&smbfs_node_pool, np);
if (dvp) {
vrele(dvp);
@@ -323,7 +290,7 @@ smbfs_inactive(void *v)
np->n_flag &= ~NOPEN;
smbfs_attr_cacheremove(vp);
}
- *ap->a_recycle = ((np->n_flag & NGONE) != 0);
+ *ap->a_recycle = ((vp->v_type == VNON) || (np->n_flag & NGONE) != 0);
VOP_UNLOCK(vp);
return (0);
Index: src/sys/fs/smbfs/smbfs_node.h
diff -u src/sys/fs/smbfs/smbfs_node.h:1.13 src/sys/fs/smbfs/smbfs_node.h:1.14
--- src/sys/fs/smbfs/smbfs_node.h:1.13 Wed Nov 28 13:34:24 2012
+++ src/sys/fs/smbfs/smbfs_node.h Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_node.h,v 1.13 2012/11/28 13:34:24 nakayama Exp $ */
+/* $NetBSD: smbfs_node.h,v 1.14 2014/12/21 10:48:53 hannken Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@@ -54,10 +54,19 @@
struct smbfs_fctx;
+#define SMBFS_KEYSIZE(nmlen) (sizeof(struct smbkey) + (nmlen))
+struct smbkey {
+ struct vnode * k_parent; /* Parent vnode. */
+ u_char k_nmlen; /* Name length. */
+ u_char k_name[0]; /* Name (variable length). */
+} __packed;
+
struct smbnode {
struct genfs_node n_gnode;
+ kmutex_t n_lock;
+ struct smbkey * n_key;
int n_flag;
- struct vnode * n_parent;
+#define n_parent n_key->k_parent
struct vnode * n_vnode;
struct smbmount * n_mount;
time_t n_attrage; /* attributes cache time */
@@ -70,12 +79,11 @@ struct smbnode {
int n_dosattr;
u_int16_t n_fid; /* file handle */
int n_rwstate; /* granted access mode */
- u_char n_nmlen;
- u_char * n_name;
+#define n_nmlen n_key->k_nmlen
+#define n_name n_key->k_name
struct smbfs_fctx * n_dirseq; /* ff context */
long n_dirofs; /* last ff offset */
struct lockf * n_lockf; /* Locking records of file */
- LIST_ENTRY(smbnode) n_hash;
};
#define VTOSMB(vp) ((struct smbnode *)(vp)->v_data)
@@ -85,9 +93,10 @@ struct smbfattr;
int smbfs_inactive(void *);
int smbfs_reclaim(void *);
+int smbfs_loadvnode(struct mount *, struct vnode *,
+ const void *, size_t, const void **);
int smbfs_nget(struct mount *, struct vnode *, const char *, int,
struct smbfattr *, struct vnode **);
-#define smbfs_hash(x, y) hash32_strn((x), (y), HASH32_STR_INIT)
int smbfs_readvnode(struct vnode *, struct uio *, kauth_cred_t);
int smbfs_writevnode(struct vnode *, struct uio *, kauth_cred_t, int);
Index: src/sys/fs/smbfs/smbfs_smb.c
diff -u src/sys/fs/smbfs/smbfs_smb.c:1.46 src/sys/fs/smbfs/smbfs_smb.c:1.47
--- src/sys/fs/smbfs/smbfs_smb.c:1.46 Sat Nov 15 18:52:44 2014
+++ src/sys/fs/smbfs/smbfs_smb.c Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_smb.c,v 1.46 2014/11/15 18:52:44 nakayama Exp $ */
+/* $NetBSD: smbfs_smb.c,v 1.47 2014/12/21 10:48:53 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_smb.c,v 1.46 2014/11/15 18:52:44 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_smb.c,v 1.47 2014/12/21 10:48:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -116,7 +116,7 @@ smbfs_getino(struct smbnode *dnp, const
#endif
u_int32_t ino;
- ino = dnp->n_ino + smbfs_hash(name, nmlen);
+ ino = dnp->n_ino + hash32_strn(name, nmlen, HASH32_STR_INIT);
if (ino <= 2)
ino += 3;
return ino;
Index: src/sys/fs/smbfs/smbfs_vfsops.c
diff -u src/sys/fs/smbfs/smbfs_vfsops.c:1.103 src/sys/fs/smbfs/smbfs_vfsops.c:1.104
--- src/sys/fs/smbfs/smbfs_vfsops.c:1.103 Mon Jul 14 16:29:50 2014
+++ src/sys/fs/smbfs/smbfs_vfsops.c Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_vfsops.c,v 1.103 2014/07/14 16:29:50 maxv Exp $ */
+/* $NetBSD: smbfs_vfsops.c,v 1.104 2014/12/21 10:48:53 hannken Exp $ */
/*
* Copyright (c) 2000-2001, Boris Popov
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.103 2014/07/14 16:29:50 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vfsops.c,v 1.104 2014/12/21 10:48:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -88,6 +88,7 @@ struct vfsops smbfs_vfsops = {
.vfs_statvfs = smbfs_statvfs,
.vfs_sync = smbfs_sync,
.vfs_vget = smbfs_vget,
+ .vfs_loadvnode = smbfs_loadvnode,
.vfs_fhtovp = (void *)eopnotsupp,
.vfs_vptofh = (void *)eopnotsupp,
.vfs_init = smbfs_init,
@@ -205,10 +206,6 @@ smbfs_mount(struct mount *mp, const char
smp = malloc(sizeof(*smp), M_SMBFSDATA, M_WAITOK|M_ZERO);
mp->mnt_data = smp;
- smp->sm_hash = hashinit(desiredvnodes, HASH_LIST, true,
- &smp->sm_hashlen);
-
- mutex_init(&smp->sm_hashlock, MUTEX_DEFAULT, IPL_NONE);
smp->sm_share = ssp;
smp->sm_root = NULL;
smp->sm_args = *args;
@@ -261,8 +258,6 @@ smbfs_unmount(struct mount *mp, int mntf
smb_share_put(smp->sm_share, &scred);
mp->mnt_data = NULL;
- hashdone(smp->sm_hash, HASH_LIST, smp->sm_hashlen);
- mutex_destroy(&smp->sm_hashlock);
free(smp, M_SMBFSDATA);
return 0;
}
@@ -295,14 +290,12 @@ smbfs_setroot(struct mount *mp)
* Someone might have already set sm_root while we slept
* in smb_lookup or vnode allocation.
*/
- if (smp->sm_root)
- vput(vp);
- else {
+ if (smp->sm_root) {
+ KASSERT(smp->sm_root == VTOSMB(vp));
+ vrele(vp);
+ } else {
vp->v_vflag |= VV_ROOT;
smp->sm_root = VTOSMB(vp);
-
- /* Keep reference, but unlock */
- VOP_UNLOCK(vp);
}
return (0);
Index: src/sys/fs/smbfs/smbfs_vnops.c
diff -u src/sys/fs/smbfs/smbfs_vnops.c:1.92 src/sys/fs/smbfs/smbfs_vnops.c:1.93
--- src/sys/fs/smbfs/smbfs_vnops.c:1.92 Fri Nov 7 12:05:58 2014
+++ src/sys/fs/smbfs/smbfs_vnops.c Sun Dec 21 10:48:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: smbfs_vnops.c,v 1.92 2014/11/07 12:05:58 nakayama Exp $ */
+/* $NetBSD: smbfs_vnops.c,v 1.93 2014/12/21 10:48:53 hannken Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.92 2014/11/07 12:05:58 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.93 2014/12/21 10:48:53 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -606,7 +606,6 @@ smbfs_create(void *v)
error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, ap->a_vpp);
if (error)
goto out;
- VOP_UNLOCK(*ap->a_vpp);
cache_enter(dvp, *ap->a_vpp, cnp->cn_nameptr, cnp->cn_namelen,
cnp->cn_flags);
@@ -809,7 +808,6 @@ smbfs_mkdir(void *v)
error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
if (error)
goto out;
- VOP_UNLOCK(vp);
*ap->a_vpp = vp;
out:
@@ -1347,46 +1345,23 @@ smbfs_lookup(void *v)
if (isdot)
return (EISDIR);
- if (flags & ISDOTDOT)
- VOP_UNLOCK(dvp);
error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp);
- if (flags & ISDOTDOT)
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
if (error)
return (error);
- if (*vpp != dvp)
- VOP_UNLOCK(*vpp);
return (0);
}
if (isdot) {
-
- /*
- * "." lookup
- */
vref(dvp);
*vpp = dvp;
- } else if (flags & ISDOTDOT) {
-
- /*
- * ".." lookup
- */
- VOP_UNLOCK(dvp);
- error = smbfs_nget(mp, dvp, name, nmlen, NULL, vpp);
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- if (error) {
- return error;
- }
+ error = 0;
} else {
- /*
- * Other lookups.
- */
- error = smbfs_nget(mp, dvp, name, nmlen, &fattr, vpp);
- if (error)
- return error;
+ error = smbfs_nget(mp, dvp, name, nmlen,
+ ((flags & ISDOTDOT) ? NULL : &fattr), vpp);
}
+ if (error)
+ return error;
- KASSERT(error == 0);
if (cnp->cn_nameiop != DELETE || !islastcn) {
VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_mtime.tv_sec;
cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
@@ -1399,7 +1374,5 @@ smbfs_lookup(void *v)
#endif
}
- if (*vpp != dvp)
- VOP_UNLOCK(*vpp);
return (0);
}