summaryrefslogtreecommitdiffstats
path: root/sys/fs/udf
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2003-05-04 03:40:11 +0000
committerscottl <scottl@FreeBSD.org>2003-05-04 03:40:11 +0000
commit35f9e645cf6f2083217d43c1a08f2f7552e64fef (patch)
treed3dcfe9af28b03bd4bbe34d1cca136046fe1c7df /sys/fs/udf
parentc3792f8bd926539973db34033a84333af43d74b1 (diff)
downloadFreeBSD-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.h7
-rw-r--r--sys/fs/udf/udf_vfsops.c7
-rw-r--r--sys/fs/udf/udf_vnops.c18
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);
OpenPOWER on IntegriCloud