1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
From bb7185a63157cd1f419c972abb20123ca7ad1749 Mon Sep 17 00:00:00 2001
From: Justus Winter <4winter@informatik.uni-hamburg.de>
Date: Wed, 15 Apr 2015 02:17:11 +0200
Subject: [PATCH hurd 10/10] ext2fs: use libihash for node hash
---
ext2fs/ext2fs.c | 2 --
ext2fs/ext2fs.h | 5 -----
ext2fs/inode.c | 61 +++++++++++++++++----------------------------------------
3 files changed, 18 insertions(+), 50 deletions(-)
diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
index beb7cad..d0fdfe7 100644
--- a/ext2fs/ext2fs.c
+++ b/ext2fs/ext2fs.c
@@ -185,8 +185,6 @@ main (int argc, char **argv)
map_hypermetadata ();
- inode_init ();
-
/* Set diskfs_root_node to the root inode. */
err = diskfs_cached_lookup (EXT2_ROOT_INO, &diskfs_root_node);
if (err)
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 9667b6f..69b7c02 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -159,9 +159,6 @@ struct disknode
each DIRBLKSIZE piece of the directory. */
int *dirents;
- /* Links on hash list. */
- struct node *hnext, **hprevp;
-
/* Lock to lock while fiddling with this inode's block allocation info. */
pthread_rwlock_t alloc_lock;
@@ -423,8 +420,6 @@ void write_all_disknodes ();
/* Lookup node INUM (which must have a reference already) and return it
without allocating any new references. */
struct node *ifind (ino_t inum);
-
-void inode_init (void);
/* ---------------------------------------------------------------- */
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index 7af617c..0071a2b 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -20,6 +20,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "ext2fs.h"
+#include <hurd/ihash.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
@@ -39,49 +40,28 @@
#define UF_IMMUTABLE 0
#endif
-#define INOHSZ 8192
-#if ((INOHSZ&(INOHSZ-1)) == 0)
-#define INOHASH(ino) ((ino)&(INOHSZ-1))
-#else
-#define INOHASH(ino) (((unsigned)(ino))%INOHSZ)
-#endif
-
/* The nodehash is a cache of nodes.
- Access to nodehash and nodehash_nr_items is protected by
- nodecache_lock.
+ Access to nodehash is protected by nodecache_lock.
Every node in the nodehash carries a light reference. When we are
asked to give up that light reference, we reacquire our lock
momentarily to check whether someone else reacquired a reference
through the nodehash. */
-static struct node *nodehash[INOHSZ];
-static size_t nodehash_nr_items;
+static struct hurd_ihash nodehash =
+ HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP);
static pthread_rwlock_t nodecache_lock = PTHREAD_RWLOCK_INITIALIZER;
static error_t read_node (struct node *np);
pthread_spinlock_t generation_lock = PTHREAD_SPINLOCK_INITIALIZER;
-/* Initialize the inode hash table. */
-void
-inode_init ()
-{
- int n;
- for (n = 0; n < INOHSZ; n++)
- nodehash[n] = 0;
-}
-
/* Lookup node with inode number INUM. Returns NULL if the node is
not found in the node cache. */
static struct node *
lookup (ino_t inum)
{
- struct node *np;
- for (np = nodehash[INOHASH(inum)]; np; np = diskfs_node_disknode (np)->hnext)
- if (np->cache_id == inum)
- return np;
- return NULL;
+ return hurd_ihash_find (&nodehash, inum);
}
/* Fetch inode INUM, set *NPP to the node structure;
@@ -124,14 +104,15 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
goto gotit;
}
- dn->hnext = nodehash[INOHASH(inum)];
- if (dn->hnext)
- diskfs_node_disknode (dn->hnext)->hprevp = &dn->hnext;
- dn->hprevp = &nodehash[INOHASH(inum)];
- nodehash[INOHASH(inum)] = np;
diskfs_nref_light (np);
- nodehash_nr_items += 1;
+ err = hurd_ihash_add (&nodehash, inum, np);
pthread_rwlock_unlock (&nodecache_lock);
+ if (err)
+ {
+ diskfs_nrele_light (np);
+ diskfs_nput (np);
+ return err;
+ }
/* Get the contents of NP off disk. */
err = read_node (np);
@@ -199,7 +180,7 @@ void
diskfs_try_dropping_softrefs (struct node *np)
{
pthread_rwlock_wrlock (&nodecache_lock);
- if (diskfs_node_disknode (np)->hprevp != NULL)
+ if (hurd_ihash_find (&nodehash, np->cache_id) != NULL)
{
/* Check if someone reacquired a reference through the
nodehash. */
@@ -214,13 +195,7 @@ diskfs_try_dropping_softrefs (struct node *np)
return;
}
- *diskfs_node_disknode (np)->hprevp = diskfs_node_disknode (np)->hnext;
- if (diskfs_node_disknode (np)->hnext)
- diskfs_node_disknode (diskfs_node_disknode (np)->hnext)->hprevp =
- diskfs_node_disknode (np)->hprevp;
- diskfs_node_disknode (np)->hnext = NULL;
- diskfs_node_disknode (np)->hprevp = NULL;
- nodehash_nr_items -= 1;
+ hurd_ihash_remove (&nodehash, np->cache_id);
diskfs_nrele_light (np);
}
pthread_rwlock_unlock (&nodecache_lock);
@@ -608,7 +583,8 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
during processing (normally we delegate access to hash-table with
nodecache_lock, but we can't hold this while locking the
individual node locks). */
- num_nodes = nodehash_nr_items;
+ /* XXX: Can we? */
+ num_nodes = nodehash.nr_items;
/* TODO This method doesn't scale beyond a few dozen nodes and should be
replaced. */
@@ -621,10 +597,9 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
}
p = node_list;
- for (n = 0; n < INOHSZ; n++)
- for (node = nodehash[n]; node; node = diskfs_node_disknode (node)->hnext)
+ HURD_IHASH_ITERATE (&nodehash, value)
{
- *p++ = node;
+ *p++ = node = (struct node *) value;
/* We acquire a hard reference for node, but without using
diskfs_nref. We do this so that diskfs_new_hardrefs will not
--
2.1.4
|