From 56942c3f2aafe613c8d12f0ef8d4f7872ebfae5f Mon Sep 17 00:00:00 2001 From: Patrick Caulfield Date: Wed, 22 Sep 2004 12:10:34 +0000 Subject: [PATCH] Put some locking round the LV hash table as it could be accessed by different threads concurrently. --- daemons/clvmd/lvm-functions.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c index 4499b6ee6..71988dbff 100644 --- a/daemons/clvmd/lvm-functions.c +++ b/daemons/clvmd/lvm-functions.c @@ -46,6 +46,7 @@ static struct cmd_context *cmd = NULL; static struct hash_table *lv_hash = NULL; +static pthread_mutex_t lv_hash_lock; struct lv_info { int lock_id; @@ -57,7 +58,9 @@ static int get_current_lock(char *resource) { struct lv_info *lvi; + pthread_mutex_lock(&lv_hash_lock); lvi = hash_lookup(lv_hash, resource); + pthread_mutex_unlock(&lv_hash_lock); if (lvi) { return lvi->lock_mode; } else { @@ -69,11 +72,14 @@ static int get_current_lock(char *resource) void unlock_all() { struct hash_node *v; + + pthread_mutex_lock(&lv_hash_lock); hash_iterate(v, lv_hash) { struct lv_info *lvi = hash_get_data(lv_hash, v); sync_unlock(hash_get_key(lv_hash, v), lvi->lock_id); } + pthread_mutex_unlock(&lv_hash_lock); } /* Gets a real lock and keeps the info in the hash table */ @@ -85,7 +91,9 @@ int hold_lock(char *resource, int mode, int flags) flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */ + pthread_mutex_lock(&lv_hash_lock); lvi = hash_lookup(lv_hash, resource); + pthread_mutex_unlock(&lv_hash_lock); if (lvi) { /* Already exists - convert it */ status = @@ -113,7 +121,9 @@ int hold_lock(char *resource, int mode, int flags) DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode, strerror(errno)); } else { + pthread_mutex_lock(&lv_hash_lock); hash_insert(lv_hash, resource, lvi); + pthread_mutex_unlock(&lv_hash_lock); } errno = saved_errno; } @@ -127,8 +137,9 @@ int hold_unlock(char *resource) int status; int saved_errno; + pthread_mutex_lock(&lv_hash_lock); lvi = hash_lookup(lv_hash, resource); - + pthread_mutex_unlock(&lv_hash_lock); if (!lvi) { DEBUGLOG("hold_unlock, lock not already held\n"); return 0; @@ -137,7 +148,9 @@ int hold_unlock(char *resource) status = sync_unlock(resource, lvi->lock_id); saved_errno = errno; if (!status) { + pthread_mutex_lock(&lv_hash_lock); hash_remove(lv_hash, resource); + pthread_mutex_unlock(&lv_hash_lock); free(lvi); } else { DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status, @@ -427,6 +440,7 @@ void init_lvhash() { /* Create hash table for keeping LV locks & status */ lv_hash = hash_create(100); + pthread_mutex_init(&lv_hash_lock, NULL); } /* Called to initialise the LVM context of the daemon */ -- 2.43.5