Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'md-3.9-fixes' of git://neil.brown.name/md

Pull md fixes from NeilBrown:
"A few bugfixes for md

- recent regressions in raid5
- recent regressions in dmraid
- a few instances of CONFIG_MULTICORE_RAID456 linger

Several tagged for -stable"

* tag 'md-3.9-fixes' of git://neil.brown.name/md:
md: remove CONFIG_MULTICORE_RAID456 entirely
md/raid5: ensure sync and DISCARD don't happen at the same time.
MD: Prevent sysfs operations on uninitialized kobjects
MD RAID5: Avoid accessing gendisk or queue structs when not available
md/raid5: schedule_construction should abort if nothing to do.

+86 -47
-1
arch/tile/configs/tilegx_defconfig
··· 330 330 CONFIG_MD_RAID1=m 331 331 CONFIG_MD_RAID10=m 332 332 CONFIG_MD_RAID456=m 333 - CONFIG_MULTICORE_RAID456=y 334 333 CONFIG_MD_FAULTY=m 335 334 CONFIG_BLK_DEV_DM=m 336 335 CONFIG_DM_DEBUG=y
-1
arch/tile/configs/tilepro_defconfig
··· 324 324 CONFIG_MD_RAID1=m 325 325 CONFIG_MD_RAID10=m 326 326 CONFIG_MD_RAID456=m 327 - CONFIG_MULTICORE_RAID456=y 328 327 CONFIG_MD_FAULTY=m 329 328 CONFIG_BLK_DEV_DM=m 330 329 CONFIG_DM_DEBUG=y
+2 -4
drivers/md/md.c
··· 7663 7663 removed++; 7664 7664 } 7665 7665 } 7666 - if (removed) 7667 - sysfs_notify(&mddev->kobj, NULL, 7668 - "degraded"); 7669 - 7666 + if (removed && mddev->kobj.sd) 7667 + sysfs_notify(&mddev->kobj, NULL, "degraded"); 7670 7668 7671 7669 rdev_for_each(rdev, mddev) { 7672 7670 if (rdev->raid_disk >= 0 &&
+2 -2
drivers/md/md.h
··· 506 506 static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) 507 507 { 508 508 char nm[20]; 509 - if (!test_bit(Replacement, &rdev->flags)) { 509 + if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { 510 510 sprintf(nm, "rd%d", rdev->raid_disk); 511 511 return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); 512 512 } else ··· 516 516 static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) 517 517 { 518 518 char nm[20]; 519 - if (!test_bit(Replacement, &rdev->flags)) { 519 + if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { 520 520 sprintf(nm, "rd%d", rdev->raid_disk); 521 521 sysfs_remove_link(&mddev->kobj, nm); 522 522 }
+81 -35
drivers/md/raid5.c
··· 671 671 bi->bi_next = NULL; 672 672 if (rrdev) 673 673 set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); 674 - trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), 675 - bi, disk_devt(conf->mddev->gendisk), 676 - sh->dev[i].sector); 674 + 675 + if (conf->mddev->gendisk) 676 + trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), 677 + bi, disk_devt(conf->mddev->gendisk), 678 + sh->dev[i].sector); 677 679 generic_make_request(bi); 678 680 } 679 681 if (rrdev) { ··· 703 701 rbi->bi_io_vec[0].bv_offset = 0; 704 702 rbi->bi_size = STRIPE_SIZE; 705 703 rbi->bi_next = NULL; 706 - trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), 707 - rbi, disk_devt(conf->mddev->gendisk), 708 - sh->dev[i].sector); 704 + if (conf->mddev->gendisk) 705 + trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), 706 + rbi, disk_devt(conf->mddev->gendisk), 707 + sh->dev[i].sector); 709 708 generic_make_request(rbi); 710 709 } 711 710 if (!rdev && !rrdev) { ··· 2283 2280 int level = conf->level; 2284 2281 2285 2282 if (rcw) { 2286 - /* if we are not expanding this is a proper write request, and 2287 - * there will be bios with new data to be drained into the 2288 - * stripe cache 2289 - */ 2290 - if (!expand) { 2291 - sh->reconstruct_state = reconstruct_state_drain_run; 2292 - set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); 2293 - } else 2294 - sh->reconstruct_state = reconstruct_state_run; 2295 - 2296 - set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); 2297 2283 2298 2284 for (i = disks; i--; ) { 2299 2285 struct r5dev *dev = &sh->dev[i]; ··· 2295 2303 s->locked++; 2296 2304 } 2297 2305 } 2306 + /* if we are not expanding this is a proper write request, and 2307 + * there will be bios with new data to be drained into the 2308 + * stripe cache 2309 + */ 2310 + if (!expand) { 2311 + if (!s->locked) 2312 + /* False alarm, nothing to do */ 2313 + return; 2314 + sh->reconstruct_state = reconstruct_state_drain_run; 2315 + set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); 2316 + } else 2317 + sh->reconstruct_state = reconstruct_state_run; 2318 + 2319 + set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); 2320 + 2298 2321 if (s->locked + conf->max_degraded == disks) 2299 2322 if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) 2300 2323 atomic_inc(&conf->pending_full_writes); ··· 2317 2310 BUG_ON(level == 6); 2318 2311 BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || 2319 2312 test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); 2320 - 2321 - sh->reconstruct_state = reconstruct_state_prexor_drain_run; 2322 - set_bit(STRIPE_OP_PREXOR, &s->ops_request); 2323 - set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); 2324 - set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); 2325 2313 2326 2314 for (i = disks; i--; ) { 2327 2315 struct r5dev *dev = &sh->dev[i]; ··· 2332 2330 s->locked++; 2333 2331 } 2334 2332 } 2333 + if (!s->locked) 2334 + /* False alarm - nothing to do */ 2335 + return; 2336 + sh->reconstruct_state = reconstruct_state_prexor_drain_run; 2337 + set_bit(STRIPE_OP_PREXOR, &s->ops_request); 2338 + set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); 2339 + set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); 2335 2340 } 2336 2341 2337 2342 /* keep the parity disk(s) locked while asynchronous operations ··· 2573 2564 int i; 2574 2565 2575 2566 clear_bit(STRIPE_SYNCING, &sh->state); 2567 + if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) 2568 + wake_up(&conf->wait_for_overlap); 2576 2569 s->syncing = 0; 2577 2570 s->replacing = 0; 2578 2571 /* There is nothing more to do for sync/check/repair. ··· 2748 2737 { 2749 2738 int i; 2750 2739 struct r5dev *dev; 2740 + int discard_pending = 0; 2751 2741 2752 2742 for (i = disks; i--; ) 2753 2743 if (sh->dev[i].written) { ··· 2777 2765 STRIPE_SECTORS, 2778 2766 !test_bit(STRIPE_DEGRADED, &sh->state), 2779 2767 0); 2780 - } 2781 - } else if (test_bit(R5_Discard, &sh->dev[i].flags)) 2782 - clear_bit(R5_Discard, &sh->dev[i].flags); 2768 + } else if (test_bit(R5_Discard, &dev->flags)) 2769 + discard_pending = 1; 2770 + } 2771 + if (!discard_pending && 2772 + test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) { 2773 + clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags); 2774 + clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); 2775 + if (sh->qd_idx >= 0) { 2776 + clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags); 2777 + clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags); 2778 + } 2779 + /* now that discard is done we can proceed with any sync */ 2780 + clear_bit(STRIPE_DISCARD, &sh->state); 2781 + if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) 2782 + set_bit(STRIPE_HANDLE, &sh->state); 2783 + 2784 + } 2783 2785 2784 2786 if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) 2785 2787 if (atomic_dec_and_test(&conf->pending_full_writes)) ··· 2852 2826 set_bit(STRIPE_HANDLE, &sh->state); 2853 2827 if (rmw < rcw && rmw > 0) { 2854 2828 /* prefer read-modify-write, but need to get some data */ 2855 - blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d", 2856 - (unsigned long long)sh->sector, rmw); 2829 + if (conf->mddev->queue) 2830 + blk_add_trace_msg(conf->mddev->queue, 2831 + "raid5 rmw %llu %d", 2832 + (unsigned long long)sh->sector, rmw); 2857 2833 for (i = disks; i--; ) { 2858 2834 struct r5dev *dev = &sh->dev[i]; 2859 2835 if ((dev->towrite || i == sh->pd_idx) && ··· 2905 2877 } 2906 2878 } 2907 2879 } 2908 - if (rcw) 2880 + if (rcw && conf->mddev->queue) 2909 2881 blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d", 2910 2882 (unsigned long long)sh->sector, 2911 2883 rcw, qread, test_bit(STRIPE_DELAYED, &sh->state)); ··· 3445 3417 return; 3446 3418 } 3447 3419 3448 - if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { 3449 - set_bit(STRIPE_SYNCING, &sh->state); 3450 - clear_bit(STRIPE_INSYNC, &sh->state); 3420 + if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { 3421 + spin_lock(&sh->stripe_lock); 3422 + /* Cannot process 'sync' concurrently with 'discard' */ 3423 + if (!test_bit(STRIPE_DISCARD, &sh->state) && 3424 + test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { 3425 + set_bit(STRIPE_SYNCING, &sh->state); 3426 + clear_bit(STRIPE_INSYNC, &sh->state); 3427 + } 3428 + spin_unlock(&sh->stripe_lock); 3451 3429 } 3452 3430 clear_bit(STRIPE_DELAYED, &sh->state); 3453 3431 ··· 3613 3579 test_bit(STRIPE_INSYNC, &sh->state)) { 3614 3580 md_done_sync(conf->mddev, STRIPE_SECTORS, 1); 3615 3581 clear_bit(STRIPE_SYNCING, &sh->state); 3582 + if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) 3583 + wake_up(&conf->wait_for_overlap); 3616 3584 } 3617 3585 3618 3586 /* If the failed drives are just a ReadError, then we might need ··· 4018 3982 atomic_inc(&conf->active_aligned_reads); 4019 3983 spin_unlock_irq(&conf->device_lock); 4020 3984 4021 - trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), 4022 - align_bi, disk_devt(mddev->gendisk), 4023 - raid_bio->bi_sector); 3985 + if (mddev->gendisk) 3986 + trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), 3987 + align_bi, disk_devt(mddev->gendisk), 3988 + raid_bio->bi_sector); 4024 3989 generic_make_request(align_bi); 4025 3990 return 1; 4026 3991 } else { ··· 4115 4078 } 4116 4079 spin_unlock_irq(&conf->device_lock); 4117 4080 } 4118 - trace_block_unplug(mddev->queue, cnt, !from_schedule); 4081 + if (mddev->queue) 4082 + trace_block_unplug(mddev->queue, cnt, !from_schedule); 4119 4083 kfree(cb); 4120 4084 } 4121 4085 ··· 4179 4141 sh = get_active_stripe(conf, logical_sector, 0, 0, 0); 4180 4142 prepare_to_wait(&conf->wait_for_overlap, &w, 4181 4143 TASK_UNINTERRUPTIBLE); 4144 + set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); 4145 + if (test_bit(STRIPE_SYNCING, &sh->state)) { 4146 + release_stripe(sh); 4147 + schedule(); 4148 + goto again; 4149 + } 4150 + clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); 4182 4151 spin_lock_irq(&sh->stripe_lock); 4183 4152 for (d = 0; d < conf->raid_disks; d++) { 4184 4153 if (d == sh->pd_idx || d == sh->qd_idx) ··· 4198 4153 goto again; 4199 4154 } 4200 4155 } 4156 + set_bit(STRIPE_DISCARD, &sh->state); 4201 4157 finish_wait(&conf->wait_for_overlap, &w); 4202 4158 for (d = 0; d < conf->raid_disks; d++) { 4203 4159 if (d == sh->pd_idx || d == sh->qd_idx)
+1 -4
drivers/md/raid5.h
··· 221 221 struct stripe_operations { 222 222 int target, target2; 223 223 enum sum_check_flags zero_sum_result; 224 - #ifdef CONFIG_MULTICORE_RAID456 225 - unsigned long request; 226 - wait_queue_head_t wait_for_ops; 227 - #endif 228 224 } ops; 229 225 struct r5dev { 230 226 /* rreq and rvec are used for the replacement device when ··· 319 323 STRIPE_COMPUTE_RUN, 320 324 STRIPE_OPS_REQ_PENDING, 321 325 STRIPE_ON_UNPLUG_LIST, 326 + STRIPE_DISCARD, 322 327 }; 323 328 324 329 /*