summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kwolek <adam.kwolek@intel.com>2011-02-03 17:02:39 +1100
committerNeilBrown <neilb@suse.de>2011-02-03 17:02:39 +1100
commit5e7b0330669594ee79201d19ff45a7850fa0f951 (patch)
treebf9d83efad62a620d988d42966c6eb22930f40f4
parenta201e6803f622d6f780edcabaaa6a3986485000b (diff)
imsm: FIX: crash during getting map
When get_imsm_map() is called with second_map parameter == '-1' and array is not in migration state NULL pointer is returned. This is wrong. '-1' means return map as migration record points. '-1' can be passed to get_imsm_map() from imsm_num_data_members(). imsm_num_data_members() is called to get current map members based on migr_state information Signed-off-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--super-intel.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/super-intel.c b/super-intel.c
index 84ab47b3..4081071c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -565,17 +565,24 @@ static size_t sizeof_imsm_map(struct imsm_map *map)
struct imsm_map *get_imsm_map(struct imsm_dev *dev, int second_map)
{
+ /* A device can have 2 maps if it is in the middle of a migration.
+ * If second_map is:
+ * 0 - we return the first map
+ * 1 - we return the second map if it exists, else NULL
+ * -1 - we return the second map if it exists, else the first
+ */
struct imsm_map *map = &dev->vol.map[0];
- if (second_map && !dev->vol.migr_state)
+ if (second_map == 1 && !dev->vol.migr_state)
return NULL;
- else if (second_map) {
+ else if (second_map == 1 ||
+ (second_map < 0 && dev->vol.migr_state)) {
void *ptr = map;
return ptr + sizeof_imsm_map(map);
} else
return map;
-
+
}
/* return the size of the device.
@@ -654,14 +661,7 @@ static __u32 get_imsm_ord_tbl_ent(struct imsm_dev *dev,
{
struct imsm_map *map;
- if (second_map == -1) {
- if (dev->vol.migr_state)
- map = get_imsm_map(dev, 1);
- else
- map = get_imsm_map(dev, 0);
- } else {
- map = get_imsm_map(dev, second_map);
- }
+ map = get_imsm_map(dev, second_map);
/* top byte identifies disk under rebuild */
return __le32_to_cpu(map->disk_ord_tbl[slot]);