Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On 05/01/2014 04:51 PM, Christoph Hellwig wrote: Instead of letting the ULD play games with the prep_fn move back to the model of a central prep_fn with a callback to the ULD. This already cleans up and shortens the code by itself, and will be required to properly support blk-mq in the SCSI midlayer. ... And leaving the device handler to still provide a prep_fn(). But that's for another day. Signed-off-by: Christoph Hellwig h...@lst.de Reviewed-by: Nicholas Bellinger n...@linux-iscsi.org Reviewed-by: Mike Christie micha...@cs.wisc.edu Reviewed-by: Hannes Reinecke h...@suse.de Cheers, Hannes -- Dr. Hannes Reinecke zSeries Storage h...@suse.de +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] scsi: reintroduce scsi_driver.init_command
Instead of letting the ULD play games with the prep_fn move back to the model of a central prep_fn with a callback to the ULD. This already cleans up and shortens the code by itself, and will be required to properly support blk-mq in the SCSI midlayer. Signed-off-by: Christoph Hellwig h...@lst.de Reviewed-by: Nicholas Bellinger n...@linux-iscsi.org Reviewed-by: Mike Christie micha...@cs.wisc.edu --- drivers/scsi/scsi_lib.c| 66 ++-- drivers/scsi/sd.c | 44 ++--- drivers/scsi/sr.c | 19 - include/scsi/scsi_driver.h |9 ++ 4 files changed, 62 insertions(+), 76 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 045822b..9f841df 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1073,15 +1073,7 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; + struct scsi_cmnd *cmd = req-special; /* * BLOCK_PC requests may transfer data, in which case they must @@ -1125,15 +1117,11 @@ EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); */ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; + struct scsi_cmnd *cmd = req-special; if (unlikely(sdev-scsi_dh_data sdev-scsi_dh_data-scsi_dh sdev-scsi_dh_data-scsi_dh-prep_fn)) { - ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); + int ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); if (ret != BLKPREP_OK) return ret; } @@ -1143,16 +1131,13 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) */ BUG_ON(!req-nr_phys_segments); - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; - memset(cmd-cmnd, 0, BLK_MAX_CDB); return scsi_init_io(cmd, GFP_ATOMIC); } EXPORT_SYMBOL(scsi_setup_fs_cmnd); -int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) +static int +scsi_prep_state_check(struct scsi_device *sdev, struct request *req) { int ret = BLKPREP_OK; @@ -1204,9 +1189,9 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) } return ret; } -EXPORT_SYMBOL(scsi_prep_state_check); -int scsi_prep_return(struct request_queue *q, struct request *req, int ret) +static int +scsi_prep_return(struct request_queue *q, struct request *req, int ret) { struct scsi_device *sdev = q-queuedata; @@ -1237,18 +1222,44 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) return ret; } -EXPORT_SYMBOL(scsi_prep_return); -int scsi_prep_fn(struct request_queue *q, struct request *req) +static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q-queuedata; - int ret = BLKPREP_KILL; + struct scsi_cmnd *cmd; + int ret; - if (req-cmd_type == REQ_TYPE_BLOCK_PC) + ret = scsi_prep_state_check(sdev, req); + if (ret != BLKPREP_OK) + goto out; + + cmd = scsi_get_cmd_from_req(sdev, req); + if (unlikely(!cmd)) { + ret = BLKPREP_DEFER; + goto out; + } + + if (req-cmd_type == REQ_TYPE_FS) + ret = scsi_cmd_to_driver(cmd)-init_command(cmd); + else if (req-cmd_type == REQ_TYPE_BLOCK_PC) ret = scsi_setup_blk_pc_cmnd(sdev, req); + else + ret = BLKPREP_KILL; + +out: return scsi_prep_return(q, req, ret); } -EXPORT_SYMBOL(scsi_prep_fn); + +static void scsi_unprep_fn(struct request_queue *q, struct request *req) +{ + if (req-cmd_type == REQ_TYPE_FS) { + struct scsi_cmnd *cmd = req-special; + struct scsi_driver *drv = scsi_cmd_to_driver(cmd); + + if (drv-uninit_command) + drv-uninit_command(cmd); + } +} /* * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else @@ -1669,6 +1680,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) return NULL; blk_queue_prep_rq(q, scsi_prep_fn); + blk_queue_unprep_rq(q, scsi_unprep_fn); blk_queue_softirq_done(q, scsi_softirq_done); blk_queue_rq_timed_out(q, scsi_times_out); blk_queue_lld_busy(q, scsi_lld_busy); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On Sun, Mar 30, 2014 at 10:45:04PM -0700, Nicholas A. Bellinger wrote: int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; + struct scsi_cmnd *cmd = req-special; Mmm, I thought that req-special was only holding a pointer to a pre-allocated scsi_cmnd during mq operation, no..? For the mq case the block layer sets up req-special. For the old case scsi_get_cmd_from_req sets up req-special the first it is called, and leaves it in there until the command is done. + ret = scsi_prep_state_check(sdev, req); + if (ret != BLKPREP_OK) + goto out; + + cmd = scsi_get_cmd_from_req(sdev, req); + if (unlikely(!cmd)) { + ret = BLKPREP_DEFER; + goto out; + } + From here the req-special pointer may or may not be set depending on mq operation, no..? a) there is no blk-mq support yet in James tree (+ these patches) b) even in my scsi-mq tree this code path won't be called for the mq case c) after scsi_get_cmd_from_req returns req-special will always be set up to point to the scsi_cmnd: static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, struct request *req) { struct scsi_cmnd *cmd; if (!req-special) { ... req-special = cmd; } else { cmd = req-special; } /* pull a tag out of the request if we have one */ cmd-tag = req-tag; cmd-request = req; cmd-cmnd = req-cmd; cmd-prot_op = SCSI_PROT_NORMAL; return cmd; } } ret = scsi_setup_fs_cmnd(sdp, rq); if (ret != BLKPREP_OK) And this currently assumes req-special is always set when calling scsi_setup_fs_cmnd() That is the case both before and after this patch. -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On Mon, 2014-03-31 at 08:08 +0200, Christoph Hellwig wrote: On Sun, Mar 30, 2014 at 10:45:04PM -0700, Nicholas A. Bellinger wrote: int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; + struct scsi_cmnd *cmd = req-special; Mmm, I thought that req-special was only holding a pointer to a pre-allocated scsi_cmnd during mq operation, no..? For the mq case the block layer sets up req-special. For the old case scsi_get_cmd_from_req sets up req-special the first it is called, and leaves it in there until the command is done. Er, yes of course. Reviewed-by: Nicholas Bellinger n...@linux-iscsi.org -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On 03/27/2014 11:14 AM, Christoph Hellwig wrote: @@ -1663,6 +1652,8 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned char op = SCpnt-cmnd[0]; unsigned char unmap = SCpnt-cmnd[1] 8; + sd_uninit_command(SCpnt); + The above call would free the cmnd-cmnd and set it to null. If then scsi_io_completion was going to do some error processing it looks like it could try to access the scsi_cmnd-cmnd field. With the current code that would not be a problem because the blk unprep callback is not called until the block layer does its request cleanup in blk_finish_request which as you know is after scsi_io_completion/scsi_end_request is done with the cmnd. -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On Mon, Mar 31, 2014 at 01:56:13AM -0500, Mike Christie wrote: The above call would free the cmnd-cmnd and set it to null. If then scsi_io_completion was going to do some error processing it looks like it could try to access the scsi_cmnd-cmnd field. With the current code that would not be a problem because the blk unprep callback is not called until the block layer does its request cleanup in blk_finish_request which as you know is after scsi_io_completion/scsi_end_request is done with the cmnd. Right, we should probabl call -uninit_command at that place as well instead of calling it internall in -done. -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
The above call would free the cmnd-cmnd and set it to null. If then scsi_io_completion was going to do some error processing it looks like it could try to access the scsi_cmnd-cmnd field. With the current code that would not be a problem because the blk unprep callback is not called until the block layer does its request cleanup in blk_finish_request which as you know is after scsi_io_completion/scsi_end_request is done with the cmnd. This incremental patches fixes the issue, and makes sure the uninit calls are nicely paired like the rest of the I/O completion routines after patch 2: diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 48c5c77..8e79612 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -490,8 +490,6 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) struct request *req = cmd-request; unsigned long flags; - scsi_uninit_command(cmd); - spin_lock_irqsave(q-queue_lock, flags); blk_unprep_request(req); req-special = NULL; @@ -941,6 +939,7 @@ requeue: /* Unprep the request and put it back at the head of the queue. * A new command will be prepared and issued. */ + scsi_uninit_command(cmd); scsi_release_buffers(cmd); scsi_requeue_command(q, cmd); break; @@ -956,6 +955,7 @@ requeue: return; next_command: + scsi_uninit_command(cmd); scsi_release_buffers(cmd); scsi_next_command(cmd); } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d95c4fd..d99cb3f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1652,8 +1652,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned char op = SCpnt-cmnd[0]; unsigned char unmap = SCpnt-cmnd[1] 8; - sd_uninit_command(SCpnt); - if (req-cmd_flags REQ_DISCARD || req-cmd_flags REQ_WRITE_SAME) { if (!result) { good_bytes = blk_rq_bytes(req); -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] scsi: reintroduce scsi_driver.init_command
On Thu, 2014-03-27 at 17:14 +0100, Christoph Hellwig wrote: Move control of the prep_fn back from the ULDs into the scsi layer. Besides cleaning up the code and removing the only use of the unprep_fn requeuest_queue method this also prepares for usinng blk-mq, which doesn't have equivalent functionality to the prep_fn method and requires the driver to provide just a single I/O submission method. Signed-off-by: Christoph Hellwig h...@lst.de --- drivers/scsi/scsi_lib.c| 66 ++-- drivers/scsi/sd.c | 46 +++--- drivers/scsi/sr.c | 19 - include/scsi/scsi_driver.h |8 ++ 4 files changed, 63 insertions(+), 76 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a73751b..48c5c77 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c SNIP @@ -1071,15 +1083,7 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; + struct scsi_cmnd *cmd = req-special; Mmm, I thought that req-special was only holding a pointer to a pre-allocated scsi_cmnd during mq operation, no..? /* * BLOCK_PC requests may transfer data, in which case they must @@ -1123,15 +1127,11 @@ EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); */ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; + struct scsi_cmnd *cmd = req-special; Ditto here for REQ_TYPE_FS_CMND if (unlikely(sdev-scsi_dh_data sdev-scsi_dh_data-scsi_dh sdev-scsi_dh_data-scsi_dh-prep_fn)) { - ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); + int ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); if (ret != BLKPREP_OK) return ret; } @@ -1141,16 +1141,13 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) */ BUG_ON(!req-nr_phys_segments); - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; - memset(cmd-cmnd, 0, BLK_MAX_CDB); return scsi_init_io(cmd, GFP_ATOMIC); } EXPORT_SYMBOL(scsi_setup_fs_cmnd); -int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) +static int +scsi_prep_state_check(struct scsi_device *sdev, struct request *req) { int ret = BLKPREP_OK; @@ -1202,9 +1199,9 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) } return ret; } -EXPORT_SYMBOL(scsi_prep_state_check); -int scsi_prep_return(struct request_queue *q, struct request *req, int ret) +static int +scsi_prep_return(struct request_queue *q, struct request *req, int ret) { struct scsi_device *sdev = q-queuedata; @@ -1235,18 +1232,33 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) return ret; } -EXPORT_SYMBOL(scsi_prep_return); -int scsi_prep_fn(struct request_queue *q, struct request *req) +static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q-queuedata; - int ret = BLKPREP_KILL; + struct scsi_cmnd *cmd; + int ret; - if (req-cmd_type == REQ_TYPE_BLOCK_PC) + ret = scsi_prep_state_check(sdev, req); + if (ret != BLKPREP_OK) + goto out; + + cmd = scsi_get_cmd_from_req(sdev, req); + if (unlikely(!cmd)) { + ret = BLKPREP_DEFER; + goto out; + } + From here the req-special pointer may or may not be set depending on mq operation, no..? + if (req-cmd_type == REQ_TYPE_FS) + ret = scsi_cmd_to_driver(cmd)-init_command(cmd); + else if (req-cmd_type == REQ_TYPE_BLOCK_PC) ret = scsi_setup_blk_pc_cmnd(sdev, req); + else + ret = BLKPREP_KILL; + +out: return scsi_prep_return(q, req, ret); } -EXPORT_SYMBOL(scsi_prep_fn); /* * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 89e6c04..d95c4fd 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c SNIP @@ -886,12 +882,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } else if (rq-cmd_flags REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); goto out; - } else if (rq-cmd_type == REQ_TYPE_BLOCK_PC) { - ret =
[PATCH 3/4] scsi: reintroduce scsi_driver.init_command
Move control of the prep_fn back from the ULDs into the scsi layer. Besides cleaning up the code and removing the only use of the unprep_fn requeuest_queue method this also prepares for usinng blk-mq, which doesn't have equivalent functionality to the prep_fn method and requires the driver to provide just a single I/O submission method. Signed-off-by: Christoph Hellwig h...@lst.de --- drivers/scsi/scsi_lib.c| 66 ++-- drivers/scsi/sd.c | 46 +++--- drivers/scsi/sr.c | 19 - include/scsi/scsi_driver.h |8 ++ 4 files changed, 63 insertions(+), 76 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a73751b..48c5c77 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -456,6 +456,16 @@ void scsi_requeue_run_queue(struct work_struct *work) scsi_run_queue(q); } +static void scsi_uninit_command(struct scsi_cmnd *cmd) +{ + if (cmd-request-cmd_type == REQ_TYPE_FS) { + struct scsi_driver *drv = scsi_cmd_to_driver(cmd); + + if (drv-uninit_command) + drv-uninit_command(cmd); + } +} + /* * Function: scsi_requeue_command() * @@ -480,6 +490,8 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) struct request *req = cmd-request; unsigned long flags; + scsi_uninit_command(cmd); + spin_lock_irqsave(q-queue_lock, flags); blk_unprep_request(req); req-special = NULL; @@ -1071,15 +1083,7 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; - - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; + struct scsi_cmnd *cmd = req-special; /* * BLOCK_PC requests may transfer data, in which case they must @@ -1123,15 +1127,11 @@ EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); */ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) { - struct scsi_cmnd *cmd; - int ret = scsi_prep_state_check(sdev, req); - - if (ret != BLKPREP_OK) - return ret; + struct scsi_cmnd *cmd = req-special; if (unlikely(sdev-scsi_dh_data sdev-scsi_dh_data-scsi_dh sdev-scsi_dh_data-scsi_dh-prep_fn)) { - ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); + int ret = sdev-scsi_dh_data-scsi_dh-prep_fn(sdev, req); if (ret != BLKPREP_OK) return ret; } @@ -1141,16 +1141,13 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) */ BUG_ON(!req-nr_phys_segments); - cmd = scsi_get_cmd_from_req(sdev, req); - if (unlikely(!cmd)) - return BLKPREP_DEFER; - memset(cmd-cmnd, 0, BLK_MAX_CDB); return scsi_init_io(cmd, GFP_ATOMIC); } EXPORT_SYMBOL(scsi_setup_fs_cmnd); -int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) +static int +scsi_prep_state_check(struct scsi_device *sdev, struct request *req) { int ret = BLKPREP_OK; @@ -1202,9 +1199,9 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) } return ret; } -EXPORT_SYMBOL(scsi_prep_state_check); -int scsi_prep_return(struct request_queue *q, struct request *req, int ret) +static int +scsi_prep_return(struct request_queue *q, struct request *req, int ret) { struct scsi_device *sdev = q-queuedata; @@ -1235,18 +1232,33 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) return ret; } -EXPORT_SYMBOL(scsi_prep_return); -int scsi_prep_fn(struct request_queue *q, struct request *req) +static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q-queuedata; - int ret = BLKPREP_KILL; + struct scsi_cmnd *cmd; + int ret; - if (req-cmd_type == REQ_TYPE_BLOCK_PC) + ret = scsi_prep_state_check(sdev, req); + if (ret != BLKPREP_OK) + goto out; + + cmd = scsi_get_cmd_from_req(sdev, req); + if (unlikely(!cmd)) { + ret = BLKPREP_DEFER; + goto out; + } + + if (req-cmd_type == REQ_TYPE_FS) + ret = scsi_cmd_to_driver(cmd)-init_command(cmd); + else if (req-cmd_type == REQ_TYPE_BLOCK_PC) ret = scsi_setup_blk_pc_cmnd(sdev, req); + else + ret = BLKPREP_KILL; + +out: return scsi_prep_return(q, req, ret); } -EXPORT_SYMBOL(scsi_prep_fn); /* * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else diff --git