Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3620a3a authored by Jonathan Brassow's avatar Jonathan Brassow Committed by NeilBrown
Browse files

MD RAID5: Avoid accessing gendisk or queue structs when not available



MD RAID5:  Fix kernel oops when RAID4/5/6 is used via device-mapper

Commit a9add5d9 (v3.8-rc1) added blktrace calls to the RAID4/5/6 driver.
However, when device-mapper is used to create RAID4/5/6 arrays, the
mddev->gendisk and mddev->queue fields are not setup.  Therefore, calling
things like trace_block_bio_remap will cause a kernel oops.  This patch
conditionalizes those calls on whether the proper fields exist to make
the calls.  (Device-mapper will call trace_block_bio_remap on its own.)

This patch is suitable for the 3.8.y stable kernel.

Cc: stable@vger.kernel.org (v3.8+)
Signed-off-by: default avatarJonathan Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent ce7d363a
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -674,6 +674,8 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
			bi->bi_next = NULL;
			if (rrdev)
				set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);

			if (conf->mddev->gendisk)
				trace_block_bio_remap(bdev_get_queue(bi->bi_bdev),
						      bi, disk_devt(conf->mddev->gendisk),
						      sh->dev[i].sector);
@@ -704,6 +706,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
			rbi->bi_io_vec[0].bv_offset = 0;
			rbi->bi_size = STRIPE_SIZE;
			rbi->bi_next = NULL;
			if (conf->mddev->gendisk)
				trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
						      rbi, disk_devt(conf->mddev->gendisk),
						      sh->dev[i].sector);
@@ -2835,7 +2838,9 @@ static void handle_stripe_dirtying(struct r5conf *conf,
	set_bit(STRIPE_HANDLE, &sh->state);
	if (rmw < rcw && rmw > 0) {
		/* prefer read-modify-write, but need to get some data */
		blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d",
		if (conf->mddev->queue)
			blk_add_trace_msg(conf->mddev->queue,
					  "raid5 rmw %llu %d",
					  (unsigned long long)sh->sector, rmw);
		for (i = disks; i--; ) {
			struct r5dev *dev = &sh->dev[i];
@@ -2886,7 +2891,7 @@ static void handle_stripe_dirtying(struct r5conf *conf,
				}
			}
		}
		if (rcw)
		if (rcw && conf->mddev->queue)
			blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d",
					  (unsigned long long)sh->sector,
					  rcw, qread, test_bit(STRIPE_DELAYED, &sh->state));
@@ -3993,6 +3998,7 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio)
		atomic_inc(&conf->active_aligned_reads);
		spin_unlock_irq(&conf->device_lock);

		if (mddev->gendisk)
			trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev),
					      align_bi, disk_devt(mddev->gendisk),
					      raid_bio->bi_sector);
@@ -4089,6 +4095,7 @@ static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule)
		}
		spin_unlock_irq(&conf->device_lock);
	}
	if (mddev->queue)
		trace_block_unplug(mddev->queue, cnt, !from_schedule);
	kfree(cb);
}