diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-03-17 11:21:20 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-17 11:21:20 -0400 |
| commit | 47239561e39bceefecc3cd67f71fcf86a198a8ff (patch) | |
| tree | 9823d0973494ea8acabb744bc3aba42b610fb434 /drivers/md | |
| parent | ed681a91ab805341675d166a9592551093c0a2d9 (diff) | |
| parent | 5bee17f18b595937e6beafeee5197868a3f74a06 (diff) | |
Merge branch 'linus' into core/printk
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/dm-io.c | 2 | ||||
| -rw-r--r-- | drivers/md/dm-kcopyd.c | 2 | ||||
| -rw-r--r-- | drivers/md/linear.c | 6 | ||||
| -rw-r--r-- | drivers/md/md.c | 58 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 6 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 19 |
6 files changed, 53 insertions, 40 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index a34338567a2a..f14813be4eff 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
| @@ -328,7 +328,7 @@ static void dispatch_io(int rw, unsigned int num_regions, | |||
| 328 | struct dpages old_pages = *dp; | 328 | struct dpages old_pages = *dp; |
| 329 | 329 | ||
| 330 | if (sync) | 330 | if (sync) |
| 331 | rw |= (1 << BIO_RW_SYNC); | 331 | rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); |
| 332 | 332 | ||
| 333 | /* | 333 | /* |
| 334 | * For multiple regions we need to be careful to rewind | 334 | * For multiple regions we need to be careful to rewind |
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index 3073618269ea..0a225da21272 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c | |||
| @@ -344,7 +344,7 @@ static int run_io_job(struct kcopyd_job *job) | |||
| 344 | { | 344 | { |
| 345 | int r; | 345 | int r; |
| 346 | struct dm_io_request io_req = { | 346 | struct dm_io_request io_req = { |
| 347 | .bi_rw = job->rw | (1 << BIO_RW_SYNC), | 347 | .bi_rw = job->rw | (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG), |
| 348 | .mem.type = DM_IO_PAGE_LIST, | 348 | .mem.type = DM_IO_PAGE_LIST, |
| 349 | .mem.ptr.pl = job->pages, | 349 | .mem.ptr.pl = job->pages, |
| 350 | .mem.offset = job->offset, | 350 | .mem.offset = job->offset, |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 1e3aea9eecf1..09658b218474 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
| @@ -25,13 +25,13 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector) | |||
| 25 | { | 25 | { |
| 26 | dev_info_t *hash; | 26 | dev_info_t *hash; |
| 27 | linear_conf_t *conf = mddev_to_conf(mddev); | 27 | linear_conf_t *conf = mddev_to_conf(mddev); |
| 28 | sector_t idx = sector >> conf->sector_shift; | ||
| 28 | 29 | ||
| 29 | /* | 30 | /* |
| 30 | * sector_div(a,b) returns the remainer and sets a to a/b | 31 | * sector_div(a,b) returns the remainer and sets a to a/b |
| 31 | */ | 32 | */ |
| 32 | sector >>= conf->sector_shift; | 33 | (void)sector_div(idx, conf->spacing); |
| 33 | (void)sector_div(sector, conf->spacing); | 34 | hash = conf->hash_table[idx]; |
| 34 | hash = conf->hash_table[sector]; | ||
| 35 | 35 | ||
| 36 | while (sector >= hash->num_sectors + hash->start_sector) | 36 | while (sector >= hash->num_sectors + hash->start_sector) |
| 37 | hash++; | 37 | hash++; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 41e2509bf896..a307f87eb90e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -214,12 +214,7 @@ static inline mddev_t *mddev_get(mddev_t *mddev) | |||
| 214 | return mddev; | 214 | return mddev; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| 217 | static void mddev_delayed_delete(struct work_struct *ws) | 217 | static void mddev_delayed_delete(struct work_struct *ws); |
| 218 | { | ||
| 219 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | ||
| 220 | kobject_del(&mddev->kobj); | ||
| 221 | kobject_put(&mddev->kobj); | ||
| 222 | } | ||
| 223 | 218 | ||
| 224 | static void mddev_put(mddev_t *mddev) | 219 | static void mddev_put(mddev_t *mddev) |
| 225 | { | 220 | { |
| @@ -474,7 +469,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
| 474 | * causes ENOTSUPP, we allocate a spare bio... | 469 | * causes ENOTSUPP, we allocate a spare bio... |
| 475 | */ | 470 | */ |
| 476 | struct bio *bio = bio_alloc(GFP_NOIO, 1); | 471 | struct bio *bio = bio_alloc(GFP_NOIO, 1); |
| 477 | int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC); | 472 | int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG); |
| 478 | 473 | ||
| 479 | bio->bi_bdev = rdev->bdev; | 474 | bio->bi_bdev = rdev->bdev; |
| 480 | bio->bi_sector = sector; | 475 | bio->bi_sector = sector; |
| @@ -531,7 +526,7 @@ int sync_page_io(struct block_device *bdev, sector_t sector, int size, | |||
| 531 | struct completion event; | 526 | struct completion event; |
| 532 | int ret; | 527 | int ret; |
| 533 | 528 | ||
| 534 | rw |= (1 << BIO_RW_SYNC); | 529 | rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG); |
| 535 | 530 | ||
| 536 | bio->bi_bdev = bdev; | 531 | bio->bi_bdev = bdev; |
| 537 | bio->bi_sector = sector; | 532 | bio->bi_sector = sector; |
| @@ -1481,6 +1476,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
| 1481 | if (find_rdev_nr(mddev, rdev->desc_nr)) | 1476 | if (find_rdev_nr(mddev, rdev->desc_nr)) |
| 1482 | return -EBUSY; | 1477 | return -EBUSY; |
| 1483 | } | 1478 | } |
| 1479 | if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { | ||
| 1480 | printk(KERN_WARNING "md: %s: array is limited to %d devices\n", | ||
| 1481 | mdname(mddev), mddev->max_disks); | ||
| 1482 | return -EBUSY; | ||
| 1483 | } | ||
| 1484 | bdevname(rdev->bdev,b); | 1484 | bdevname(rdev->bdev,b); |
| 1485 | while ( (s=strchr(b, '/')) != NULL) | 1485 | while ( (s=strchr(b, '/')) != NULL) |
| 1486 | *s = '!'; | 1486 | *s = '!'; |
| @@ -2441,6 +2441,15 @@ static void analyze_sbs(mddev_t * mddev) | |||
| 2441 | 2441 | ||
| 2442 | i = 0; | 2442 | i = 0; |
| 2443 | rdev_for_each(rdev, tmp, mddev) { | 2443 | rdev_for_each(rdev, tmp, mddev) { |
| 2444 | if (rdev->desc_nr >= mddev->max_disks || | ||
| 2445 | i > mddev->max_disks) { | ||
| 2446 | printk(KERN_WARNING | ||
| 2447 | "md: %s: %s: only %d devices permitted\n", | ||
| 2448 | mdname(mddev), bdevname(rdev->bdev, b), | ||
| 2449 | mddev->max_disks); | ||
| 2450 | kick_rdev_from_array(rdev); | ||
| 2451 | continue; | ||
| 2452 | } | ||
| 2444 | if (rdev != freshest) | 2453 | if (rdev != freshest) |
| 2445 | if (super_types[mddev->major_version]. | 2454 | if (super_types[mddev->major_version]. |
| 2446 | validate_super(mddev, rdev)) { | 2455 | validate_super(mddev, rdev)) { |
| @@ -3528,6 +3537,21 @@ static struct kobj_type md_ktype = { | |||
| 3528 | 3537 | ||
| 3529 | int mdp_major = 0; | 3538 | int mdp_major = 0; |
| 3530 | 3539 | ||
| 3540 | static void mddev_delayed_delete(struct work_struct *ws) | ||
| 3541 | { | ||
| 3542 | mddev_t *mddev = container_of(ws, mddev_t, del_work); | ||
| 3543 | |||
| 3544 | if (mddev->private == &md_redundancy_group) { | ||
| 3545 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | ||
| 3546 | if (mddev->sysfs_action) | ||
| 3547 | sysfs_put(mddev->sysfs_action); | ||
| 3548 | mddev->sysfs_action = NULL; | ||
| 3549 | mddev->private = NULL; | ||
| 3550 | } | ||
| 3551 | kobject_del(&mddev->kobj); | ||
| 3552 | kobject_put(&mddev->kobj); | ||
| 3553 | } | ||
| 3554 | |||
| 3531 | static int md_alloc(dev_t dev, char *name) | 3555 | static int md_alloc(dev_t dev, char *name) |
| 3532 | { | 3556 | { |
| 3533 | static DEFINE_MUTEX(disks_mutex); | 3557 | static DEFINE_MUTEX(disks_mutex); |
| @@ -4019,13 +4043,9 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
| 4019 | mddev->queue->merge_bvec_fn = NULL; | 4043 | mddev->queue->merge_bvec_fn = NULL; |
| 4020 | mddev->queue->unplug_fn = NULL; | 4044 | mddev->queue->unplug_fn = NULL; |
| 4021 | mddev->queue->backing_dev_info.congested_fn = NULL; | 4045 | mddev->queue->backing_dev_info.congested_fn = NULL; |
| 4022 | if (mddev->pers->sync_request) { | ||
| 4023 | sysfs_remove_group(&mddev->kobj, &md_redundancy_group); | ||
| 4024 | if (mddev->sysfs_action) | ||
| 4025 | sysfs_put(mddev->sysfs_action); | ||
| 4026 | mddev->sysfs_action = NULL; | ||
| 4027 | } | ||
| 4028 | module_put(mddev->pers->owner); | 4046 | module_put(mddev->pers->owner); |
| 4047 | if (mddev->pers->sync_request) | ||
| 4048 | mddev->private = &md_redundancy_group; | ||
| 4029 | mddev->pers = NULL; | 4049 | mddev->pers = NULL; |
| 4030 | /* tell userspace to handle 'inactive' */ | 4050 | /* tell userspace to handle 'inactive' */ |
| 4031 | sysfs_notify_dirent(mddev->sysfs_state); | 4051 | sysfs_notify_dirent(mddev->sysfs_state); |
| @@ -4614,13 +4634,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
| 4614 | * noticed in interrupt contexts ... | 4634 | * noticed in interrupt contexts ... |
| 4615 | */ | 4635 | */ |
| 4616 | 4636 | ||
| 4617 | if (rdev->desc_nr == mddev->max_disks) { | ||
| 4618 | printk(KERN_WARNING "%s: can not hot-add to full array!\n", | ||
| 4619 | mdname(mddev)); | ||
| 4620 | err = -EBUSY; | ||
| 4621 | goto abort_unbind_export; | ||
| 4622 | } | ||
| 4623 | |||
| 4624 | rdev->raid_disk = -1; | 4637 | rdev->raid_disk = -1; |
| 4625 | 4638 | ||
| 4626 | md_update_sb(mddev, 1); | 4639 | md_update_sb(mddev, 1); |
| @@ -4634,9 +4647,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev) | |||
| 4634 | md_new_event(mddev); | 4647 | md_new_event(mddev); |
| 4635 | return 0; | 4648 | return 0; |
| 4636 | 4649 | ||
| 4637 | abort_unbind_export: | ||
| 4638 | unbind_rdev_from_array(rdev); | ||
| 4639 | |||
| 4640 | abort_export: | 4650 | abort_export: |
| 4641 | export_rdev(rdev); | 4651 | export_rdev(rdev); |
| 4642 | return err; | 4652 | return err; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 7b4f5f7155d8..e2466425d9ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -1237,8 +1237,9 @@ static void end_sync_write(struct bio *bio, int error) | |||
| 1237 | update_head_pos(mirror, r1_bio); | 1237 | update_head_pos(mirror, r1_bio); |
| 1238 | 1238 | ||
| 1239 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 1239 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
| 1240 | md_done_sync(mddev, r1_bio->sectors, uptodate); | 1240 | sector_t s = r1_bio->sectors; |
| 1241 | put_buf(r1_bio); | 1241 | put_buf(r1_bio); |
| 1242 | md_done_sync(mddev, s, uptodate); | ||
| 1242 | } | 1243 | } |
| 1243 | } | 1244 | } |
| 1244 | 1245 | ||
| @@ -1640,7 +1641,8 @@ static void raid1d(mddev_t *mddev) | |||
| 1640 | } | 1641 | } |
| 1641 | 1642 | ||
| 1642 | bio = r1_bio->bios[r1_bio->read_disk]; | 1643 | bio = r1_bio->bios[r1_bio->read_disk]; |
| 1643 | if ((disk=read_balance(conf, r1_bio)) == -1) { | 1644 | if ((disk=read_balance(conf, r1_bio)) == -1 || |
| 1645 | disk == r1_bio->read_disk) { | ||
| 1644 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" | 1646 | printk(KERN_ALERT "raid1: %s: unrecoverable I/O" |
| 1645 | " read error for block %llu\n", | 1647 | " read error for block %llu\n", |
| 1646 | bdevname(bio->bi_bdev,b), | 1648 | bdevname(bio->bi_bdev,b), |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 6736d6dff981..7301631abe04 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -1236,6 +1236,7 @@ static void end_sync_read(struct bio *bio, int error) | |||
| 1236 | /* for reconstruct, we always reschedule after a read. | 1236 | /* for reconstruct, we always reschedule after a read. |
| 1237 | * for resync, only after all reads | 1237 | * for resync, only after all reads |
| 1238 | */ | 1238 | */ |
| 1239 | rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); | ||
| 1239 | if (test_bit(R10BIO_IsRecover, &r10_bio->state) || | 1240 | if (test_bit(R10BIO_IsRecover, &r10_bio->state) || |
| 1240 | atomic_dec_and_test(&r10_bio->remaining)) { | 1241 | atomic_dec_and_test(&r10_bio->remaining)) { |
| 1241 | /* we have read all the blocks, | 1242 | /* we have read all the blocks, |
| @@ -1243,7 +1244,6 @@ static void end_sync_read(struct bio *bio, int error) | |||
| 1243 | */ | 1244 | */ |
| 1244 | reschedule_retry(r10_bio); | 1245 | reschedule_retry(r10_bio); |
| 1245 | } | 1246 | } |
| 1246 | rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); | ||
| 1247 | } | 1247 | } |
| 1248 | 1248 | ||
| 1249 | static void end_sync_write(struct bio *bio, int error) | 1249 | static void end_sync_write(struct bio *bio, int error) |
| @@ -1264,11 +1264,13 @@ static void end_sync_write(struct bio *bio, int error) | |||
| 1264 | 1264 | ||
| 1265 | update_head_pos(i, r10_bio); | 1265 | update_head_pos(i, r10_bio); |
| 1266 | 1266 | ||
| 1267 | rdev_dec_pending(conf->mirrors[d].rdev, mddev); | ||
| 1267 | while (atomic_dec_and_test(&r10_bio->remaining)) { | 1268 | while (atomic_dec_and_test(&r10_bio->remaining)) { |
| 1268 | if (r10_bio->master_bio == NULL) { | 1269 | if (r10_bio->master_bio == NULL) { |
| 1269 | /* the primary of several recovery bios */ | 1270 | /* the primary of several recovery bios */ |
| 1270 | md_done_sync(mddev, r10_bio->sectors, 1); | 1271 | sector_t s = r10_bio->sectors; |
| 1271 | put_buf(r10_bio); | 1272 | put_buf(r10_bio); |
| 1273 | md_done_sync(mddev, s, 1); | ||
| 1272 | break; | 1274 | break; |
| 1273 | } else { | 1275 | } else { |
| 1274 | r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; | 1276 | r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; |
| @@ -1276,7 +1278,6 @@ static void end_sync_write(struct bio *bio, int error) | |||
| 1276 | r10_bio = r10_bio2; | 1278 | r10_bio = r10_bio2; |
| 1277 | } | 1279 | } |
| 1278 | } | 1280 | } |
| 1279 | rdev_dec_pending(conf->mirrors[d].rdev, mddev); | ||
| 1280 | } | 1281 | } |
| 1281 | 1282 | ||
| 1282 | /* | 1283 | /* |
| @@ -1749,8 +1750,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1749 | if (!go_faster && conf->nr_waiting) | 1750 | if (!go_faster && conf->nr_waiting) |
| 1750 | msleep_interruptible(1000); | 1751 | msleep_interruptible(1000); |
| 1751 | 1752 | ||
| 1752 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
| 1753 | |||
| 1754 | /* Again, very different code for resync and recovery. | 1753 | /* Again, very different code for resync and recovery. |
| 1755 | * Both must result in an r10bio with a list of bios that | 1754 | * Both must result in an r10bio with a list of bios that |
| 1756 | * have bi_end_io, bi_sector, bi_bdev set, | 1755 | * have bi_end_io, bi_sector, bi_bdev set, |
| @@ -1886,6 +1885,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 1886 | /* resync. Schedule a read for every block at this virt offset */ | 1885 | /* resync. Schedule a read for every block at this virt offset */ |
| 1887 | int count = 0; | 1886 | int count = 0; |
| 1888 | 1887 | ||
| 1888 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
| 1889 | |||
| 1889 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, | 1890 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, |
| 1890 | &sync_blocks, mddev->degraded) && | 1891 | &sync_blocks, mddev->degraded) && |
| 1891 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | 1892 | !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { |
| @@ -2010,13 +2011,13 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
| 2010 | /* There is nowhere to write, so all non-sync | 2011 | /* There is nowhere to write, so all non-sync |
| 2011 | * drives must be failed, so try the next chunk... | 2012 | * drives must be failed, so try the next chunk... |
| 2012 | */ | 2013 | */ |
| 2013 | { | 2014 | if (sector_nr + max_sync < max_sector) |
| 2014 | sector_t sec = max_sector - sector_nr; | 2015 | max_sector = sector_nr + max_sync; |
| 2015 | sectors_skipped += sec; | 2016 | |
| 2017 | sectors_skipped += (max_sector - sector_nr); | ||
| 2016 | chunks_skipped ++; | 2018 | chunks_skipped ++; |
| 2017 | sector_nr = max_sector; | 2019 | sector_nr = max_sector; |
| 2018 | goto skipped; | 2020 | goto skipped; |
| 2019 | } | ||
| 2020 | } | 2021 | } |
| 2021 | 2022 | ||
| 2022 | static int run(mddev_t *mddev) | 2023 | static int run(mddev_t *mddev) |
