Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/smbfs Change smbfs from hashlist to vcache.
details: https://anonhg.NetBSD.org/src/rev/66ce0253e62d
branches: trunk
changeset: 335011:66ce0253e62d
user: hannken <hannken%NetBSD.org@localhost>
date: Sun Dec 21 10:48:53 2014 +0000
description:
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().
diffstat:
sys/fs/smbfs/smbfs.h | 5 +-
sys/fs/smbfs/smbfs_node.c | 249 +++++++++++++++++++------------------------
sys/fs/smbfs/smbfs_node.h | 21 ++-
sys/fs/smbfs/smbfs_smb.c | 6 +-
sys/fs/smbfs/smbfs_vfsops.c | 21 +--
sys/fs/smbfs/smbfs_vnops.c | 45 +------
6 files changed, 143 insertions(+), 204 deletions(-)
diffs (truncated from 602 to 300 lines):
diff -r b452115c880a -r 66ce0253e62d sys/fs/smbfs/smbfs.h
--- a/sys/fs/smbfs/smbfs.h Sat Dec 20 23:36:21 2014 +0000
+++ b/sys/fs/smbfs/smbfs.h Sun Dec 21 10:48:53 2014 +0000
@@ -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 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;
};
diff -r b452115c880a -r 66ce0253e62d sys/fs/smbfs/smbfs_node.c
--- a/sys/fs/smbfs/smbfs_node.c Sat Dec 20 23:36:21 2014 +0000
+++ b/sys/fs/smbfs/smbfs_node.c Sun Dec 21 10:48:53 2014 +0000
@@ -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 @@
#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 @@
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));
+
+ 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);
- cp = malloc(nmlen, M_SMBNODENAME, M_WAITOK);
- memcpy(cp, name, nmlen);
+ 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);
- return cp;
+ 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 inline void
-smbfs_name_free(u_char *name)
+int
+smbfs_nget(struct mount *mp, struct vnode *dvp, const char *name, int nmlen,
+ struct smbfattr *fap, struct vnode **vpp)
{
- free(name, M_SMBNODENAME);
-}
+ struct smbkey *key;
+ struct smbmount *smp __diagused;
+ struct smbnode *np;
+ struct vnode *vp;
+ union {
+ struct smbkey u_key;
+ char u_data[64];
+ } small_key;
+ int error;
+ const int key_len = SMBFS_KEYSIZE(nmlen);
-static int
-smbfs_node_alloc(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 vnode *vp;
- u_long hashval;
- int error;
+ 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 @@
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 @@
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;
- }
+ goto retry;
+ }
}
-
- 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;
- }
-
- 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);
Home |
Main Index |
Thread Index |
Old Index