When stacking request-based DM on blk_mq device, request cloning and
remapping are done in a single call to target's clone_and_map_rq().
The clone is allocated and valid only if clone_and_map_rq() returns
DM_MAPIO_REMAPPED.
The "IS_ERR(clone)" check in map_request() does not cover all the
!DM_MAPIO_REMAPPED cases that are possible (E.g. if underlying devices
are not ready or unavailable, clone_and_map_rq() may return
DM_MAPIO_REQUEUE without ever having established an ERR_PTR). Fix this
by explicitly checking for a return that is not DM_MAPIO_REMAPPED in
map_request().
Without this fix, DM core may call setup_clone() for a NULL clone
and oops like this:
BUG: unable to handle kernel NULL pointer dereference at
0000000000000068
IP: [<
ffffffff81227525>] blk_rq_prep_clone+0x7d/0x137
...
CPU: 2 PID: 5793 Comm: kdmwork-253:3 Not tainted 4.0.0-nm #1
...
Call Trace:
[<
ffffffffa01d1c09>] map_tio_request+0xa9/0x258 [dm_mod]
[<
ffffffff81071de9>] kthread_worker_fn+0xfd/0x150
[<
ffffffff81071cec>] ? kthread_parkme+0x24/0x24
[<
ffffffff81071cec>] ? kthread_parkme+0x24/0x24
[<
ffffffff81071fdd>] kthread+0xe6/0xee
[<
ffffffff81093a59>] ? put_lock_stats+0xe/0x20
[<
ffffffff81071ef7>] ? __init_kthread_worker+0x5b/0x5b
[<
ffffffff814c2d98>] ret_from_fork+0x58/0x90
[<
ffffffff81071ef7>] ? __init_kthread_worker+0x5b/0x5b
Fixes:
e5863d9ad ("dm: allocate requests in target when stacking on blk-mq devices")
Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Cc: stable@vger.kernel.org # 4.0+
dm_kill_unmapped_request(rq, r);
return r;
}
- if (IS_ERR(clone))
- return DM_MAPIO_REQUEUE;
+ if (r != DM_MAPIO_REMAPPED)
+ return r;
if (setup_clone(clone, rq, tio, GFP_ATOMIC)) {
/* -ENOMEM */
ti->type->release_clone_rq(clone);