diff options
author | scottl <scottl@FreeBSD.org> | 2003-05-04 03:40:11 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-05-04 03:40:11 +0000 |
commit | 35f9e645cf6f2083217d43c1a08f2f7552e64fef (patch) | |
tree | d3dcfe9af28b03bd4bbe34d1cca136046fe1c7df /sys/fs/udf | |
parent | c3792f8bd926539973db34033a84333af43d74b1 (diff) | |
download | FreeBSD-src-35f9e645cf6f2083217d43c1a08f2f7552e64fef.zip FreeBSD-src-35f9e645cf6f2083217d43c1a08f2f7552e64fef.tar.gz |
Implement the node cache as a hash table.
Diffstat (limited to 'sys/fs/udf')
-rw-r--r-- | sys/fs/udf/udf.h | 7 | ||||
-rw-r--r-- | sys/fs/udf/udf_vfsops.c | 7 | ||||
-rw-r--r-- | sys/fs/udf/udf_vnops.c | 18 |
3 files changed, 26 insertions, 6 deletions
diff --git a/sys/fs/udf/udf.h b/sys/fs/udf/udf.h index 654c8fd..3fde1a3 100644 --- a/sys/fs/udf/udf.h +++ b/sys/fs/udf/udf.h @@ -26,8 +26,10 @@ * $FreeBSD$ */ +#define UDF_HASHTBLSIZE 100 + struct udf_node { - TAILQ_ENTRY(udf_node) tq; + LIST_ENTRY(udf_node) le; struct vnode *i_vnode; struct vnode *i_devvp; struct udf_mnt *udfmp; @@ -50,7 +52,8 @@ struct udf_mnt { uint64_t root_id; struct vnode *root_vp; struct long_ad root_icb; - TAILQ_HEAD(, udf_node) udf_tqh; + LIST_HEAD(udf_hash_lh, udf_node) *hashtbl; + u_long hashsz; struct mtx hash_mtx; int p_sectors; int s_table_entries; diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index fed899e..9ba75d4 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -446,10 +446,11 @@ udf_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { brelse(bp); bp = NULL; - TAILQ_INIT(&udfmp->udf_tqh); devvp->v_rdev->si_mountpoint = mp; mtx_init(&udfmp->hash_mtx, "udf_hash", NULL, MTX_DEF); + udfmp->hashtbl = phashinit(UDF_HASHTBLSIZE, M_UDFMOUNT, &udfmp->hashsz); + return 0; bail: @@ -482,6 +483,10 @@ udf_unmount(struct mount *mp, int mntflags, struct thread *td) if (udfmp->s_table != NULL) FREE(udfmp->s_table, M_UDFSTABLE); + + if (udfmp->hashtbl != NULL) + FREE(udfmp->hashtbl, M_UDFMOUNT); + FREE(udfmp, M_UDFMOUNT); mp->mnt_data = (qaddr_t)0; diff --git a/sys/fs/udf/udf_vnops.c b/sys/fs/udf/udf_vnops.c index d48e36d..848bb5c 100644 --- a/sys/fs/udf/udf_vnops.c +++ b/sys/fs/udf/udf_vnops.c @@ -95,13 +95,17 @@ int udf_hashlookup(struct udf_mnt *udfmp, ino_t id, int flags, struct vnode **vpp) { struct udf_node *node; + struct udf_hash_lh *lh; int error; *vpp = NULL; loop: mtx_lock(&udfmp->hash_mtx); - TAILQ_FOREACH(node, &udfmp->udf_tqh, tq) { + lh = &udfmp->hashtbl[id % udfmp->hashsz]; + if (lh == NULL) + return (ENOENT); + LIST_FOREACH(node, lh, le) { if (node->hash_id == id) { VI_LOCK(node->i_vnode); mtx_unlock(&udfmp->hash_mtx); @@ -124,12 +128,16 @@ int udf_hashins(struct udf_node *node) { struct udf_mnt *udfmp; + struct udf_hash_lh *lh; udfmp = node->udfmp; vn_lock(node->i_vnode, LK_EXCLUSIVE | LK_RETRY, curthread); mtx_lock(&udfmp->hash_mtx); - TAILQ_INSERT_TAIL(&udfmp->udf_tqh, node, tq); + lh = &udfmp->hashtbl[node->hash_id % udfmp->hashsz]; + if (lh == NULL) + LIST_INIT(lh); + LIST_INSERT_HEAD(lh, node, le); mtx_unlock(&udfmp->hash_mtx); return (0); @@ -139,11 +147,15 @@ int udf_hashrem(struct udf_node *node) { struct udf_mnt *udfmp; + struct udf_hash_lh *lh; udfmp = node->udfmp; mtx_lock(&udfmp->hash_mtx); - TAILQ_REMOVE(&udfmp->udf_tqh, node, tq); + lh = &udfmp->hashtbl[node->hash_id % udfmp->hashsz]; + if (lh == NULL) + panic("hash entry is NULL, node->hash_id= %d\n", node->hash_id); + LIST_REMOVE(node, le); mtx_unlock(&udfmp->hash_mtx); return (0); |