blkfront: properly fail packet requests c/s 1036:f5635e334aa5 ("blkfront: forward unknown IOCTLs to scsi_cmd_ioctl() for /dev/sdX") uncovered a problem in blkfront's request handling: blk_pc_request()-s, among other sources resulting from the handling of the SG_IO ioctl in scsi_cmd_ioctl(), must not be passed to end_request() without prior adjustment: Neither is their ->hard_cur_sectors necessarily correct (potentially resulting in an infinite loop), nor is ->errors ever getting set properly to reflect the failure (sg_io() intentionally ignores the return value from blk_execute_rq()). As blktap2's internally created devices have the same deficiency, fix this there too. Signed-off-by: Jan Beulich --- a/drivers/xen/blkfront/blkfront.c +++ b/drivers/xen/blkfront/blkfront.c @@ -709,6 +709,12 @@ void do_blkif_request(request_queue_t *r while ((req = elv_next_request(rq)) != NULL) { info = req->rq_disk->private_data; if (!blk_fs_request(req)) { + if (blk_pc_request(req)) { + req->errors = (DID_ERROR << 16) + | (DRIVER_INVALID << 24); + req->hard_cur_sectors = (req->data_len + + 511) >> 9; + } end_request(req, 0); continue; } --- a/drivers/xen/blktap2/device.c +++ b/drivers/xen/blktap2/device.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -825,6 +826,12 @@ blktap_device_run_queue(struct blktap *t while ((req = elv_next_request(rq)) != NULL) { if (!blk_fs_request(req)) { + if (blk_pc_request(req)) { + req->errors = (DID_ERROR << 16) + | (DRIVER_INVALID << 24); + req->hard_cur_sectors = (req->data_len + + 511) >> 9; + } end_request(req, 0); continue; } @@ -912,9 +919,16 @@ blktap_device_do_request(request_queue_t fail: while ((req = elv_next_request(rq))) { - BTERR("device closed: failing secs %llu - %llu\n", - (unsigned long long)req->sector, - (unsigned long long)req->sector + req->nr_sectors); + if (blk_fs_request(req)) { + unsigned long long sec = req->sector; + + BTERR("device closed: failing secs %#Lx-%#Lx\n", + sec, sec + req->nr_sectors - 1); + } else if (blk_pc_request(req)) { + req->errors = (DID_ERROR << 16) + | (DRIVER_INVALID << 24); + req->hard_cur_sectors = (req->data_len + 511) >> 9; + } end_request(req, 0); } }