Index: sys/kern/vfs_cache.c =================================================================== --- sys/kern/vfs_cache.c +++ sys/kern/vfs_cache.c @@ -490,13 +490,25 @@ cache_assert_vlp_locked(vlp); } +/* + * Called when initializing the vnode. + * + * TODO: With the value stored we may do better than computing the hash based + * on the address and perhaps the FNV algorithm may also need to be retired. + */ +static void +cache_prehash(struct vnode *vp) +{ + + vp->v_nchash = fnv_32_buf(&vp, sizeof(vp), FNV1_32_INIT); +} + static uint32_t cache_get_hash(char *name, u_char len, struct vnode *dvp) { uint32_t hash; - hash = fnv_32_buf(name, len, FNV1_32_INIT); - hash = fnv_32_buf(&dvp, sizeof(dvp), hash); + hash = fnv_32_buf(name, len, dvp->v_nchash); return (hash); } @@ -2070,6 +2082,16 @@ } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL); +void +cache_vnode_init(struct vnode *vp) +{ + + LIST_INIT(&vp->v_cache_src); + TAILQ_INIT(&vp->v_cache_dst); + vp->v_cache_dd = NULL; + cache_prehash(vp); +} + void cache_changesize(u_long newmaxvnodes) { Index: sys/kern/vfs_subr.c =================================================================== --- sys/kern/vfs_subr.c +++ sys/kern/vfs_subr.c @@ -563,8 +563,7 @@ /* * Initialize namecache. */ - LIST_INIT(&vp->v_cache_src); - TAILQ_INIT(&vp->v_cache_dst); + cache_vnode_init(vp); /* * Initialize rangelocks. */ Index: sys/sys/vnode.h =================================================================== --- sys/sys/vnode.h +++ sys/sys/vnode.h @@ -107,6 +107,7 @@ enum vtype v_type:8; /* u vnode type */ short v_irflag; /* i frequently read flags */ seqc_t v_seqc; /* i modification count */ + uint32_t v_nchash; /* u namecache hash */ struct vop_vector *v_op; /* u vnode operations vector */ void *v_data; /* u private data for fs */ @@ -171,8 +172,8 @@ u_int v_holdcnt; /* I prevents recycling. */ u_int v_usecount; /* I ref count of users */ - u_int v_iflag; /* i vnode flags (see below) */ - u_int v_vflag; /* v vnode flags */ + u_short v_iflag; /* i vnode flags (see below) */ + u_short v_vflag; /* v vnode flags */ u_short v_mflag; /* l mnt-specific vnode flags */ short v_dbatchcpu; /* i LRU requeue deferral batch */ int v_writecount; /* I ref count of writers or @@ -245,10 +246,10 @@ #define VIRF_DOOMED 0x0001 /* This vnode is being recycled */ #define VI_TEXT_REF 0x0001 /* Text ref grabbed use ref */ -#define VI_MOUNT 0x0020 /* Mount in progress */ -#define VI_DOINGINACT 0x0800 /* VOP_INACTIVE is in progress */ -#define VI_OWEINACT 0x1000 /* Need to call inactive */ -#define VI_DEFINACT 0x2000 /* deferred inactive */ +#define VI_MOUNT 0x0002 /* Mount in progress */ +#define VI_DOINGINACT 0x0004 /* VOP_INACTIVE is in progress */ +#define VI_OWEINACT 0x0008 /* Need to call inactive */ +#define VI_DEFINACT 0x0010 /* deferred inactive */ #define VV_ROOT 0x0001 /* root of its filesystem */ #define VV_ISTTY 0x0002 /* vnode represents a tty */ @@ -635,6 +636,7 @@ struct timespec *dtsp); int cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct timespec *tsp, int *ticksp); +void cache_vnode_init(struct vnode *vp); void cache_purge(struct vnode *vp); void cache_purge_negative(struct vnode *vp); void cache_purgevfs(struct mount *mp, bool force);