summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2003-01-10 19:14:01 +0000
committerAlasdair Kergon <agk@redhat.com>2003-01-10 19:14:01 +0000
commit6bb20ee09ea975080e3e57285854a788d3f38673 (patch)
treeeec0b58457c47f5431abf8b5bd4fbf5dbe22696f
parent541356430c12579a3521bd9786987e3a91af7b5e (diff)
downloadlvm2-6bb20ee09ea975080e3e57285854a788d3f38673.tar.gz
Fix (rare) cache bug on machines with large /dev directories.old-beta6_3beta6_3
-rw-r--r--lib/cache/cache.c13
-rw-r--r--lib/datastruct/hash.c24
2 files changed, 17 insertions, 20 deletions
diff --git a/lib/cache/cache.c b/lib/cache/cache.c
index 5fd00d0b9..63cabe284 100644
--- a/lib/cache/cache.c
+++ b/lib/cache/cache.c
@@ -63,11 +63,16 @@ const struct format_type *fmt_from_vgname(const char *vgname)
struct cache_vginfo *vginfo_from_vgid(const char *vgid)
{
struct cache_vginfo *vginfo;
+ char id[ID_LEN + 1];
if (!_vgid_hash || !vgid)
return NULL;
- if (!(vginfo = hash_lookup_fixed(_vgid_hash, vgid, ID_LEN)))
+ /* vgid not necessarily NULL-terminated */
+ strncpy(&id[0], vgid, ID_LEN);
+ id[ID_LEN] = '\0';
+
+ if (!(vginfo = hash_lookup(_vgid_hash, id)))
return NULL;
return vginfo;
@@ -76,11 +81,15 @@ struct cache_vginfo *vginfo_from_vgid(const char *vgid)
struct cache_info *info_from_pvid(const char *pvid)
{
struct cache_info *info;
+ char id[ID_LEN + 1];
if (!_pvid_hash || !pvid)
return NULL;
- if (!(info = hash_lookup_fixed(_pvid_hash, pvid, ID_LEN)))
+ strncpy(&id[0], pvid, ID_LEN);
+ id[ID_LEN] = '\0';
+
+ if (!(info = hash_lookup(_pvid_hash, id)))
return NULL;
return info;
diff --git a/lib/datastruct/hash.c b/lib/datastruct/hash.c
index b85e69026..ac4f181ce 100644
--- a/lib/datastruct/hash.c
+++ b/lib/datastruct/hash.c
@@ -59,10 +59,10 @@ static struct hash_node *_create_node(const char *str)
return n;
}
-static unsigned _hash(const char *str, unsigned len)
+static unsigned _hash(const char *str)
{
unsigned long h = 0, g;
- while (*str && len--) {
+ while (*str) {
h <<= 4;
h += _nums[(int) *str++];
g = h & ((unsigned long) 0xf << 16u);
@@ -125,30 +125,18 @@ void hash_destroy(struct hash_table *t)
dbg_free(t);
}
-static inline struct hash_node **_find_fixed(struct hash_table *t,
- const char *key, unsigned len)
+static inline struct hash_node **_find(struct hash_table *t, const char *key)
{
- unsigned h = _hash(key, len) & (t->num_slots - 1);
+ unsigned h = _hash(key) & (t->num_slots - 1);
struct hash_node **c;
for (c = &t->slots[h]; *c; c = &((*c)->next))
- if (!strncmp(key, (*c)->key, len))
+ if (!strcmp(key, (*c)->key))
break;
return c;
}
-static inline struct hash_node **_find(struct hash_table *t, const char *key)
-{
- return _find_fixed(t, key, strlen(key));
-}
-
-void *hash_lookup_fixed(struct hash_table *t, const char *key, unsigned len)
-{
- struct hash_node **c = _find_fixed(t, key, len);
- return *c ? (*c)->data : 0;
-}
-
void *hash_lookup(struct hash_table *t, const char *key)
{
struct hash_node **c = _find(t, key);
@@ -238,6 +226,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
{
- unsigned h = _hash(n->key, strlen(n->key)) & (t->num_slots - 1);
+ unsigned h = _hash(n->key) & (t->num_slots - 1);
return n->next ? n->next : _next_slot(t, h + 1);
}