|
@@ -56,6 +56,11 @@ static void dm_hash_remove_all(int keep_open_devices);
|
|
*/
|
|
*/
|
|
static DECLARE_RWSEM(_hash_lock);
|
|
static DECLARE_RWSEM(_hash_lock);
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Protects use of mdptr to obtain hash cell name and uuid from mapped device.
|
|
|
|
+ */
|
|
|
|
+static DEFINE_MUTEX(dm_hash_cells_mutex);
|
|
|
|
+
|
|
static void init_buckets(struct list_head *buckets)
|
|
static void init_buckets(struct list_head *buckets)
|
|
{
|
|
{
|
|
unsigned int i;
|
|
unsigned int i;
|
|
@@ -206,7 +211,9 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi
|
|
list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
|
|
list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
|
|
}
|
|
}
|
|
dm_get(md);
|
|
dm_get(md);
|
|
|
|
+ mutex_lock(&dm_hash_cells_mutex);
|
|
dm_set_mdptr(md, cell);
|
|
dm_set_mdptr(md, cell);
|
|
|
|
+ mutex_unlock(&dm_hash_cells_mutex);
|
|
up_write(&_hash_lock);
|
|
up_write(&_hash_lock);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -224,7 +231,9 @@ static void __hash_remove(struct hash_cell *hc)
|
|
/* remove from the dev hash */
|
|
/* remove from the dev hash */
|
|
list_del(&hc->uuid_list);
|
|
list_del(&hc->uuid_list);
|
|
list_del(&hc->name_list);
|
|
list_del(&hc->name_list);
|
|
|
|
+ mutex_lock(&dm_hash_cells_mutex);
|
|
dm_set_mdptr(hc->md, NULL);
|
|
dm_set_mdptr(hc->md, NULL);
|
|
|
|
+ mutex_unlock(&dm_hash_cells_mutex);
|
|
|
|
|
|
table = dm_get_table(hc->md);
|
|
table = dm_get_table(hc->md);
|
|
if (table) {
|
|
if (table) {
|
|
@@ -321,7 +330,9 @@ static int dm_hash_rename(uint32_t cookie, const char *old, const char *new)
|
|
*/
|
|
*/
|
|
list_del(&hc->name_list);
|
|
list_del(&hc->name_list);
|
|
old_name = hc->name;
|
|
old_name = hc->name;
|
|
|
|
+ mutex_lock(&dm_hash_cells_mutex);
|
|
hc->name = new_name;
|
|
hc->name = new_name;
|
|
|
|
+ mutex_unlock(&dm_hash_cells_mutex);
|
|
list_add(&hc->name_list, _name_buckets + hash_str(new_name));
|
|
list_add(&hc->name_list, _name_buckets + hash_str(new_name));
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1582,8 +1593,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
|
|
if (!md)
|
|
if (!md)
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
|
|
|
|
- dm_get(md);
|
|
|
|
- down_read(&_hash_lock);
|
|
|
|
|
|
+ mutex_lock(&dm_hash_cells_mutex);
|
|
hc = dm_get_mdptr(md);
|
|
hc = dm_get_mdptr(md);
|
|
if (!hc || hc->md != md) {
|
|
if (!hc || hc->md != md) {
|
|
r = -ENXIO;
|
|
r = -ENXIO;
|
|
@@ -1596,8 +1606,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
|
|
strcpy(uuid, hc->uuid ? : "");
|
|
strcpy(uuid, hc->uuid ? : "");
|
|
|
|
|
|
out:
|
|
out:
|
|
- up_read(&_hash_lock);
|
|
|
|
- dm_put(md);
|
|
|
|
|
|
+ mutex_unlock(&dm_hash_cells_mutex);
|
|
|
|
|
|
return r;
|
|
return r;
|
|
}
|
|
}
|