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>