diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /drivers/md | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/super.c | 14 | ||||
-rw-r--r-- | drivers/md/dm-crypt.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-flakey.c | 27 | ||||
-rw-r--r-- | drivers/md/dm-log.c | 11 | ||||
-rw-r--r-- | drivers/md/dm-raid.c | 82 | ||||
-rw-r--r-- | drivers/md/dm-round-robin.c | 7 |
6 files changed, 85 insertions, 58 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 95a4ca6ce6ff..849ad441cd76 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -760,7 +760,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size, | |||
760 | if (!d->nr_stripes || | 760 | if (!d->nr_stripes || |
761 | d->nr_stripes > INT_MAX || | 761 | d->nr_stripes > INT_MAX || |
762 | d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) { | 762 | d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) { |
763 | pr_err("nr_stripes too large"); | 763 | pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)", |
764 | (unsigned)d->nr_stripes); | ||
764 | return -ENOMEM; | 765 | return -ENOMEM; |
765 | } | 766 | } |
766 | 767 | ||
@@ -1820,7 +1821,7 @@ static int cache_alloc(struct cache *ca) | |||
1820 | free = roundup_pow_of_two(ca->sb.nbuckets) >> 10; | 1821 | free = roundup_pow_of_two(ca->sb.nbuckets) >> 10; |
1821 | 1822 | ||
1822 | if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || | 1823 | if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || |
1823 | !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || | 1824 | !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || |
1824 | !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || | 1825 | !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || |
1825 | !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || | 1826 | !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || |
1826 | !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || | 1827 | !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || |
@@ -1844,7 +1845,7 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1844 | struct block_device *bdev, struct cache *ca) | 1845 | struct block_device *bdev, struct cache *ca) |
1845 | { | 1846 | { |
1846 | char name[BDEVNAME_SIZE]; | 1847 | char name[BDEVNAME_SIZE]; |
1847 | const char *err = NULL; | 1848 | const char *err = NULL; /* must be set for any error case */ |
1848 | int ret = 0; | 1849 | int ret = 0; |
1849 | 1850 | ||
1850 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); | 1851 | memcpy(&ca->sb, sb, sizeof(struct cache_sb)); |
@@ -1861,8 +1862,13 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page, | |||
1861 | ca->discard = CACHE_DISCARD(&ca->sb); | 1862 | ca->discard = CACHE_DISCARD(&ca->sb); |
1862 | 1863 | ||
1863 | ret = cache_alloc(ca); | 1864 | ret = cache_alloc(ca); |
1864 | if (ret != 0) | 1865 | if (ret != 0) { |
1866 | if (ret == -ENOMEM) | ||
1867 | err = "cache_alloc(): -ENOMEM"; | ||
1868 | else | ||
1869 | err = "cache_alloc(): unknown error"; | ||
1865 | goto err; | 1870 | goto err; |
1871 | } | ||
1866 | 1872 | ||
1867 | if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) { | 1873 | if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) { |
1868 | err = "error calling kobject_add"; | 1874 | err = "error calling kobject_add"; |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 4e9784b4e0ac..eedba67b0e3e 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -181,7 +181,7 @@ struct crypt_config { | |||
181 | u8 key[0]; | 181 | u8 key[0]; |
182 | }; | 182 | }; |
183 | 183 | ||
184 | #define MIN_IOS 16 | 184 | #define MIN_IOS 64 |
185 | 185 | ||
186 | static void clone_init(struct dm_crypt_io *, struct bio *); | 186 | static void clone_init(struct dm_crypt_io *, struct bio *); |
187 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); | 187 | static void kcryptd_queue_crypt(struct dm_crypt_io *io); |
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 97e446d54a15..6a2e8dd44a1b 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
@@ -289,15 +289,13 @@ static int flakey_map(struct dm_target *ti, struct bio *bio) | |||
289 | pb->bio_submitted = true; | 289 | pb->bio_submitted = true; |
290 | 290 | ||
291 | /* | 291 | /* |
292 | * Map reads as normal only if corrupt_bio_byte set. | 292 | * Error reads if neither corrupt_bio_byte or drop_writes are set. |
293 | * Otherwise, flakey_end_io() will decide if the reads should be modified. | ||
293 | */ | 294 | */ |
294 | if (bio_data_dir(bio) == READ) { | 295 | if (bio_data_dir(bio) == READ) { |
295 | /* If flags were specified, only corrupt those that match. */ | 296 | if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags)) |
296 | if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && | ||
297 | all_corrupt_bio_flags_match(bio, fc)) | ||
298 | goto map_bio; | ||
299 | else | ||
300 | return -EIO; | 297 | return -EIO; |
298 | goto map_bio; | ||
301 | } | 299 | } |
302 | 300 | ||
303 | /* | 301 | /* |
@@ -334,14 +332,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error) | |||
334 | struct flakey_c *fc = ti->private; | 332 | struct flakey_c *fc = ti->private; |
335 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); | 333 | struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); |
336 | 334 | ||
337 | /* | ||
338 | * Corrupt successful READs while in down state. | ||
339 | */ | ||
340 | if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { | 335 | if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { |
341 | if (fc->corrupt_bio_byte) | 336 | if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && |
337 | all_corrupt_bio_flags_match(bio, fc)) { | ||
338 | /* | ||
339 | * Corrupt successful matching READs while in down state. | ||
340 | */ | ||
342 | corrupt_bio_data(bio, fc); | 341 | corrupt_bio_data(bio, fc); |
343 | else | 342 | |
343 | } else if (!test_bit(DROP_WRITES, &fc->flags)) { | ||
344 | /* | ||
345 | * Error read during the down_interval if drop_writes | ||
346 | * wasn't configured. | ||
347 | */ | ||
344 | return -EIO; | 348 | return -EIO; |
349 | } | ||
345 | } | 350 | } |
346 | 351 | ||
347 | return error; | 352 | return error; |
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 4ca2d1df5b44..07fc1ad42ec5 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
@@ -291,9 +291,10 @@ static void header_from_disk(struct log_header_core *core, struct log_header_dis | |||
291 | core->nr_regions = le64_to_cpu(disk->nr_regions); | 291 | core->nr_regions = le64_to_cpu(disk->nr_regions); |
292 | } | 292 | } |
293 | 293 | ||
294 | static int rw_header(struct log_c *lc, int rw) | 294 | static int rw_header(struct log_c *lc, int op) |
295 | { | 295 | { |
296 | lc->io_req.bi_op = rw; | 296 | lc->io_req.bi_op = op; |
297 | lc->io_req.bi_op_flags = 0; | ||
297 | 298 | ||
298 | return dm_io(&lc->io_req, 1, &lc->header_location, NULL); | 299 | return dm_io(&lc->io_req, 1, &lc->header_location, NULL); |
299 | } | 300 | } |
@@ -316,7 +317,7 @@ static int read_header(struct log_c *log) | |||
316 | { | 317 | { |
317 | int r; | 318 | int r; |
318 | 319 | ||
319 | r = rw_header(log, READ); | 320 | r = rw_header(log, REQ_OP_READ); |
320 | if (r) | 321 | if (r) |
321 | return r; | 322 | return r; |
322 | 323 | ||
@@ -630,7 +631,7 @@ static int disk_resume(struct dm_dirty_log *log) | |||
630 | header_to_disk(&lc->header, lc->disk_header); | 631 | header_to_disk(&lc->header, lc->disk_header); |
631 | 632 | ||
632 | /* write the new header */ | 633 | /* write the new header */ |
633 | r = rw_header(lc, WRITE); | 634 | r = rw_header(lc, REQ_OP_WRITE); |
634 | if (!r) { | 635 | if (!r) { |
635 | r = flush_header(lc); | 636 | r = flush_header(lc); |
636 | if (r) | 637 | if (r) |
@@ -698,7 +699,7 @@ static int disk_flush(struct dm_dirty_log *log) | |||
698 | log_clear_bit(lc, lc->clean_bits, i); | 699 | log_clear_bit(lc, lc->clean_bits, i); |
699 | } | 700 | } |
700 | 701 | ||
701 | r = rw_header(lc, WRITE); | 702 | r = rw_header(lc, REQ_OP_WRITE); |
702 | if (r) | 703 | if (r) |
703 | fail_log_device(lc); | 704 | fail_log_device(lc); |
704 | else { | 705 | else { |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 1b9795d75ef8..8abde6b8cedc 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -191,7 +191,6 @@ struct raid_dev { | |||
191 | #define RT_FLAG_RS_BITMAP_LOADED 2 | 191 | #define RT_FLAG_RS_BITMAP_LOADED 2 |
192 | #define RT_FLAG_UPDATE_SBS 3 | 192 | #define RT_FLAG_UPDATE_SBS 3 |
193 | #define RT_FLAG_RESHAPE_RS 4 | 193 | #define RT_FLAG_RESHAPE_RS 4 |
194 | #define RT_FLAG_KEEP_RS_FROZEN 5 | ||
195 | 194 | ||
196 | /* Array elements of 64 bit needed for rebuild/failed disk bits */ | 195 | /* Array elements of 64 bit needed for rebuild/failed disk bits */ |
197 | #define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8) | 196 | #define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8) |
@@ -861,6 +860,9 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size) | |||
861 | { | 860 | { |
862 | unsigned long min_region_size = rs->ti->len / (1 << 21); | 861 | unsigned long min_region_size = rs->ti->len / (1 << 21); |
863 | 862 | ||
863 | if (rs_is_raid0(rs)) | ||
864 | return 0; | ||
865 | |||
864 | if (!region_size) { | 866 | if (!region_size) { |
865 | /* | 867 | /* |
866 | * Choose a reasonable default. All figures in sectors. | 868 | * Choose a reasonable default. All figures in sectors. |
@@ -930,6 +932,8 @@ static int validate_raid_redundancy(struct raid_set *rs) | |||
930 | rebuild_cnt++; | 932 | rebuild_cnt++; |
931 | 933 | ||
932 | switch (rs->raid_type->level) { | 934 | switch (rs->raid_type->level) { |
935 | case 0: | ||
936 | break; | ||
933 | case 1: | 937 | case 1: |
934 | if (rebuild_cnt >= rs->md.raid_disks) | 938 | if (rebuild_cnt >= rs->md.raid_disks) |
935 | goto too_many; | 939 | goto too_many; |
@@ -2335,6 +2339,13 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) | |||
2335 | case 0: | 2339 | case 0: |
2336 | break; | 2340 | break; |
2337 | default: | 2341 | default: |
2342 | /* | ||
2343 | * We have to keep any raid0 data/metadata device pairs or | ||
2344 | * the MD raid0 personality will fail to start the array. | ||
2345 | */ | ||
2346 | if (rs_is_raid0(rs)) | ||
2347 | continue; | ||
2348 | |||
2338 | dev = container_of(rdev, struct raid_dev, rdev); | 2349 | dev = container_of(rdev, struct raid_dev, rdev); |
2339 | if (dev->meta_dev) | 2350 | if (dev->meta_dev) |
2340 | dm_put_device(ti, dev->meta_dev); | 2351 | dm_put_device(ti, dev->meta_dev); |
@@ -2579,7 +2590,6 @@ static int rs_prepare_reshape(struct raid_set *rs) | |||
2579 | } else { | 2590 | } else { |
2580 | /* Process raid1 without delta_disks */ | 2591 | /* Process raid1 without delta_disks */ |
2581 | mddev->raid_disks = rs->raid_disks; | 2592 | mddev->raid_disks = rs->raid_disks; |
2582 | set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags); | ||
2583 | reshape = false; | 2593 | reshape = false; |
2584 | } | 2594 | } |
2585 | } else { | 2595 | } else { |
@@ -2590,7 +2600,6 @@ static int rs_prepare_reshape(struct raid_set *rs) | |||
2590 | if (reshape) { | 2600 | if (reshape) { |
2591 | set_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags); | 2601 | set_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags); |
2592 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); | 2602 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); |
2593 | set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags); | ||
2594 | } else if (mddev->raid_disks < rs->raid_disks) | 2603 | } else if (mddev->raid_disks < rs->raid_disks) |
2595 | /* Create new superblocks and bitmaps, if any new disks */ | 2604 | /* Create new superblocks and bitmaps, if any new disks */ |
2596 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); | 2605 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); |
@@ -2902,7 +2911,6 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
2902 | goto bad; | 2911 | goto bad; |
2903 | 2912 | ||
2904 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); | 2913 | set_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags); |
2905 | set_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags); | ||
2906 | /* Takeover ain't recovery, so disable recovery */ | 2914 | /* Takeover ain't recovery, so disable recovery */ |
2907 | rs_setup_recovery(rs, MaxSector); | 2915 | rs_setup_recovery(rs, MaxSector); |
2908 | rs_set_new(rs); | 2916 | rs_set_new(rs); |
@@ -3386,21 +3394,28 @@ static void raid_postsuspend(struct dm_target *ti) | |||
3386 | { | 3394 | { |
3387 | struct raid_set *rs = ti->private; | 3395 | struct raid_set *rs = ti->private; |
3388 | 3396 | ||
3389 | if (test_and_clear_bit(RT_FLAG_RS_RESUMED, &rs->runtime_flags)) { | 3397 | if (!rs->md.suspended) |
3390 | if (!rs->md.suspended) | 3398 | mddev_suspend(&rs->md); |
3391 | mddev_suspend(&rs->md); | 3399 | |
3392 | rs->md.ro = 1; | 3400 | rs->md.ro = 1; |
3393 | } | ||
3394 | } | 3401 | } |
3395 | 3402 | ||
3396 | static void attempt_restore_of_faulty_devices(struct raid_set *rs) | 3403 | static void attempt_restore_of_faulty_devices(struct raid_set *rs) |
3397 | { | 3404 | { |
3398 | int i; | 3405 | int i; |
3399 | uint64_t failed_devices, cleared_failed_devices = 0; | 3406 | uint64_t cleared_failed_devices[DISKS_ARRAY_ELEMS]; |
3400 | unsigned long flags; | 3407 | unsigned long flags; |
3408 | bool cleared = false; | ||
3401 | struct dm_raid_superblock *sb; | 3409 | struct dm_raid_superblock *sb; |
3410 | struct mddev *mddev = &rs->md; | ||
3402 | struct md_rdev *r; | 3411 | struct md_rdev *r; |
3403 | 3412 | ||
3413 | /* RAID personalities have to provide hot add/remove methods or we need to bail out. */ | ||
3414 | if (!mddev->pers || !mddev->pers->hot_add_disk || !mddev->pers->hot_remove_disk) | ||
3415 | return; | ||
3416 | |||
3417 | memset(cleared_failed_devices, 0, sizeof(cleared_failed_devices)); | ||
3418 | |||
3404 | for (i = 0; i < rs->md.raid_disks; i++) { | 3419 | for (i = 0; i < rs->md.raid_disks; i++) { |
3405 | r = &rs->dev[i].rdev; | 3420 | r = &rs->dev[i].rdev; |
3406 | if (test_bit(Faulty, &r->flags) && r->sb_page && | 3421 | if (test_bit(Faulty, &r->flags) && r->sb_page && |
@@ -3420,7 +3435,7 @@ static void attempt_restore_of_faulty_devices(struct raid_set *rs) | |||
3420 | * ourselves. | 3435 | * ourselves. |
3421 | */ | 3436 | */ |
3422 | if ((r->raid_disk >= 0) && | 3437 | if ((r->raid_disk >= 0) && |
3423 | (r->mddev->pers->hot_remove_disk(r->mddev, r) != 0)) | 3438 | (mddev->pers->hot_remove_disk(mddev, r) != 0)) |
3424 | /* Failed to revive this device, try next */ | 3439 | /* Failed to revive this device, try next */ |
3425 | continue; | 3440 | continue; |
3426 | 3441 | ||
@@ -3430,22 +3445,30 @@ static void attempt_restore_of_faulty_devices(struct raid_set *rs) | |||
3430 | clear_bit(Faulty, &r->flags); | 3445 | clear_bit(Faulty, &r->flags); |
3431 | clear_bit(WriteErrorSeen, &r->flags); | 3446 | clear_bit(WriteErrorSeen, &r->flags); |
3432 | clear_bit(In_sync, &r->flags); | 3447 | clear_bit(In_sync, &r->flags); |
3433 | if (r->mddev->pers->hot_add_disk(r->mddev, r)) { | 3448 | if (mddev->pers->hot_add_disk(mddev, r)) { |
3434 | r->raid_disk = -1; | 3449 | r->raid_disk = -1; |
3435 | r->saved_raid_disk = -1; | 3450 | r->saved_raid_disk = -1; |
3436 | r->flags = flags; | 3451 | r->flags = flags; |
3437 | } else { | 3452 | } else { |
3438 | r->recovery_offset = 0; | 3453 | r->recovery_offset = 0; |
3439 | cleared_failed_devices |= 1 << i; | 3454 | set_bit(i, (void *) cleared_failed_devices); |
3455 | cleared = true; | ||
3440 | } | 3456 | } |
3441 | } | 3457 | } |
3442 | } | 3458 | } |
3443 | if (cleared_failed_devices) { | 3459 | |
3460 | /* If any failed devices could be cleared, update all sbs failed_devices bits */ | ||
3461 | if (cleared) { | ||
3462 | uint64_t failed_devices[DISKS_ARRAY_ELEMS]; | ||
3463 | |||
3444 | rdev_for_each(r, &rs->md) { | 3464 | rdev_for_each(r, &rs->md) { |
3445 | sb = page_address(r->sb_page); | 3465 | sb = page_address(r->sb_page); |
3446 | failed_devices = le64_to_cpu(sb->failed_devices); | 3466 | sb_retrieve_failed_devices(sb, failed_devices); |
3447 | failed_devices &= ~cleared_failed_devices; | 3467 | |
3448 | sb->failed_devices = cpu_to_le64(failed_devices); | 3468 | for (i = 0; i < DISKS_ARRAY_ELEMS; i++) |
3469 | failed_devices[i] &= ~cleared_failed_devices[i]; | ||
3470 | |||
3471 | sb_update_failed_devices(sb, failed_devices); | ||
3449 | } | 3472 | } |
3450 | } | 3473 | } |
3451 | } | 3474 | } |
@@ -3610,26 +3633,15 @@ static void raid_resume(struct dm_target *ti) | |||
3610 | * devices are reachable again. | 3633 | * devices are reachable again. |
3611 | */ | 3634 | */ |
3612 | attempt_restore_of_faulty_devices(rs); | 3635 | attempt_restore_of_faulty_devices(rs); |
3613 | } else { | 3636 | } |
3614 | mddev->ro = 0; | ||
3615 | mddev->in_sync = 0; | ||
3616 | 3637 | ||
3617 | /* | 3638 | mddev->ro = 0; |
3618 | * When passing in flags to the ctr, we expect userspace | 3639 | mddev->in_sync = 0; |
3619 | * to reset them because they made it to the superblocks | ||
3620 | * and reload the mapping anyway. | ||
3621 | * | ||
3622 | * -> only unfreeze recovery in case of a table reload or | ||
3623 | * we'll have a bogus recovery/reshape position | ||
3624 | * retrieved from the superblock by the ctr because | ||
3625 | * the ongoing recovery/reshape will change it after read. | ||
3626 | */ | ||
3627 | if (!test_bit(RT_FLAG_KEEP_RS_FROZEN, &rs->runtime_flags)) | ||
3628 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | ||
3629 | 3640 | ||
3630 | if (mddev->suspended) | 3641 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
3631 | mddev_resume(mddev); | 3642 | |
3632 | } | 3643 | if (mddev->suspended) |
3644 | mddev_resume(mddev); | ||
3633 | } | 3645 | } |
3634 | 3646 | ||
3635 | static struct target_type raid_target = { | 3647 | static struct target_type raid_target = { |
diff --git a/drivers/md/dm-round-robin.c b/drivers/md/dm-round-robin.c index 4ace1da17db8..6c25213ab38c 100644 --- a/drivers/md/dm-round-robin.c +++ b/drivers/md/dm-round-robin.c | |||
@@ -210,14 +210,17 @@ static struct dm_path *rr_select_path(struct path_selector *ps, size_t nr_bytes) | |||
210 | struct path_info *pi = NULL; | 210 | struct path_info *pi = NULL; |
211 | struct dm_path *current_path = NULL; | 211 | struct dm_path *current_path = NULL; |
212 | 212 | ||
213 | local_irq_save(flags); | ||
213 | current_path = *this_cpu_ptr(s->current_path); | 214 | current_path = *this_cpu_ptr(s->current_path); |
214 | if (current_path) { | 215 | if (current_path) { |
215 | percpu_counter_dec(&s->repeat_count); | 216 | percpu_counter_dec(&s->repeat_count); |
216 | if (percpu_counter_read_positive(&s->repeat_count) > 0) | 217 | if (percpu_counter_read_positive(&s->repeat_count) > 0) { |
218 | local_irq_restore(flags); | ||
217 | return current_path; | 219 | return current_path; |
220 | } | ||
218 | } | 221 | } |
219 | 222 | ||
220 | spin_lock_irqsave(&s->lock, flags); | 223 | spin_lock(&s->lock); |
221 | if (!list_empty(&s->valid_paths)) { | 224 | if (!list_empty(&s->valid_paths)) { |
222 | pi = list_entry(s->valid_paths.next, struct path_info, list); | 225 | pi = list_entry(s->valid_paths.next, struct path_info, list); |
223 | list_move_tail(&pi->list, &s->valid_paths); | 226 | list_move_tail(&pi->list, &s->valid_paths); |