X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmd%2Fdm-ioctl.c;h=442e2be6052e330f283379b3cc9eb02f7a5855df;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=f7e743691aa8198d03293e8e04b9195c54c757fa;hpb=9464c7cf61b9433057924c36e6e02f303a00e768;p=linux-2.6.git diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index f7e743691..442e2be60 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -15,7 +15,6 @@ #include #include #include -#include #include @@ -102,10 +101,8 @@ static struct hash_cell *__get_name_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _name_buckets + h, name_list) - if (!strcmp(hc->name, str)) { - dm_get(hc->md); + if (!strcmp(hc->name, str)) return hc; - } return NULL; } @@ -116,10 +113,8 @@ static struct hash_cell *__get_uuid_cell(const char *str) unsigned int h = hash_str(str); list_for_each_entry (hc, _uuid_buckets + h, uuid_list) - if (!strcmp(hc->uuid, str)) { - dm_get(hc->md); + if (!strcmp(hc->uuid, str)) return hc; - } return NULL; } @@ -195,7 +190,7 @@ static int unregister_with_devfs(struct hash_cell *hc) */ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_device *md) { - struct hash_cell *cell, *hc; + struct hash_cell *cell; /* * Allocate the new cells. @@ -208,19 +203,14 @@ static int dm_hash_insert(const char *name, const char *uuid, struct mapped_devi * Insert the cell into both hash tables. */ down_write(&_hash_lock); - hc = __get_name_cell(name); - if (hc) { - dm_put(hc->md); + if (__get_name_cell(name)) goto bad; - } list_add(&cell->name_list, _name_buckets + hash_str(name)); if (uuid) { - hc = __get_uuid_cell(uuid); - if (hc) { + if (__get_uuid_cell(uuid)) { list_del(&cell->name_list); - dm_put(hc->md); goto bad; } list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid)); @@ -254,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); } @@ -298,7 +288,6 @@ static int dm_hash_rename(const char *old, const char *new) if (hc) { DMWARN("asked to rename to an already existing name %s -> %s", old, new); - dm_put(hc->md); up_write(&_hash_lock); kfree(new_name); return -EBUSY; @@ -338,7 +327,6 @@ static int dm_hash_rename(const char *old, const char *new) dm_table_put(table); } - dm_put(hc->md); up_write(&_hash_lock); kfree(old_name); return 0; @@ -612,20 +600,12 @@ 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); - - if (*param->name) + else if (*param->name) return __get_name_cell(param->name); - - md = dm_get_md(huge_decode_dev(param->dev)); - if (md) - mdptr = dm_get_mdptr(md); - - return mdptr; + else + return dm_get_mdptr(huge_decode_dev(param->dev)); } static struct mapped_device *find_device(struct dm_ioctl *param) @@ -637,6 +617,7 @@ static struct mapped_device *find_device(struct dm_ioctl *param) hc = __find_device_hash_cell(param); if (hc) { md = hc->md; + dm_get(md); /* * Sneakily write in both the name and the uuid @@ -661,7 +642,6 @@ static struct mapped_device *find_device(struct dm_ioctl *param) static int dev_remove(struct dm_ioctl *param, size_t param_size) { struct hash_cell *hc; - struct mapped_device *md; down_write(&_hash_lock); hc = __find_device_hash_cell(param); @@ -672,11 +652,8 @@ static int dev_remove(struct dm_ioctl *param, size_t param_size) return -ENXIO; } - md = hc->md; - __hash_remove(hc); up_write(&_hash_lock); - dm_put(md); param->data_size = 0; return 0; } @@ -713,54 +690,6 @@ 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; @@ -802,6 +731,7 @@ static int do_resume(struct dm_ioctl *param) } md = hc->md; + dm_get(md); new_map = hc->new_map; hc->new_map = NULL; @@ -1045,43 +975,33 @@ 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, md); + r = dm_table_create(&t, get_mode(param), param->target_count); if (r) - goto out; + return r; r = populate_table(t, param, param_size); if (r) { dm_table_put(t); - goto out; + return r; } down_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); + hc = __find_device_hash_cell(param); + if (!hc) { + DMWARN("device doesn't appear to be in the dev hash table."); up_write(&_hash_lock); - r = -ENXIO; - goto out; + dm_table_put(t); + return -ENXIO; } 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; } @@ -1089,7 +1009,6 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) { int r; struct hash_cell *hc; - struct mapped_device *md; down_write(&_hash_lock); @@ -1108,9 +1027,7 @@ static int table_clear(struct dm_ioctl *param, size_t param_size) param->flags &= ~DM_INACTIVE_PRESENT_FLAG; r = __dev_status(hc->md, param); - md = hc->md; up_write(&_hash_lock); - dm_put(md); return r; } @@ -1297,8 +1214,7 @@ static ioctl_fn lookup_ioctl(unsigned int cmd) {DM_LIST_VERSIONS_CMD, list_versions}, - {DM_TARGET_MSG_CMD, target_message}, - {DM_DEV_SET_GEOMETRY_CMD, dev_set_geometry} + {DM_TARGET_MSG_CMD, target_message} }; return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;