summaryrefslogtreecommitdiff
path: root/debian/patches/0010-ext2fs-use-libihash-for-node-hash.patch
blob: fa4de2b472b0a113654c49474a3e3471cae01cf8 (plain)
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