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>