Commit 1134e5ae authored by Mike Anderson's avatar Mike Anderson Committed by Linus Torvalds
Browse files

[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: default avatarMike Anderson <andmike@us.ibm.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 9ade92a9
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -244,9 +244,9 @@ static void __hash_remove(struct hash_cell *hc)
		dm_table_put(table);
	}

	dm_put(hc->md);
	if (hc->new_map)
		dm_table_put(hc->new_map);
	dm_put(hc->md);
	free_cell(hc);
}

@@ -985,33 +985,43 @@ static int table_load(struct dm_ioctl *param, size_t param_size)
	int r;
	struct hash_cell *hc;
	struct dm_table *t;
	struct mapped_device *md;

	md = find_device(param);
	if (!md)
		return -ENXIO;

	r = dm_table_create(&t, get_mode(param), param->target_count);
	r = dm_table_create(&t, get_mode(param), param->target_count, md);
	if (r)
		return r;
		goto out;

	r = populate_table(t, param, param_size);
	if (r) {
		dm_table_put(t);
		return r;
		goto out;
	}

	down_write(&_hash_lock);
	hc = __find_device_hash_cell(param);
	if (!hc) {
		DMWARN("device doesn't appear to be in the dev hash table.");
		up_write(&_hash_lock);
	hc = dm_get_mdptr(md);
	if (!hc || hc->md != md) {
		DMWARN("device has been removed from the dev hash table.");
		dm_table_put(t);
		return -ENXIO;
		up_write(&_hash_lock);
		r = -ENXIO;
		goto out;
	}

	if (hc->new_map)
		dm_table_put(hc->new_map);
	hc->new_map = t;
	up_write(&_hash_lock);

	param->flags |= DM_INACTIVE_PRESENT_FLAG;
	r = __dev_status(md, param);

out:
	dm_put(md);

	r = __dev_status(hc->md, param);
	up_write(&_hash_lock);
	return r;
}

+12 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1)

struct dm_table {
	struct mapped_device *md;
	atomic_t holders;

	/* btree table */
@@ -206,7 +207,8 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
	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);

@@ -229,6 +231,7 @@ int dm_table_create(struct dm_table **result, int mode, unsigned num_targets)
	}

	t->mode = mode;
	t->md = md;
	*result = t;
	return 0;
}
@@ -952,12 +955,20 @@ int dm_table_flush_all(struct dm_table *t)
	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_get_device);
EXPORT_SYMBOL(dm_put_device);
EXPORT_SYMBOL(dm_table_event);
EXPORT_SYMBOL(dm_table_get_size);
EXPORT_SYMBOL(dm_table_get_mode);
EXPORT_SYMBOL(dm_table_get_md);
EXPORT_SYMBOL(dm_table_put);
EXPORT_SYMBOL(dm_table_get);
EXPORT_SYMBOL(dm_table_unplug_all);
+3 −3
Original line number Diff line number Diff line
@@ -1007,18 +1007,18 @@ void dm_get(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)) {
		map = dm_get_table(md);
		if (!dm_suspended(md)) {
			dm_table_presuspend_targets(map);
			dm_table_postsuspend_targets(map);
		}
		__unbind(md);
		dm_table_put(map);
		free_dev(md);
	}

	dm_table_put(map);
}

/*
+3 −1
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ int dm_suspended(struct mapped_device *md);
 * Functions for manipulating a table.  Tables are also reference
 * 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_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);
struct list_head *dm_table_get_devices(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_postsuspend_targets(struct dm_table *t);
void dm_table_resume_targets(struct dm_table *t);