mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Put some locking round the LV hash table as it could be accessed by
different threads concurrently.
This commit is contained in:
parent
f2b2f485a5
commit
56942c3f2a
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user