diff options
| -rw-r--r-- | drivers/md/linear.c | 35 | ||||
| -rw-r--r-- | include/linux/raid/linear.h | 6 |
2 files changed, 21 insertions, 20 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 13e928bde7cd..09a64b9cbde8 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
| @@ -33,14 +33,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
| 33 | { | 33 | { |
| 34 | dev_info_t *hash; | 34 | dev_info_t *hash; |
| 35 | linear_conf_t *conf = mddev_to_conf(mddev); | 35 | linear_conf_t *conf = mddev_to_conf(mddev); |
| 36 | sector_t block = sector >> 1; | ||
| 37 | 36 | ||
| 38 | /* | 37 | /* |
| 39 | * sector_div(a,b) returns the remainer and sets a to a/b | 38 | * sector_div(a,b) returns the remainer and sets a to a/b |
| 40 | */ | 39 | */ |
| 41 | block >>= conf->preshift; | 40 | sector >>= conf->sector_shift; |
| 42 | (void)sector_div(block, conf->hash_spacing); | 41 | (void)sector_div(sector, conf->spacing); |
| 43 | hash = conf->hash_table[block]; | 42 | hash = conf->hash_table[sector]; |
| 44 | 43 | ||
| 45 | while (sector >= hash->num_sectors + hash->start_sector) | 44 | while (sector >= hash->num_sectors + hash->start_sector) |
| 46 | hash++; | 45 | hash++; |
| @@ -164,25 +163,25 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 164 | * that is larger than min_sectors and use the size of that as | 163 | * that is larger than min_sectors and use the size of that as |
| 165 | * the actual spacing | 164 | * the actual spacing |
| 166 | */ | 165 | */ |
| 167 | conf->hash_spacing = conf->array_sectors / 2; | 166 | conf->spacing = conf->array_sectors; |
| 168 | for (i=0; i < cnt-1 ; i++) { | 167 | for (i=0; i < cnt-1 ; i++) { |
| 169 | sector_t tmp = 0; | 168 | sector_t tmp = 0; |
| 170 | int j; | 169 | int j; |
| 171 | for (j = i; j < cnt - 1 && tmp < min_sectors; j++) | 170 | for (j = i; j < cnt - 1 && tmp < min_sectors; j++) |
| 172 | tmp += conf->disks[j].num_sectors; | 171 | tmp += conf->disks[j].num_sectors; |
| 173 | if (tmp >= min_sectors && tmp < conf->hash_spacing * 2) | 172 | if (tmp >= min_sectors && tmp < conf->spacing) |
| 174 | conf->hash_spacing = tmp / 2; | 173 | conf->spacing = tmp; |
| 175 | } | 174 | } |
| 176 | 175 | ||
| 177 | /* hash_spacing may be too large for sector_div to work with, | 176 | /* spacing may be too large for sector_div to work with, |
| 178 | * so we might need to pre-shift | 177 | * so we might need to pre-shift |
| 179 | */ | 178 | */ |
| 180 | conf->preshift = 0; | 179 | conf->sector_shift = 0; |
| 181 | if (sizeof(sector_t) > sizeof(u32)) { | 180 | if (sizeof(sector_t) > sizeof(u32)) { |
| 182 | sector_t space = conf->hash_spacing; | 181 | sector_t space = conf->spacing; |
| 183 | while (space > (sector_t)(~(u32)0)) { | 182 | while (space > (sector_t)(~(u32)0)) { |
| 184 | space >>= 1; | 183 | space >>= 1; |
| 185 | conf->preshift++; | 184 | conf->sector_shift++; |
| 186 | } | 185 | } |
| 187 | } | 186 | } |
| 188 | /* | 187 | /* |
| @@ -194,9 +193,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 194 | unsigned round; | 193 | unsigned round; |
| 195 | unsigned long base; | 194 | unsigned long base; |
| 196 | 195 | ||
| 197 | sz = conf->array_sectors >> (conf->preshift + 1); | 196 | sz = conf->array_sectors >> conf->sector_shift; |
| 198 | sz += 1; /* force round-up */ | 197 | sz += 1; /* force round-up */ |
| 199 | base = conf->hash_spacing >> conf->preshift; | 198 | base = conf->spacing >> conf->sector_shift; |
| 200 | round = sector_div(sz, base); | 199 | round = sector_div(sz, base); |
| 201 | nb_zone = sz + (round ? 1 : 0); | 200 | nb_zone = sz + (round ? 1 : 0); |
| 202 | } | 201 | } |
| @@ -221,7 +220,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 221 | i = 0; | 220 | i = 0; |
| 222 | for (curr_sector = 0; | 221 | for (curr_sector = 0; |
| 223 | curr_sector < conf->array_sectors; | 222 | curr_sector < conf->array_sectors; |
| 224 | curr_sector += conf->hash_spacing * 2) { | 223 | curr_sector += conf->spacing) { |
| 225 | 224 | ||
| 226 | while (i < raid_disks-1 && | 225 | while (i < raid_disks-1 && |
| 227 | curr_sector >= conf->disks[i+1].start_sector) | 226 | curr_sector >= conf->disks[i+1].start_sector) |
| @@ -230,12 +229,12 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
| 230 | *table ++ = conf->disks + i; | 229 | *table ++ = conf->disks + i; |
| 231 | } | 230 | } |
| 232 | 231 | ||
| 233 | if (conf->preshift) { | 232 | if (conf->sector_shift) { |
| 234 | conf->hash_spacing >>= conf->preshift; | 233 | conf->spacing >>= conf->sector_shift; |
| 235 | /* round hash_spacing up so that when we divide by it, | 234 | /* round spacing up so that when we divide by it, |
| 236 | * we err on the side of "too-low", which is safest. | 235 | * we err on the side of "too-low", which is safest. |
| 237 | */ | 236 | */ |
| 238 | conf->hash_spacing++; | 237 | conf->spacing++; |
| 239 | } | 238 | } |
| 240 | 239 | ||
| 241 | BUG_ON(table - conf->hash_table > nb_zone); | 240 | BUG_ON(table - conf->hash_table > nb_zone); |
diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h index 87090e98529f..f38b9c586afb 100644 --- a/include/linux/raid/linear.h +++ b/include/linux/raid/linear.h | |||
| @@ -15,9 +15,11 @@ struct linear_private_data | |||
| 15 | { | 15 | { |
| 16 | struct linear_private_data *prev; /* earlier version */ | 16 | struct linear_private_data *prev; /* earlier version */ |
| 17 | dev_info_t **hash_table; | 17 | dev_info_t **hash_table; |
| 18 | sector_t hash_spacing; | 18 | sector_t spacing; |
| 19 | sector_t array_sectors; | 19 | sector_t array_sectors; |
| 20 | int preshift; /* shift before dividing by hash_spacing */ | 20 | int sector_shift; /* shift before dividing |
| 21 | * by spacing | ||
| 22 | */ | ||
| 21 | dev_info_t disks[0]; | 23 | dev_info_t disks[0]; |
| 22 | }; | 24 | }; |
| 23 | 25 | ||
