Module Name:    src
Committed By:   hannken
Date:           Sun Aug 10 08:53:22 UTC 2014

Modified Files:
        src/sys/fs/hfs: files.hfs hfs.h hfs_vfsops.c hfs_vnops.c
        src/sys/modules/hfs: Makefile
        src/sys/rump/fs/lib/libhfs: Makefile
Removed Files:
        src/sys/fs/hfs: hfs_nhash.c

Log Message:
Change hfs from hashlist to vcache.
- use (cnid, fork) as key.
- use pool for hfs nodes.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/fs/hfs/files.hfs
cvs rdiff -u -r1.8 -r1.9 src/sys/fs/hfs/hfs.h
cvs rdiff -u -r1.13 -r0 src/sys/fs/hfs/hfs_nhash.c
cvs rdiff -u -r1.31 -r1.32 src/sys/fs/hfs/hfs_vfsops.c
cvs rdiff -u -r1.30 -r1.31 src/sys/fs/hfs/hfs_vnops.c
cvs rdiff -u -r1.1 -r1.2 src/sys/modules/hfs/Makefile
cvs rdiff -u -r1.3 -r1.4 src/sys/rump/fs/lib/libhfs/Makefile

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/hfs/files.hfs
diff -u src/sys/fs/hfs/files.hfs:1.2 src/sys/fs/hfs/files.hfs:1.3
--- src/sys/fs/hfs/files.hfs:1.2	Tue Mar  6 11:28:47 2007
+++ src/sys/fs/hfs/files.hfs	Sun Aug 10 08:53:22 2014
@@ -1,8 +1,7 @@
-#	$NetBSD: files.hfs,v 1.2 2007/03/06 11:28:47 dillo Exp $
+#	$NetBSD: files.hfs,v 1.3 2014/08/10 08:53:22 hannken Exp $
 
 deffs	HFS
 
-file	fs/hfs/hfs_nhash.c	hfs
 file	fs/hfs/hfs_subr.c	hfs
 file	fs/hfs/hfs_vfsops.c	hfs
 file	fs/hfs/hfs_vnops.c	hfs

Index: src/sys/fs/hfs/hfs.h
diff -u src/sys/fs/hfs/hfs.h:1.8 src/sys/fs/hfs/hfs.h:1.9
--- src/sys/fs/hfs/hfs.h:1.8	Sat Jan 28 16:24:35 2012
+++ src/sys/fs/hfs/hfs.h	Sun Aug 10 08:53:22 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs.h,v 1.8 2012/01/28 16:24:35 joerg Exp $	*/
+/*	$NetBSD: hfs.h,v 1.9 2014/08/10 08:53:22 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -65,9 +65,13 @@ struct hfsmount {
 	hfs_volume hm_vol;			/* essential volume information */
 };
 
+struct hfsnode_key {
+	hfs_cnid_t hnk_cnid;
+	uint8_t hnk_fork;
+};
+
 struct hfsnode {
 	struct genfs_node h_gnode;
-	LIST_ENTRY(hfsnode) h_hash;/* hash chain */
 	struct vnode *h_vnode;		/* vnode associated with this hnode */
 	struct hfsmount *h_hmp;	/* mount point associated with this hnode */
 	struct vnode *h_devvp;		/* vnode for block I/O */
@@ -92,7 +96,8 @@ struct hfsnode {
 	 */
 	hfs_cnid_t		h_parent;
 
-	uint8_t h_fork;
+	struct hfsnode_key h_key;
+#define h_fork	h_key.hnk_fork
 
 	long	dummy;	/* FOR DEVELOPMENT ONLY */
 };
@@ -149,19 +154,13 @@ extern const struct vnodeopv_desc hfs_sp
 extern const struct vnodeopv_desc hfs_fifoop_opv_desc;
 extern int (**hfs_specop_p) (void *);
 extern int (**hfs_fifoop_p) (void *);
+extern struct pool hfs_node_pool;
 
 
 /*
  * Function prototypes
  */
 
-/* hfs_nhash.c */
-void hfs_nhashinit (void);
-void hfs_nhashdone (void);
-struct vnode *hfs_nhashget (dev_t, hfs_cnid_t, uint8_t, int);
-void hfs_nhashinsert (struct hfsnode *);
-void hfs_nhashremove (struct hfsnode *);
-
 /* hfs_subr.c */
 void hfs_vinit (struct mount *, int (**)(void *), int (**)(void *),
 		 struct vnode **);

Index: src/sys/fs/hfs/hfs_vfsops.c
diff -u src/sys/fs/hfs/hfs_vfsops.c:1.31 src/sys/fs/hfs/hfs_vfsops.c:1.32
--- src/sys/fs/hfs/hfs_vfsops.c:1.31	Wed Apr 16 18:55:18 2014
+++ src/sys/fs/hfs/hfs_vfsops.c	Sun Aug 10 08:53:22 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_vfsops.c,v 1.31 2014/04/16 18:55:18 maxv Exp $	*/
+/*	$NetBSD: hfs_vfsops.c,v 1.32 2014/08/10 08:53:22 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.31 2014/04/16 18:55:18 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_vfsops.c,v 1.32 2014/08/10 08:53:22 hannken Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -139,7 +139,7 @@ MODULE(MODULE_CLASS_VFS, hfs, NULL);
 
 MALLOC_JUSTDEFINE(M_HFSMNT, "hfs mount", "hfs mount structures");
 
-extern kmutex_t hfs_hashlock;
+struct pool hfs_node_pool;
 
 const struct vnodeopv_desc * const hfs_vnodeopv_descs[] = {
 	&hfs_vnodeop_opv_desc,
@@ -159,6 +159,7 @@ struct vfsops hfs_vfsops = {
 	.vfs_statvfs = hfs_statvfs,
 	.vfs_sync = hfs_sync,
 	.vfs_vget = hfs_vget,
+	.vfs_loadvnode = hfs_loadvnode,
 	.vfs_fhtovp = hfs_fhtovp,
 	.vfs_vptofh = hfs_vptofh,
 	.vfs_init = hfs_init,
@@ -507,7 +508,18 @@ hfs_sync(struct mount *mp, int waitfor, 
 int
 hfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
 {
-    return hfs_vget_internal(mp, ino, HFS_DATAFORK, vpp);
+	int error;
+
+	error = hfs_vget_internal(mp, ino, HFS_DATAFORK, vpp);
+	if (error)
+		return error;
+	error = vn_lock(*vpp, LK_EXCLUSIVE);
+	if (error) {
+		vrele(*vpp);
+		*vpp = NULL;
+		return error;
+	}
+	return 0;
 }
 
 /*
@@ -517,93 +529,60 @@ int
 hfs_vget_internal(struct mount *mp, ino_t ino, uint8_t fork,
     struct vnode **vpp)
 {
+	struct hfsnode_key key;
+
+	memset(&key, 0, sizeof(key));
+	key.hnk_cnid = (hfs_cnid_t)ino;
+	key.hnk_fork = (fork != HFS_RSRCFORK ? HFS_DATAFORK : HFS_RSRCFORK);
+
+	return vcache_get(mp, &key, sizeof(key), vpp);
+}
+
+int
+hfs_loadvnode(struct mount *mp, struct vnode *vp,
+    const void *key, size_t key_len, const void **new_key)
+{
 	struct hfsmount *hmp;
 	struct hfsnode *hnode;
-	struct vnode *vp;
+	struct hfsnode_key hfskey;
 	hfs_callback_args cbargs;
-	hfs_cnid_t cnid;
 	hfs_catalog_keyed_record_t rec;
-	hfs_catalog_key_t key; /* the search key used to find this file on disk */
+	hfs_catalog_key_t cat_key; /* the search key used to find this file on disk */
 	dev_t dev;
-	int error;
 
 #ifdef HFS_DEBUG	
-	printf("vfsop = hfs_vget()\n");
+	printf("vfsop = hfs_loadvnode()\n");
 #endif /* HFS_DEBUG */
 
-	hnode = NULL;
-	vp = NULL;
+	KASSERT(key_len == sizeof(hfskey));
+	memcpy(&hfskey, key, key_len);
+
 	hmp = VFSTOHFS(mp);
 	dev = hmp->hm_dev;
-	cnid = (hfs_cnid_t)ino;
-
-	if (fork != HFS_RSRCFORK)
-	    fork = HFS_DATAFORK;
-
- retry:
-	/* Check if this vnode has already been allocated. If so, just return it. */
-	if ((*vpp = hfs_nhashget(dev, cnid, fork, LK_EXCLUSIVE)) != NULL)
-		return 0;
 
-	/* Allocate a new vnode/inode. */
-	error = getnewvnode(VT_HFS, mp, hfs_vnodeop_p, NULL, &vp);
-	if (error) {
-		goto error;
-	}
-	hnode = malloc(sizeof(struct hfsnode), M_TEMP,
-		M_WAITOK | M_ZERO);
-
-	/*
-	 * If someone beat us to it while sleeping in getnewvnode(),
-	 * push back the freshly allocated vnode we don't need, and return.
-	 */
-	mutex_enter(&hfs_hashlock);
-	if (hfs_nhashget(dev, cnid, fork, 0) != NULL) {
-		mutex_exit(&hfs_hashlock);
-		ungetnewvnode(vp);
-		free(hnode, M_TEMP);
-		goto retry;
-	}
-
-	vp->v_vflag |= VV_LOCKSWORK;	
-	vp->v_data = hnode;
-	genfs_node_init(vp, &hfs_genfsops);
-	
+	hnode = pool_get(&hfs_node_pool, PR_WAITOK);
+	memset(hnode, 0, sizeof(*hnode));
 	hnode->h_vnode = vp;
 	hnode->h_hmp = hmp;
 	hnode->dummy = 0x1337BABE;
-	
-	/*
-	 * We need to put this vnode into the hash chain and lock it so that other
-	 * requests for this inode will block if they arrive while we are sleeping
-	 * waiting for old data structures to be purged or for the contents of the
-	 * disk portion of this inode to be read. The hash chain requires the node's
-	 * device and cnid to be known. Since this information was passed in the
-	 * arguments, fill in the appropriate hfsnode fields without reading having
-	 * to read the disk.
-	 */
 	hnode->h_dev = dev;
-	hnode->h_rec.u.cnid = cnid;
-	hnode->h_fork = fork;
-
-	hfs_nhashinsert(hnode);
-	mutex_exit(&hfs_hashlock);
-
+	hnode->h_rec.u.cnid = hfskey.hnk_cnid;
+	hnode->h_fork = hfskey.hnk_fork;
+	hnode->h_key = hfskey;
 
 	/*
 	 * Read catalog record from disk.
 	 */
 	hfslib_init_cbargs(&cbargs);
 	
-	if (hfslib_find_catalog_record_with_cnid(&hmp->hm_vol, cnid,
-		&rec, &key, &cbargs) != 0) {
-		vput(vp);
-		error = EBADF;
-		goto error;
+	if (hfslib_find_catalog_record_with_cnid(&hmp->hm_vol, hfskey.hnk_cnid,
+		&rec, &cat_key, &cbargs) != 0) {
+		pool_put(&hfs_node_pool, hnode);
+		return EBADF;
 	}
 		
 	memcpy(&hnode->h_rec, &rec, sizeof(hnode->h_rec));
-	hnode->h_parent = key.parent_cnid;
+	hnode->h_parent = cat_key.parent_cnid;
 
 	/* XXX Eventually need to add an "ignore permissions" mount option */
 
@@ -613,9 +592,14 @@ hfs_vget_internal(struct mount *mp, ino_
 	 */
 	/* DATE AND TIME */
 
+	vp->v_tag = VT_HFS;
+	vp->v_op = hfs_vnodeop_p;
+	vp->v_vflag |= VV_LOCKSWORK;	
+	vp->v_data = hnode;
+	genfs_node_init(vp, &hfs_genfsops);
+
 	/*
 	 * Initialize the vnode from the hfsnode, check for aliases.
-	 * Note that the underlying vnode may change.
 	 */
 	hfs_vinit(mp, hfs_specop_p, hfs_fifoop_p, &vp);
 
@@ -634,13 +618,8 @@ hfs_vget_internal(struct mount *mp, ino_
 	else
 		uvm_vnp_setsize(vp, 0); /* no directly reading directories */
 		
-	*vpp = vp;
-	
+	*new_key = &hnode->h_key;
 	return 0;
-
-error:
-	*vpp = NULL;
-	return error;
 }
 
 int
@@ -675,6 +654,8 @@ hfs_init(void)
 #endif /* HFS_DEBUG */
 
 	malloc_type_attach(M_HFSMNT);
+	pool_init(&hfs_node_pool, sizeof(struct hfsnode), 0, 0, 0, "hfsndpl",
+	    &pool_allocator_nointr, IPL_NONE);
 
 	callbacks.error = hfs_libcb_error;
 	callbacks.allocmem = hfs_libcb_malloc;
@@ -684,7 +665,6 @@ hfs_init(void)
 	callbacks.closevol = hfs_libcb_closedev;
 	callbacks.read = hfs_libcb_read;
 
-	hfs_nhashinit();
 	hfslib_init(&callbacks);
 }
 
@@ -709,8 +689,9 @@ hfs_done(void)
 
 	malloc_type_detach(M_HFSMNT);
 
+	pool_destroy(&hfs_node_pool);
+
 	hfslib_done();
-	hfs_nhashdone();
 }
 
 int

Index: src/sys/fs/hfs/hfs_vnops.c
diff -u src/sys/fs/hfs/hfs_vnops.c:1.30 src/sys/fs/hfs/hfs_vnops.c:1.31
--- src/sys/fs/hfs/hfs_vnops.c:1.30	Fri Jul 25 08:20:51 2014
+++ src/sys/fs/hfs/hfs_vnops.c	Sun Aug 10 08:53:22 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hfs_vnops.c,v 1.30 2014/07/25 08:20:51 dholland Exp $	*/
+/*	$NetBSD: hfs_vnops.c,v 1.31 2014/08/10 08:53:22 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
@@ -101,7 +101,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.30 2014/07/25 08:20:51 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.31 2014/08/10 08:53:22 hannken Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ipsec.h"
@@ -115,6 +115,7 @@ __KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,
 #include <sys/proc.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
+#include <sys/pool.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
@@ -335,7 +336,6 @@ hfs_vop_lookup(void *v)
 	struct hfsnode *dp;	/* hfsnode for directory being searched */
 	kauth_cred_t cred;
 	struct vnode **vpp;		/* resultant vnode */
-	struct vnode *pdp;		/* saved dp during symlink work */
 	struct vnode *tdp;		/* returned by VFS_VGET */
 	struct vnode *vdp;		/* vnode for directory being searched */
 	hfs_catalog_key_t key;	/* hfs+ catalog search key for requested child */
@@ -394,12 +394,10 @@ hfs_vop_lookup(void *v)
 	}
 #endif
 	
-	pdp = vdp;
 	if (flags & ISDOTDOT) {
 		DPRINTF(("DOTDOT "));
-		VOP_UNLOCK(pdp);	/* race to get the inode */
-		error = VFS_VGET(vdp->v_mount, dp->h_parent, &tdp);
-		vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
+		error = hfs_vget_internal(vdp->v_mount, dp->h_parent,
+		    HFS_RSRCFORK, &tdp);
 		if (error != 0)
 			goto error;
 		*vpp = tdp;
@@ -467,7 +465,8 @@ hfs_vop_lookup(void *v)
 			HFS_RSRCFORK, &tdp);
 		}
 		else
-			error = VFS_VGET(vdp->v_mount, rec.file.cnid, &tdp);
+			error = hfs_vget_internal(vdp->v_mount, rec.file.cnid,
+			    HFS_DATAFORK, &tdp);
 		if (error != 0)
 			goto error;
 		*vpp = tdp;
@@ -481,8 +480,6 @@ hfs_vop_lookup(void *v)
 	cache_enter(vdp, *vpp, cnp);
 #endif
 	
-	if (*vpp != vdp)
-		VOP_UNLOCK(*vpp);
 	error = 0;
 
 	/* FALLTHROUGH */
@@ -1039,8 +1036,8 @@ hfs_vop_reclaim(void *v)
 	vp = ap->a_vp;
 	hp = VTOH(vp);
 
-	/* Remove the hfsnode from its hash chain. */
-	hfs_nhashremove(hp);
+	KASSERT(hp->h_key.hnk_cnid == hp->h_rec.u.cnid);
+	vcache_remove(vp->v_mount, &hp->h_key, sizeof(hp->h_key));
 
 	/* Decrement the reference count to the volume's device. */
 	if (hp->h_devvp) {
@@ -1049,7 +1046,7 @@ hfs_vop_reclaim(void *v)
 	}
 	
 	genfs_node_destroy(vp);
-	free(vp->v_data, M_TEMP);
+	pool_put(&hfs_node_pool, hp);
 	vp->v_data = NULL;
 
 	return 0;

Index: src/sys/modules/hfs/Makefile
diff -u src/sys/modules/hfs/Makefile:1.1 src/sys/modules/hfs/Makefile:1.2
--- src/sys/modules/hfs/Makefile:1.1	Sat Jun 28 16:11:36 2008
+++ src/sys/modules/hfs/Makefile	Sun Aug 10 08:53:22 2014
@@ -1,11 +1,10 @@
-#	$NetBSD: Makefile,v 1.1 2008/06/28 16:11:36 rumble Exp $
+#	$NetBSD: Makefile,v 1.2 2014/08/10 08:53:22 hannken Exp $
 
 .include "../Makefile.inc"
 
 .PATH:	${S}/fs/hfs
 
 KMOD=  	hfs
-SRCS=	hfs_nhash.c hfs_subr.c hfs_vfsops.c hfs_vnops.c libhfs.c \
-	unicode.c
+SRCS=	hfs_subr.c hfs_vfsops.c hfs_vnops.c libhfs.c unicode.c
 
 .include <bsd.kmodule.mk>

Index: src/sys/rump/fs/lib/libhfs/Makefile
diff -u src/sys/rump/fs/lib/libhfs/Makefile:1.3 src/sys/rump/fs/lib/libhfs/Makefile:1.4
--- src/sys/rump/fs/lib/libhfs/Makefile:1.3	Tue Feb 16 20:42:46 2010
+++ src/sys/rump/fs/lib/libhfs/Makefile	Sun Aug 10 08:53:22 2014
@@ -1,11 +1,11 @@
-#	$NetBSD: Makefile,v 1.3 2010/02/16 20:42:46 pooka Exp $
+#	$NetBSD: Makefile,v 1.4 2014/08/10 08:53:22 hannken Exp $
 #
 
 .PATH:  ${.CURDIR}/../../../../fs/hfs
 
 LIB=	rumpfs_hfs
 
-SRCS=	hfs_nhash.c hfs_subr.c hfs_vfsops.c hfs_vnops.c libhfs.c unicode.c
+SRCS=	hfs_subr.c hfs_vfsops.c hfs_vnops.c libhfs.c unicode.c
 
 .include <bsd.lib.mk>
 .include <bsd.klinks.mk>

Reply via email to