diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/linear.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 01ed03a0c7ee..1dadb134e0bb 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -42,7 +42,7 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
42 | (void)sector_div(block, conf->hash_spacing); | 42 | (void)sector_div(block, conf->hash_spacing); |
43 | hash = conf->hash_table[block]; | 43 | hash = conf->hash_table[block]; |
44 | 44 | ||
45 | while ((sector>>1) >= (hash->size + hash->offset)) | 45 | while (sector >= hash->num_sectors + hash->start_sector) |
46 | hash++; | 46 | hash++; |
47 | return hash; | 47 | return hash; |
48 | } | 48 | } |
@@ -65,7 +65,7 @@ static int linear_mergeable_bvec(struct request_queue *q, | |||
65 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); | 65 | sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); |
66 | 66 | ||
67 | dev0 = which_dev(mddev, sector); | 67 | dev0 = which_dev(mddev, sector); |
68 | maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1)); | 68 | maxsectors = dev0->num_sectors - (sector - dev0->start_sector); |
69 | 69 | ||
70 | if (maxsectors < bio_sectors) | 70 | if (maxsectors < bio_sectors) |
71 | maxsectors = 0; | 71 | maxsectors = 0; |
@@ -113,7 +113,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
113 | mdk_rdev_t *rdev; | 113 | mdk_rdev_t *rdev; |
114 | int i, nb_zone, cnt; | 114 | int i, nb_zone, cnt; |
115 | sector_t min_spacing; | 115 | sector_t min_spacing; |
116 | sector_t curr_offset; | 116 | sector_t curr_sector; |
117 | struct list_head *tmp; | 117 | struct list_head *tmp; |
118 | 118 | ||
119 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), | 119 | conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t), |
@@ -145,7 +145,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
145 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) | 145 | mddev->queue->max_sectors > (PAGE_SIZE>>9)) |
146 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); | 146 | blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); |
147 | 147 | ||
148 | disk->size = rdev->size; | 148 | disk->num_sectors = rdev->size * 2; |
149 | conf->array_sectors += rdev->size * 2; | 149 | conf->array_sectors += rdev->size * 2; |
150 | 150 | ||
151 | cnt++; | 151 | cnt++; |
@@ -169,7 +169,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
169 | sector_t sz = 0; | 169 | sector_t sz = 0; |
170 | int j; | 170 | int j; |
171 | for (j = i; j < cnt - 1 && sz < min_spacing; j++) | 171 | for (j = i; j < cnt - 1 && sz < min_spacing; j++) |
172 | sz += conf->disks[j].size; | 172 | sz += conf->disks[j].num_sectors / 2; |
173 | if (sz >= min_spacing && sz < conf->hash_spacing) | 173 | if (sz >= min_spacing && sz < conf->hash_spacing) |
174 | conf->hash_spacing = sz; | 174 | conf->hash_spacing = sz; |
175 | } | 175 | } |
@@ -211,20 +211,20 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
211 | * Here we generate the linear hash table | 211 | * Here we generate the linear hash table |
212 | * First calculate the device offsets. | 212 | * First calculate the device offsets. |
213 | */ | 213 | */ |
214 | conf->disks[0].offset = 0; | 214 | conf->disks[0].start_sector = 0; |
215 | for (i = 1; i < raid_disks; i++) | 215 | for (i = 1; i < raid_disks; i++) |
216 | conf->disks[i].offset = | 216 | conf->disks[i].start_sector = |
217 | conf->disks[i-1].offset + | 217 | conf->disks[i-1].start_sector + |
218 | conf->disks[i-1].size; | 218 | conf->disks[i-1].num_sectors; |
219 | 219 | ||
220 | table = conf->hash_table; | 220 | table = conf->hash_table; |
221 | i = 0; | 221 | i = 0; |
222 | for (curr_offset = 0; | 222 | for (curr_sector = 0; |
223 | curr_offset < conf->array_sectors / 2; | 223 | curr_sector < conf->array_sectors; |
224 | curr_offset += conf->hash_spacing) { | 224 | curr_sector += conf->hash_spacing * 2) { |
225 | 225 | ||
226 | while (i < raid_disks-1 && | 226 | while (i < raid_disks-1 && |
227 | curr_offset >= conf->disks[i+1].offset) | 227 | curr_sector >= conf->disks[i+1].start_sector) |
228 | i++; | 228 | i++; |
229 | 229 | ||
230 | *table ++ = conf->disks + i; | 230 | *table ++ = conf->disks + i; |
@@ -316,7 +316,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
316 | const int rw = bio_data_dir(bio); | 316 | const int rw = bio_data_dir(bio); |
317 | mddev_t *mddev = q->queuedata; | 317 | mddev_t *mddev = q->queuedata; |
318 | dev_info_t *tmp_dev; | 318 | dev_info_t *tmp_dev; |
319 | sector_t block; | ||
320 | int cpu; | 319 | int cpu; |
321 | 320 | ||
322 | if (unlikely(bio_barrier(bio))) { | 321 | if (unlikely(bio_barrier(bio))) { |
@@ -331,29 +330,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
331 | part_stat_unlock(); | 330 | part_stat_unlock(); |
332 | 331 | ||
333 | tmp_dev = which_dev(mddev, bio->bi_sector); | 332 | tmp_dev = which_dev(mddev, bio->bi_sector); |
334 | block = bio->bi_sector >> 1; | ||
335 | 333 | ||
336 | if (unlikely(block >= (tmp_dev->size + tmp_dev->offset) | 334 | if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors + |
337 | || block < tmp_dev->offset)) { | 335 | tmp_dev->start_sector) |
336 | || (bio->bi_sector < | ||
337 | tmp_dev->start_sector))) { | ||
338 | char b[BDEVNAME_SIZE]; | 338 | char b[BDEVNAME_SIZE]; |
339 | 339 | ||
340 | printk("linear_make_request: Block %llu out of bounds on " | 340 | printk("linear_make_request: Sector %llu out of bounds on " |
341 | "dev %s size %llu offset %llu\n", | 341 | "dev %s: %llu sectors, offset %llu\n", |
342 | (unsigned long long)block, | 342 | (unsigned long long)bio->bi_sector, |
343 | bdevname(tmp_dev->rdev->bdev, b), | 343 | bdevname(tmp_dev->rdev->bdev, b), |
344 | (unsigned long long)tmp_dev->size, | 344 | (unsigned long long)tmp_dev->num_sectors, |
345 | (unsigned long long)tmp_dev->offset); | 345 | (unsigned long long)tmp_dev->start_sector); |
346 | bio_io_error(bio); | 346 | bio_io_error(bio); |
347 | return 0; | 347 | return 0; |
348 | } | 348 | } |
349 | if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > | 349 | if (unlikely(bio->bi_sector + (bio->bi_size >> 9) > |
350 | (tmp_dev->offset + tmp_dev->size)<<1)) { | 350 | tmp_dev->start_sector + tmp_dev->num_sectors)) { |
351 | /* This bio crosses a device boundary, so we have to | 351 | /* This bio crosses a device boundary, so we have to |
352 | * split it. | 352 | * split it. |
353 | */ | 353 | */ |
354 | struct bio_pair *bp; | 354 | struct bio_pair *bp; |
355 | |||
355 | bp = bio_split(bio, | 356 | bp = bio_split(bio, |
356 | ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); | 357 | tmp_dev->start_sector + tmp_dev->num_sectors |
358 | - bio->bi_sector); | ||
359 | |||
357 | if (linear_make_request(q, &bp->bio1)) | 360 | if (linear_make_request(q, &bp->bio1)) |
358 | generic_make_request(&bp->bio1); | 361 | generic_make_request(&bp->bio1); |
359 | if (linear_make_request(q, &bp->bio2)) | 362 | if (linear_make_request(q, &bp->bio2)) |
@@ -363,7 +366,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio) | |||
363 | } | 366 | } |
364 | 367 | ||
365 | bio->bi_bdev = tmp_dev->rdev->bdev; | 368 | bio->bi_bdev = tmp_dev->rdev->bdev; |
366 | bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset; | 369 | bio->bi_sector = bio->bi_sector - tmp_dev->start_sector |
370 | + tmp_dev->rdev->data_offset; | ||
367 | 371 | ||
368 | return 1; | 372 | return 1; |
369 | } | 373 | } |