diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 72c22dc..7f3f7a1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -2025,6 +2025,8 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp) err = zfs_vnode_lock(*vpp, flags); if (err != 0) *vpp = NULL; + else + (*vpp)->v_hash = ino; return (err); } diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c index 0b72249..90e56ea 100644 --- a/sys/fs/nullfs/null_subr.c +++ b/sys/fs/nullfs/null_subr.c @@ -46,9 +46,6 @@ #include -#define LOG2_SIZEVNODE 8 /* log2(sizeof struct vnode) */ -#define NNULLNODECACHE 16 - /* * Null layer cache: * Each cache entry holds a reference to the lower vnode @@ -57,12 +54,11 @@ * alias is removed the lower vnode is vrele'd. */ -#define NULL_NHASH(vp) \ - (&null_node_hashtbl[(((uintptr_t)vp)>>LOG2_SIZEVNODE) & null_node_hash]) +#define NULL_NHASH(vp) (&null_node_hashtbl[vfs_hash_index(vp) & null_hash_mask]) static LIST_HEAD(null_node_hashhead, null_node) *null_node_hashtbl; -static u_long null_node_hash; -struct mtx null_hashmtx; +static struct mtx null_hashmtx; +static u_long null_hash_mask; static MALLOC_DEFINE(M_NULLFSHASH, "nullfs_hash", "NULLFS hash table"); MALLOC_DEFINE(M_NULLFSNODE, "nullfs_node", "NULLFS vnode private part"); @@ -77,8 +73,8 @@ nullfs_init(vfsp) struct vfsconf *vfsp; { - NULLFSDEBUG("nullfs_init\n"); /* printed during system boot */ - null_node_hashtbl = hashinit(NNULLNODECACHE, M_NULLFSHASH, &null_node_hash); + null_node_hashtbl = hashinit(desiredvnodes, M_NULLFSHASH, + &null_hash_mask); mtx_init(&null_hashmtx, "nullhs", NULL, MTX_DEF); return (0); } @@ -89,7 +85,7 @@ nullfs_uninit(vfsp) { mtx_destroy(&null_hashmtx); - hashdestroy(null_node_hashtbl, M_NULLFSHASH, null_node_hash); + hashdestroy(null_node_hashtbl, M_NULLFSHASH, null_hash_mask); return (0); } diff --git a/sys/kern/vfs_hash.c b/sys/kern/vfs_hash.c index aad22e0..0271e49 100644 --- a/sys/kern/vfs_hash.c +++ b/sys/kern/vfs_hash.c @@ -54,11 +54,18 @@ vfs_hashinit(void *dummy __unused) /* Must be SI_ORDER_SECOND so desiredvnodes is available */ SYSINIT(vfs_hash, SI_SUB_VFS, SI_ORDER_SECOND, vfs_hashinit, NULL); +u_int +vfs_hash_index(struct vnode *vp) +{ + + return (vp->v_hash + vp->v_mount->mnt_hashseed); +} + static struct vfs_hash_head * -vfs_hash_index(const struct mount *mp, u_int hash) +vfs_hash_bucket(const struct mount *mp, u_int hash) { - return(&vfs_hash_tbl[(hash + mp->mnt_hashseed) & vfs_hash_mask]); + return (&vfs_hash_tbl[(hash + mp->mnt_hashseed) & vfs_hash_mask]); } int @@ -69,7 +76,7 @@ vfs_hash_get(const struct mount *mp, u_int hash, int flags, struct thread *td, s while (1) { mtx_lock(&vfs_hash_mtx); - LIST_FOREACH(vp, vfs_hash_index(mp, hash), v_hashlist) { + LIST_FOREACH(vp, vfs_hash_bucket(mp, hash), v_hashlist) { if (vp->v_hash != hash) continue; if (vp->v_mount != mp) @@ -113,7 +120,7 @@ vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td, stru while (1) { mtx_lock(&vfs_hash_mtx); LIST_FOREACH(vp2, - vfs_hash_index(vp->v_mount, hash), v_hashlist) { + vfs_hash_bucket(vp->v_mount, hash), v_hashlist) { if (vp2->v_hash != hash) continue; if (vp2->v_mount != vp->v_mount) @@ -138,7 +145,7 @@ vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td, stru } vp->v_hash = hash; - LIST_INSERT_HEAD(vfs_hash_index(vp->v_mount, hash), vp, v_hashlist); + LIST_INSERT_HEAD(vfs_hash_bucket(vp->v_mount, hash), vp, v_hashlist); mtx_unlock(&vfs_hash_mtx); return (0); } @@ -149,7 +156,7 @@ vfs_hash_rehash(struct vnode *vp, u_int hash) mtx_lock(&vfs_hash_mtx); LIST_REMOVE(vp, v_hashlist); - LIST_INSERT_HEAD(vfs_hash_index(vp->v_mount, hash), vp, v_hashlist); + LIST_INSERT_HEAD(vfs_hash_bucket(vp->v_mount, hash), vp, v_hashlist); vp->v_hash = hash; mtx_unlock(&vfs_hash_mtx); } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 7c243b6..0bdaf36 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -279,6 +279,7 @@ SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, #define VSHOULDFREE(vp) (!((vp)->v_iflag & VI_FREE) && !(vp)->v_holdcnt) #define VSHOULDBUSY(vp) (((vp)->v_iflag & VI_FREE) && (vp)->v_holdcnt) +static int vnsz2log; /* * Initialize the vnode management data structures. @@ -293,6 +294,7 @@ SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, static void vntblinit(void *dummy __unused) { + u_int i; int physvnodes, virtvnodes; /* @@ -332,6 +334,9 @@ vntblinit(void *dummy __unused) syncer_maxdelay = syncer_mask + 1; mtx_init(&sync_mtx, "Syncer mtx", NULL, MTX_DEF); cv_init(&sync_wakeup, "syncer"); + for (i = 1; i <= sizeof(struct vnode); i <<= 1) + vnsz2log++; + vnsz2log--; } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vntblinit, NULL); @@ -1067,6 +1072,14 @@ alloc: } rangelock_init(&vp->v_rl); + /* + * For the filesystems which do not use vfs_hash_insert(), + * still initialize v_hash to have vfs_hash_index() useful. + * E.g., nullfs uses vfs_hash_index() on the lower vnode for + * its own hashing. + */ + vp->v_hash = (uintptr_t)vp >> vnsz2log; + *vpp = vp; return (0); } diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index f841f82..b54dc04 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -812,6 +814,7 @@ int fifo_printinfo(struct vnode *); typedef int vfs_hash_cmp_t(struct vnode *vp, void *arg); int vfs_hash_get(const struct mount *mp, u_int hash, int flags, struct thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg); +u_int vfs_hash_index(struct vnode *vp); int vfs_hash_insert(struct vnode *vp, u_int hash, int flags, struct thread *td, struct vnode **vpp, vfs_hash_cmp_t *fn, void *arg); void vfs_hash_rehash(struct vnode *vp, u_int hash); void vfs_hash_remove(struct vnode *vp);