[PATCH] dm table: store md
Store an up-pointer to the owning struct mapped_device in every table when it is created. Access it with: struct mapped_device *dm_table_get_md(struct dm_table *t) Tables linked to md must be destroyed before the md itself. Signed-off-by: Mike Anderson <andmike@us.ibm.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
9ade92a9a5
commit
1134e5ae79
4 changed files with 40 additions and 17 deletions
|
@ -244,9 +244,9 @@ static void __hash_remove(struct hash_cell *hc)
|
||||||
dm_table_put(table);
|
dm_table_put(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_put(hc->md);
|
|
||||||
if (hc->new_map)
|
if (hc->new_map)
|
||||||
dm_table_put(hc->new_map);
|
dm_table_put(hc->new_map);
|
||||||
|
dm_put(hc->md);
|
||||||
free_cell(hc);
|
free_cell(hc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,33 +985,43 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
|
||||||
int r;
|
int r;
|
||||||
struct hash_cell *hc;
|
struct hash_cell *hc;
|
||||||
struct dm_table *t;
|
struct dm_table *t;
|
||||||
|
struct mapped_device *md;
|
||||||
|
|
||||||
r = dm_table_create(&t, get_mode(param), param->target_count);
|
md = find_device(param);
|
||||||
|
if (!md)
|
||||||
|
return -ENXIO;
|
||||||
|
|
||||||
|
r = dm_table_create(&t, get_mode(param), param->target_count, md);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
goto out;
|
||||||
|
|
||||||
r = populate_table(t, param, param_size);
|
r = populate_table(t, param, param_size);
|
||||||
if (r) {
|
if (r) {
|
||||||
dm_table_put(t);
|
dm_table_put(t);
|
||||||
return r;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
down_write(&_hash_lock);
|
down_write(&_hash_lock);
|
||||||
hc = __find_device_hash_cell(param);
|
hc = dm_get_mdptr(md);
|
||||||
if (!hc) {
|
if (!hc || hc->md != md) {
|
||||||
DMWARN("device doesn't appear to be in the dev hash table.");
|
DMWARN("device has been removed from the dev hash table.");
|
||||||
up_write(&_hash_lock);
|
|
||||||
dm_table_put(t);
|
dm_table_put(t);
|
||||||
return -ENXIO;
|
up_write(&_hash_lock);
|
||||||
|
r = -ENXIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hc->new_map)
|
if (hc->new_map)
|
||||||
dm_table_put(hc->new_map);
|
dm_table_put(hc->new_map);
|
||||||
hc->new_map = t;
|
hc->new_map = t;
|
||||||
param->flags |= DM_INACTIVE_PRESENT_FLAG;
|
|
||||||
|
|
||||||
r = __dev_status(hc->md, param);
|
|
||||||
up_write(&_hash_lock);
|
up_write(&_hash_lock);
|
||||||
|
|
||||||
|
param->flags |= DM_INACTIVE_PRESENT_FLAG;
|
||||||
|
r = __dev_status(md, param);
|
||||||
|
|
||||||
|
out:
|
||||||
|
dm_put(md);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
|
#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)
|
||||||
|
|
||||||
struct dm_table {
|
struct dm_table {
|
||||||
|
struct mapped_device *md;
|
||||||
atomic_t holders;
|
atomic_t holders;
|
||||||
|
|
||||||
/* btree table */
|
/* btree table */
|
||||||
|
@ -206,7 +207,8 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_table_create(struct dm_table **result, int mode, unsigned num_targets)
|
int dm_table_create(struct dm_table **result, int mode,
|
||||||
|
unsigned num_targets, struct mapped_device *md)
|
||||||
{
|
{
|
||||||
struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
|
struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
|
||||||
|
|
||||||
|
@ -229,6 +231,7 @@ int dm_table_create(struct dm_table **result, int mode, unsigned num_targets)
|
||||||
}
|
}
|
||||||
|
|
||||||
t->mode = mode;
|
t->mode = mode;
|
||||||
|
t->md = md;
|
||||||
*result = t;
|
*result = t;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -952,12 +955,20 @@ int dm_table_flush_all(struct dm_table *t)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mapped_device *dm_table_get_md(struct dm_table *t)
|
||||||
|
{
|
||||||
|
dm_get(t->md);
|
||||||
|
|
||||||
|
return t->md;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(dm_vcalloc);
|
EXPORT_SYMBOL(dm_vcalloc);
|
||||||
EXPORT_SYMBOL(dm_get_device);
|
EXPORT_SYMBOL(dm_get_device);
|
||||||
EXPORT_SYMBOL(dm_put_device);
|
EXPORT_SYMBOL(dm_put_device);
|
||||||
EXPORT_SYMBOL(dm_table_event);
|
EXPORT_SYMBOL(dm_table_event);
|
||||||
EXPORT_SYMBOL(dm_table_get_size);
|
EXPORT_SYMBOL(dm_table_get_size);
|
||||||
EXPORT_SYMBOL(dm_table_get_mode);
|
EXPORT_SYMBOL(dm_table_get_mode);
|
||||||
|
EXPORT_SYMBOL(dm_table_get_md);
|
||||||
EXPORT_SYMBOL(dm_table_put);
|
EXPORT_SYMBOL(dm_table_put);
|
||||||
EXPORT_SYMBOL(dm_table_get);
|
EXPORT_SYMBOL(dm_table_get);
|
||||||
EXPORT_SYMBOL(dm_table_unplug_all);
|
EXPORT_SYMBOL(dm_table_unplug_all);
|
||||||
|
|
|
@ -1007,18 +1007,18 @@ void dm_get(struct mapped_device *md)
|
||||||
|
|
||||||
void dm_put(struct mapped_device *md)
|
void dm_put(struct mapped_device *md)
|
||||||
{
|
{
|
||||||
struct dm_table *map = dm_get_table(md);
|
struct dm_table *map;
|
||||||
|
|
||||||
if (atomic_dec_and_test(&md->holders)) {
|
if (atomic_dec_and_test(&md->holders)) {
|
||||||
|
map = dm_get_table(md);
|
||||||
if (!dm_suspended(md)) {
|
if (!dm_suspended(md)) {
|
||||||
dm_table_presuspend_targets(map);
|
dm_table_presuspend_targets(map);
|
||||||
dm_table_postsuspend_targets(map);
|
dm_table_postsuspend_targets(map);
|
||||||
}
|
}
|
||||||
__unbind(md);
|
__unbind(md);
|
||||||
|
dm_table_put(map);
|
||||||
free_dev(md);
|
free_dev(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_table_put(map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -89,7 +89,8 @@ int dm_suspended(struct mapped_device *md);
|
||||||
* Functions for manipulating a table. Tables are also reference
|
* Functions for manipulating a table. Tables are also reference
|
||||||
* counted.
|
* counted.
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
int dm_table_create(struct dm_table **result, int mode, unsigned num_targets);
|
int dm_table_create(struct dm_table **result, int mode,
|
||||||
|
unsigned num_targets, struct mapped_device *md);
|
||||||
|
|
||||||
void dm_table_get(struct dm_table *t);
|
void dm_table_get(struct dm_table *t);
|
||||||
void dm_table_put(struct dm_table *t);
|
void dm_table_put(struct dm_table *t);
|
||||||
|
@ -107,6 +108,7 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q);
|
||||||
unsigned int dm_table_get_num_targets(struct dm_table *t);
|
unsigned int dm_table_get_num_targets(struct dm_table *t);
|
||||||
struct list_head *dm_table_get_devices(struct dm_table *t);
|
struct list_head *dm_table_get_devices(struct dm_table *t);
|
||||||
int dm_table_get_mode(struct dm_table *t);
|
int dm_table_get_mode(struct dm_table *t);
|
||||||
|
struct mapped_device *dm_table_get_md(struct dm_table *t);
|
||||||
void dm_table_presuspend_targets(struct dm_table *t);
|
void dm_table_presuspend_targets(struct dm_table *t);
|
||||||
void dm_table_postsuspend_targets(struct dm_table *t);
|
void dm_table_postsuspend_targets(struct dm_table *t);
|
||||||
void dm_table_resume_targets(struct dm_table *t);
|
void dm_table_resume_targets(struct dm_table *t);
|
||||||
|
|
Loading…
Add table
Reference in a new issue