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 = scsi_setup_blk_pc_cmnd(sdp, rq);
> -             goto out;
> -     } else if (rq->cmd_type != REQ_TYPE_FS) {
> -             ret = BLKPREP_KILL;
> -             goto out;
>       }
>       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()

> @@ -903,11 +893,10 @@ static int sd_prep_fn(struct request_queue *q, struct 
> request *rq)
>        * is used for a killable error condition */
>       ret = BLKPREP_KILL;
>  
> -     SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
> -                                     "sd_prep_fn: block=%llu, "
> -                                     "count=%d\n",
> -                                     (unsigned long long)block,
> -                                     this_count));
> +     SCSI_LOG_HLQUEUE(1,
> +             scmd_printk(KERN_INFO, SCpnt,
> +                     "%s: block=%llu, count=%d\n",
> +                     __func__, (unsigned long long)block, this_count));
>  
>       if (!sdp || !scsi_device_online(sdp) ||
>           block + blk_rq_sectors(rq) > get_capacity(disk)) {
> @@ -1127,7 +1116,7 @@ static int sd_prep_fn(struct request_queue *q, struct 
> request *rq)
>        */
>       ret = BLKPREP_OK;
>   out:
> -     return scsi_prep_return(q, rq, ret);
> +     return ret;
>  }
>  
>  /**
> @@ -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);
> +
>       if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) {
>               if (!result) {
>                       good_bytes = blk_rq_bytes(req);
> @@ -2878,9 +2869,6 @@ static void sd_probe_async(void *data, async_cookie_t 
> cookie)
>  
>       sd_revalidate_disk(gd);
>  
> -     blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
> -     blk_queue_unprep_rq(sdp->request_queue, sd_unprep_fn);
> -
>       gd->driverfs_dev = &sdp->sdev_gendev;
>       gd->flags = GENHD_FL_EXT_DEVT;
>       if (sdp->removable) {
> @@ -3027,8 +3015,6 @@ static int sd_remove(struct device *dev)
>       scsi_autopm_get_device(sdkp->device);
>  
>       async_synchronize_full_domain(&scsi_sd_probe_domain);
> -     blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn);
> -     blk_queue_unprep_rq(sdkp->device->request_queue, NULL);
>       device_del(&sdkp->dev);
>       del_gendisk(sdkp->disk);
>       sd_shutdown(dev);
> diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
> index 40d8592..93cbd36 100644
> --- a/drivers/scsi/sr.c
> +++ b/drivers/scsi/sr.c

<SNIP>

> @@ -378,21 +380,14 @@ static int sr_done(struct scsi_cmnd *SCpnt)
>       return good_bytes;
>  }
>  
> -static int sr_prep_fn(struct request_queue *q, struct request *rq)
> +static int sr_init_command(struct scsi_cmnd *SCpnt)
>  {
>       int block = 0, this_count, s_size;
>       struct scsi_cd *cd;
> -     struct scsi_cmnd *SCpnt;
> -     struct scsi_device *sdp = q->queuedata;
> +     struct request *rq = SCpnt->request;
> +     struct scsi_device *sdp = SCpnt->device;
>       int ret;
>  
> -     if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
> -             ret = scsi_setup_blk_pc_cmnd(sdp, rq);
> -             goto out;
> -     } else if (rq->cmd_type != REQ_TYPE_FS) {
> -             ret = BLKPREP_KILL;
> -             goto out;
> -     }
>       ret = scsi_setup_fs_cmnd(sdp, rq);
>       if (ret != BLKPREP_OK)
>               goto out;

Ditto to the scsi_setup_fs_cmnd() call here as well.

--nab

--
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

Reply via email to