From 9ade92a9a5b0a3a10efa6551b8c67a9277bf0438 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Mon, 27 Mar 2006 01:17:53 -0800 Subject: [PATCH] dm: tidy mdptr Change dm_get_mdptr() to take a struct mapped_device instead of dev_t. Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-ioctl.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/md/dm-ioctl.c') diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 442e2be6052e..0693b6f54b7d 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -600,12 +600,22 @@ static int dev_create(struct dm_ioctl *param, size_t param_size) */ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) { + struct mapped_device *md; + void *mdptr = NULL; + if (*param->uuid) return __get_uuid_cell(param->uuid); - else if (*param->name) + + if (*param->name) return __get_name_cell(param->name); - else - return dm_get_mdptr(huge_decode_dev(param->dev)); + + md = dm_get_md(huge_decode_dev(param->dev)); + if (md) { + mdptr = dm_get_mdptr(md); + dm_put(md); + } + + return mdptr; } static struct mapped_device *find_device(struct dm_ioctl *param) -- cgit v1.2.2 From 1134e5ae79bab61c05657ca35a6297cf87202e35 Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Mon, 27 Mar 2006 01:17:54 -0800 Subject: [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 Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-ioctl.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'drivers/md/dm-ioctl.c') diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 0693b6f54b7d..65826bdac00c 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -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; } -- cgit v1.2.2 From 3ac51e741a46af7a20f55e79d3e3aeaa93c6c544 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Mon, 27 Mar 2006 01:17:54 -0800 Subject: [PATCH] dm store geometry Allow drive geometry to be stored with a new DM_DEV_SET_GEOMETRY ioctl. Device-mapper will now respond to HDIO_GETGEO. If the geometry information is not available, zero will be returned for all of the parameters. Signed-off-by: Darrick J. Wong Signed-off-by: Alasdair G Kergon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/dm-ioctl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'drivers/md/dm-ioctl.c') diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 65826bdac00c..8edd6435414d 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -700,6 +701,54 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size) return dm_hash_rename(param->name, new_name); } +static int dev_set_geometry(struct dm_ioctl *param, size_t param_size) +{ + int r = -EINVAL, x; + struct mapped_device *md; + struct hd_geometry geometry; + unsigned long indata[4]; + char *geostr = (char *) param + param->data_start; + + md = find_device(param); + if (!md) + return -ENXIO; + + if (geostr < (char *) (param + 1) || + invalid_str(geostr, (void *) param + param_size)) { + DMWARN("Invalid geometry supplied."); + goto out; + } + + x = sscanf(geostr, "%lu %lu %lu %lu", indata, + indata + 1, indata + 2, indata + 3); + + if (x != 4) { + DMWARN("Unable to interpret geometry settings."); + goto out; + } + + if (indata[0] > 65535 || indata[1] > 255 || + indata[2] > 255 || indata[3] > ULONG_MAX) { + DMWARN("Geometry exceeds range limits."); + goto out; + } + + geometry.cylinders = indata[0]; + geometry.heads = indata[1]; + geometry.sectors = indata[2]; + geometry.start = indata[3]; + + r = dm_set_geometry(md, &geometry); + if (!r) + r = __dev_status(md, param); + + param->data_size = 0; + +out: + dm_put(md); + return r; +} + static int do_suspend(struct dm_ioctl *param) { int r = 0; @@ -1234,7 +1283,8 @@ static ioctl_fn lookup_ioctl(unsigned int cmd) {DM_LIST_VERSIONS_CMD, list_versions}, - {DM_TARGET_MSG_CMD, target_message} + {DM_TARGET_MSG_CMD, target_message}, + {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} }; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn; -- cgit v1.2.2