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

Reply via email to