Re: remove exofs and the T10 OSD code V2

From: Boaz Harrosh
Date: Wed Oct 31 2018 - 11:58:06 EST


On 30/10/18 09:45, Christoph Hellwig wrote:
> On Mon, Oct 29, 2018 at 02:42:12PM -0600, Jens Axboe wrote:
>> LGTM, for both:
>
> I also have this one on top as requested by Martin. The core block
> bidi support is unfortunately also used by bsg-lib, although it is
> not anywhere near as invasive. But that is another argument for
> looking into moving bsg-lib away from using block queues..
>

BUT this patch is very very wrong.

Totally apart from T10-OSD and its use in the field. Support for scsi BIDI
commands is not exclusive to T10-OSD at all. Even the simple scsi-array
command-set has BIDI operations defined. for example the write-return-xor
and so on.

Also some private administrative CDBs of some vendor devices uses SCSI-BIDI.
So this patch just broke some drivers. (User-mode apps use bsg pass through)

Also you might (try hard and) remove all usage of scsi-bidi as an initiator
from the Linux Kernel. But what about target mode. As a target we have supported
on the wire bidi protocols like write-return-xor and others for a long time.
Are you willing to silently break all these setups in the field on the next update?
Are you so sure these are never used?

PLEASE, I beg of you guys. Do not remove SCSI-BIDI. It is a cry of generations.

And I think by the rules of Linus, as far as target mode. You are not allowed
to break users in this way.

Thanks
Boaz

> ---
>>From d6dd4f32798edd425a4df72f6125dba03e19d8c7 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <hch@xxxxxx>
> Date: Sat, 27 Oct 2018 15:49:13 +0200
> Subject: scsi: remove bidirectional command support
>
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
> drivers/scsi/cxgbi/libcxgbi.c | 13 ++---
> drivers/scsi/iscsi_tcp.c | 9 +---
> drivers/scsi/libiscsi.c | 64 +++---------------------
> drivers/scsi/libiscsi_tcp.c | 8 +--
> drivers/scsi/scsi_debug.c | 51 ++++---------------
> drivers/scsi/scsi_error.c | 3 --
> drivers/scsi/scsi_lib.c | 80 ++----------------------------
> drivers/scsi/virtio_scsi.c | 14 ++----
> drivers/target/loopback/tcm_loop.c | 15 ------
> drivers/usb/storage/uas.c | 11 +---
> include/scsi/scsi_cmnd.h | 19 +------
> include/scsi/scsi_eh.h | 1 -
> 12 files changed, 35 insertions(+), 253 deletions(-)
>
> diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
> index 75f876409fb9..4466ae5c9a74 100644
> --- a/drivers/scsi/cxgbi/libcxgbi.c
> +++ b/drivers/scsi/cxgbi/libcxgbi.c
> @@ -1211,7 +1211,7 @@ scmd_get_params(struct scsi_cmnd *sc, struct scatterlist **sgl,
> unsigned int *sgcnt, unsigned int *dlen,
> unsigned int prot)
> {
> - struct scsi_data_buffer *sdb = prot ? scsi_prot(sc) : scsi_out(sc);
> + struct scsi_data_buffer *sdb = prot ? scsi_prot(sc) : &sc->sdb;
>
> *sgl = sdb->table.sgl;
> *sgcnt = sdb->table.nents;
> @@ -1427,8 +1427,7 @@ static void task_release_itt(struct iscsi_task *task, itt_t hdr_itt)
> log_debug(1 << CXGBI_DBG_DDP,
> "cdev 0x%p, task 0x%p, release tag 0x%x.\n",
> cdev, task, tag);
> - if (sc &&
> - (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE) &&
> + if (sc && sc->sc_data_direction == DMA_FROM_DEVICE &&
> cxgbi_ppm_is_ddp_tag(ppm, tag)) {
> struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
> struct cxgbi_task_tag_info *ttinfo = &tdata->ttinfo;
> @@ -1460,9 +1459,7 @@ static int task_reserve_itt(struct iscsi_task *task, itt_t *hdr_itt)
> u32 tag = 0;
> int err = -EINVAL;
>
> - if (sc &&
> - (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE)
> - ) {
> + if (sc && sc->sc_data_direction == DMA_FROM_DEVICE) {
> struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
> struct cxgbi_task_tag_info *ttinfo = &tdata->ttinfo;
>
> @@ -1896,7 +1893,7 @@ int cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 opcode)
> if (SKB_MAX_HEAD(cdev->skb_tx_rsvd) > (512 * MAX_SKB_FRAGS) &&
> (opcode == ISCSI_OP_SCSI_DATA_OUT ||
> (opcode == ISCSI_OP_SCSI_CMD &&
> - (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
> + sc->sc_data_direction == DMA_TO_DEVICE)))
> /* data could goes into skb head */
> headroom += min_t(unsigned int,
> SKB_MAX_HEAD(cdev->skb_tx_rsvd),
> @@ -1971,7 +1968,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, unsigned int offset,
> return 0;
>
> if (task->sc) {
> - struct scsi_data_buffer *sdb = scsi_out(task->sc);
> + struct scsi_data_buffer *sdb = &task->sc->sdb;
> struct scatterlist *sg = NULL;
> int err;
>
> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
> index 23354f206533..a78b46bb2b71 100644
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -514,7 +514,7 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
> if (!task->sc)
> iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count);
> else {
> - struct scsi_data_buffer *sdb = scsi_out(task->sc);
> + struct scsi_data_buffer *sdb = &task->sc->sdb;
>
> err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl,
> sdb->table.nents, offset,
> @@ -948,12 +948,6 @@ static umode_t iscsi_sw_tcp_attr_is_visible(int param_type, int param)
> return 0;
> }
>
> -static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
> -{
> - blk_queue_flag_set(QUEUE_FLAG_BIDI, sdev->request_queue);
> - return 0;
> -}
> -
> static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
> {
> struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
> @@ -981,7 +975,6 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
> .eh_device_reset_handler= iscsi_eh_device_reset,
> .eh_target_reset_handler = iscsi_eh_recover_target,
> .use_clustering = DISABLE_CLUSTERING,
> - .slave_alloc = iscsi_sw_tcp_slave_alloc,
> .slave_configure = iscsi_sw_tcp_slave_configure,
> .target_alloc = iscsi_target_alloc,
> .proc_name = "iscsi_tcp",
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index 93c66ebad907..a6dec983c30e 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -218,32 +218,6 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
> return 0;
> }
>
> -static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
> -{
> - struct scsi_cmnd *sc = task->sc;
> - struct iscsi_rlength_ahdr *rlen_ahdr;
> - int rc;
> -
> - rlen_ahdr = iscsi_next_hdr(task);
> - rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr));
> - if (rc)
> - return rc;
> -
> - rlen_ahdr->ahslength =
> - cpu_to_be16(sizeof(rlen_ahdr->read_length) +
> - sizeof(rlen_ahdr->reserved));
> - rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
> - rlen_ahdr->reserved = 0;
> - rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
> -
> - ISCSI_DBG_SESSION(task->conn->session,
> - "bidi-in rlen_ahdr->read_length(%d) "
> - "rlen_ahdr->ahslength(%d)\n",
> - be32_to_cpu(rlen_ahdr->read_length),
> - be16_to_cpu(rlen_ahdr->ahslength));
> - return 0;
> -}
> -
> /**
> * iscsi_check_tmf_restrictions - check if a task is affected by TMF
> * @task: iscsi task
> @@ -382,13 +356,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
> memcpy(hdr->cdb, sc->cmnd, cmd_len);
>
> task->imm_count = 0;
> - if (scsi_bidi_cmnd(sc)) {
> - hdr->flags |= ISCSI_FLAG_CMD_READ;
> - rc = iscsi_prep_bidi_ahs(task);
> - if (rc)
> - return rc;
> - }
> -
> if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
> task->protected = true;
>
> @@ -463,12 +430,10 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
>
> conn->scsicmd_pdus_cnt++;
> ISCSI_DBG_SESSION(session, "iscsi prep [%s cid %d sc %p cdb 0x%x "
> - "itt 0x%x len %d bidi_len %d cmdsn %d win %d]\n",
> - scsi_bidi_cmnd(sc) ? "bidirectional" :
> + "itt 0x%x len %d cmdsn %d win %d]\n",
> sc->sc_data_direction == DMA_TO_DEVICE ?
> "write" : "read", conn->id, sc, sc->cmnd[0],
> task->itt, transfer_length,
> - scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
> session->cmdsn,
> session->max_cmdsn - session->exp_cmdsn + 1);
> return 0;
> @@ -637,12 +602,7 @@ static void fail_scsi_task(struct iscsi_task *task, int err)
> state = ISCSI_TASK_ABRT_TMF;
>
> sc->result = err << 16;
> - if (!scsi_bidi_cmnd(sc))
> - scsi_set_resid(sc, scsi_bufflen(sc));
> - else {
> - scsi_out(sc)->resid = scsi_out(sc)->length;
> - scsi_in(sc)->resid = scsi_in(sc)->length;
> - }
> + scsi_set_resid(sc, scsi_bufflen(sc));
>
> /* regular RX path uses back_lock */
> spin_lock_bh(&conn->session->back_lock);
> @@ -897,14 +857,7 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
>
> if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
> ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
> - int res_count = be32_to_cpu(rhdr->bi_residual_count);
> -
> - if (scsi_bidi_cmnd(sc) && res_count > 0 &&
> - (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
> - res_count <= scsi_in(sc)->length))
> - scsi_in(sc)->resid = res_count;
> - else
> - sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
> + sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
> }
>
> if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
> @@ -951,8 +904,8 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
>
> if (res_count > 0 &&
> (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
> - res_count <= scsi_in(sc)->length))
> - scsi_in(sc)->resid = res_count;
> + res_count <= sc->sdb.length))
> + sc->sdb.resid = res_count;
> else
> sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
> }
> @@ -1794,12 +1747,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
> spin_unlock_bh(&session->frwd_lock);
> ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
> sc->cmnd[0], reason);
> - if (!scsi_bidi_cmnd(sc))
> - scsi_set_resid(sc, scsi_bufflen(sc));
> - else {
> - scsi_out(sc)->resid = scsi_out(sc)->length;
> - scsi_in(sc)->resid = scsi_in(sc)->length;
> - }
> + scsi_set_resid(sc, scsi_bufflen(sc));
> sc->scsi_done(sc);
> return 0;
> }
> diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
> index 4fcb9e65be57..1ec8332df515 100644
> --- a/drivers/scsi/libiscsi_tcp.c
> +++ b/drivers/scsi/libiscsi_tcp.c
> @@ -491,7 +491,7 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
> struct iscsi_tcp_task *tcp_task = task->dd_data;
> struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
> int datasn = be32_to_cpu(rhdr->datasn);
> - unsigned total_in_length = scsi_in(task->sc)->length;
> + unsigned total_in_length = task->sc->sdb.length;
>
> /*
> * lib iscsi will update this in the completion handling if there
> @@ -576,11 +576,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
> data_length, session->max_burst);
>
> data_offset = be32_to_cpu(rhdr->data_offset);
> - if (data_offset + data_length > scsi_out(task->sc)->length) {
> + if (data_offset + data_length > task->sc->sdb.length) {
> iscsi_conn_printk(KERN_ERR, conn,
> "invalid R2T with data len %u at offset %u "
> "and total length %d\n", data_length,
> - data_offset, scsi_out(task->sc)->length);
> + data_offset, task->sc->sdb.length);
> return ISCSI_ERR_DATALEN;
> }
>
> @@ -692,7 +692,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
> if (tcp_conn->in.datalen) {
> struct iscsi_tcp_task *tcp_task = task->dd_data;
> struct ahash_request *rx_hash = NULL;
> - struct scsi_data_buffer *sdb = scsi_in(task->sc);
> + struct scsi_data_buffer *sdb = &task->sc->sdb;
>
> /*
> * Setup copy of Data-In into the struct scsi_cmnd
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 60bcc6df97a9..98b212ec6240 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -430,7 +430,6 @@ static int resp_rsup_opcodes(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_rsup_tmfs(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_write_same_10(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *);
> -static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *);
> static int resp_sync_cache(struct scsi_cmnd *, struct sdebug_dev_info *);
> @@ -600,9 +599,6 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
> {0, 0x42, 0, F_D_OUT | FF_MEDIA_IO, resp_unmap, NULL, /* UNMAP */
> {10, 0x1, 0, 0, 0, 0, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
> /* 25 */
> - {0, 0x53, 0, F_D_IN | F_D_OUT | FF_MEDIA_IO, resp_xdwriteread_10,
> - NULL, {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7,
> - 0, 0, 0, 0, 0, 0} }, /* XDWRITEREAD(10) */
> {0, 0x3b, 0, F_D_OUT_MAYBE, resp_write_buffer, NULL,
> {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0,
> 0, 0, 0, 0} }, /* WRITE_BUFFER */
> @@ -1010,11 +1006,11 @@ static int fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr,
> int arr_len)
> {
> int act_len;
> - struct scsi_data_buffer *sdb = scsi_in(scp);
> + struct scsi_data_buffer *sdb = &scp->sdb;
>
> if (!sdb->length)
> return 0;
> - if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
> + if (scp->sc_data_direction != DMA_FROM_DEVICE)
> return DID_ERROR << 16;
>
> act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents,
> @@ -1033,12 +1029,12 @@ static int p_fill_from_dev_buffer(struct scsi_cmnd *scp, const void *arr,
> int arr_len, unsigned int off_dst)
> {
> int act_len, n;
> - struct scsi_data_buffer *sdb = scsi_in(scp);
> + struct scsi_data_buffer *sdb = &scp->sdb;
> off_t skip = off_dst;
>
> if (sdb->length <= off_dst)
> return 0;
> - if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
> + if (scp->sc_data_direction != DMA_FROM_DEVICE)
> return DID_ERROR << 16;
>
> act_len = sg_pcopy_from_buffer(sdb->table.sgl, sdb->table.nents,
> @@ -1058,7 +1054,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr,
> {
> if (!scsi_bufflen(scp))
> return 0;
> - if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE))
> + if (scp->sc_data_direction != DMA_TO_DEVICE)
> return -1;
>
> return scsi_sg_copy_to_buffer(scp, arr, arr_len);
> @@ -2477,21 +2473,19 @@ static int do_device_access(struct scsi_cmnd *scmd, u32 sg_skip, u64 lba,
> {
> int ret;
> u64 block, rest = 0;
> - struct scsi_data_buffer *sdb;
> + struct scsi_data_buffer *sdb = &scmd->sdb;
> enum dma_data_direction dir;
>
> if (do_write) {
> - sdb = scsi_out(scmd);
> dir = DMA_TO_DEVICE;
> write_since_sync = true;
> } else {
> - sdb = scsi_in(scmd);
> dir = DMA_FROM_DEVICE;
> }
>
> if (!sdb->length)
> return 0;
> - if (!(scsi_bidi_cmnd(scmd) || scmd->sc_data_direction == dir))
> + if (scmd->sc_data_direction != dir)
> return -1;
>
> block = do_div(lba, sdebug_store_sectors);
> @@ -2774,7 +2768,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
> if (unlikely(ret == -1))
> return DID_ERROR << 16;
>
> - scsi_in(scp)->resid = scsi_bufflen(scp) - ret;
> + scp->sdb.resid = scsi_bufflen(scp) - ret;
>
> if (unlikely(sqcp)) {
> if (sqcp->inj_recovered) {
> @@ -3724,7 +3718,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
> int j;
> unsigned char *kaddr, *buf;
> unsigned int offset;
> - struct scsi_data_buffer *sdb = scsi_in(scp);
> + struct scsi_data_buffer *sdb = &scp->sdb;
> struct sg_mapping_iter miter;
>
> /* better not to use temporary buffer. */
> @@ -3754,32 +3748,6 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
> return 0;
> }
>
> -static int resp_xdwriteread_10(struct scsi_cmnd *scp,
> - struct sdebug_dev_info *devip)
> -{
> - u8 *cmd = scp->cmnd;
> - u64 lba;
> - u32 num;
> - int errsts;
> -
> - if (!scsi_bidi_cmnd(scp)) {
> - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
> - INSUFF_RES_ASCQ);
> - return check_condition_result;
> - }
> - errsts = resp_read_dt0(scp, devip);
> - if (errsts)
> - return errsts;
> - if (!(cmd[1] & 0x4)) { /* DISABLE_WRITE is not set */
> - errsts = resp_write_dt0(scp, devip);
> - if (errsts)
> - return errsts;
> - }
> - lba = get_unaligned_be32(cmd + 2);
> - num = get_unaligned_be16(cmd + 7);
> - return resp_xdwriteread(scp, lba, num, devip);
> -}
> -
> static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd)
> {
> u32 tag = blk_mq_unique_tag(cmnd->request);
> @@ -3953,7 +3921,6 @@ static int scsi_debug_slave_alloc(struct scsi_device *sdp)
> if (sdebug_verbose)
> pr_info("slave_alloc <%u %u %u %llu>\n",
> sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
> - blk_queue_flag_set(QUEUE_FLAG_BIDI, sdp->request_queue);
> return 0;
> }
>
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index c736d61b1648..42dd49961ca5 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -965,7 +965,6 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
> ses->cmnd = scmd->cmnd;
> ses->data_direction = scmd->sc_data_direction;
> ses->sdb = scmd->sdb;
> - ses->next_rq = scmd->request->next_rq;
> ses->result = scmd->result;
> ses->underflow = scmd->underflow;
> ses->prot_op = scmd->prot_op;
> @@ -976,7 +975,6 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,
> scmd->cmnd = ses->eh_cmnd;
> memset(scmd->cmnd, 0, BLK_MAX_CDB);
> memset(&scmd->sdb, 0, sizeof(scmd->sdb));
> - scmd->request->next_rq = NULL;
> scmd->result = 0;
>
> if (sense_bytes) {
> @@ -1029,7 +1027,6 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)
> scmd->cmnd = ses->cmnd;
> scmd->sc_data_direction = ses->data_direction;
> scmd->sdb = ses->sdb;
> - scmd->request->next_rq = ses->next_rq;
> scmd->result = ses->result;
> scmd->underflow = ses->underflow;
> scmd->prot_op = ses->prot_op;
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index c7fccbb8f554..cae0a5f7539d 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -610,11 +610,6 @@ static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
>
> if (cmd->sdb.table.nents)
> sg_free_table_chained(&cmd->sdb.table, true);
> - if (cmd->request->next_rq) {
> - sdb = cmd->request->next_rq->special;
> - if (sdb)
> - sg_free_table_chained(&sdb->table, true);
> - }
> if (scsi_prot_sg_count(cmd))
> sg_free_table_chained(&cmd->prot_sdb->table, true);
> }
> @@ -653,18 +648,9 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
> sg_free_table_chained(&cmd->prot_sdb->table, false);
> }
>
> -static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd)
> -{
> - struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special;
> -
> - sg_free_table_chained(&bidi_sdb->table, false);
> - kmem_cache_free(scsi_sdb_cache, bidi_sdb);
> - cmd->request->next_rq->special = NULL;
> -}
> -
> /* Returns false when no more bytes to process, true if there are more */
> static bool scsi_end_request(struct request *req, blk_status_t error,
> - unsigned int bytes, unsigned int bidi_bytes)
> + unsigned int bytes)
> {
> struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
> struct scsi_device *sdev = cmd->device;
> @@ -673,11 +659,6 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
> if (blk_update_request(req, error, bytes))
> return true;
>
> - /* Bidi request must be completed as a whole */
> - if (unlikely(bidi_bytes) &&
> - blk_update_request(req->next_rq, error, bidi_bytes))
> - return true;
> -
> if (blk_queue_add_random(q))
> add_disk_randomness(req->rq_disk);
>
> @@ -707,8 +688,6 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
> } else {
> unsigned long flags;
>
> - if (bidi_bytes)
> - scsi_release_bidi_buffers(cmd);
> scsi_release_buffers(cmd);
> scsi_put_command(cmd);
>
> @@ -916,7 +895,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
> scsi_print_command(cmd);
> }
> }
> - if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req), 0))
> + if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req)))
> return;
> /*FALLTHRU*/
> case ACTION_REPREP:
> @@ -1051,29 +1030,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
> */
> scsi_req(req)->result = cmd->result;
> scsi_req(req)->resid_len = scsi_get_resid(cmd);
> -
> - if (unlikely(scsi_bidi_cmnd(cmd))) {
> - /*
> - * Bidi commands Must be complete as a whole,
> - * both sides at once.
> - */
> - scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
> - if (scsi_end_request(req, BLK_STS_OK, blk_rq_bytes(req),
> - blk_rq_bytes(req->next_rq)))
> - WARN_ONCE(true,
> - "Bidi command with remaining bytes");
> - return;
> - }
> - }
> -
> - /* no bidi support yet, other than in pass-through */
> - if (unlikely(blk_bidi_rq(req))) {
> - WARN_ONCE(true, "Only support bidi command in passthrough");
> - scmd_printk(KERN_ERR, cmd, "Killing bidi command\n");
> - if (scsi_end_request(req, BLK_STS_IOERR, blk_rq_bytes(req),
> - blk_rq_bytes(req->next_rq)))
> - WARN_ONCE(true, "Bidi command with remaining bytes");
> - return;
> }
>
> /*
> @@ -1090,13 +1046,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
> * to retry code. Fast path should return in this block.
> */
> if (likely(blk_rq_bytes(req) > 0 || blk_stat == BLK_STS_OK)) {
> - if (likely(!scsi_end_request(req, blk_stat, good_bytes, 0)))
> + if (likely(!scsi_end_request(req, blk_stat, good_bytes)))
> return; /* no bytes remaining */
> }
>
> /* Kill remainder if no retries. */
> if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
> - if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0))
> + if (scsi_end_request(req, blk_stat, blk_rq_bytes(req)))
> WARN_ONCE(true,
> "Bytes remaining after failed, no-retry command");
> return;
> @@ -1159,23 +1115,6 @@ int scsi_init_io(struct scsi_cmnd *cmd)
> if (error)
> goto err_exit;
>
> - if (blk_bidi_rq(rq)) {
> - if (!rq->q->mq_ops) {
> - struct scsi_data_buffer *bidi_sdb =
> - kmem_cache_zalloc(scsi_sdb_cache, GFP_ATOMIC);
> - if (!bidi_sdb) {
> - error = BLKPREP_DEFER;
> - goto err_exit;
> - }
> -
> - rq->next_rq->special = bidi_sdb;
> - }
> -
> - error = scsi_init_sgtable(rq->next_rq, rq->next_rq->special);
> - if (error)
> - goto err_exit;
> - }
> -
> if (blk_integrity_rq(rq)) {
> struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
> int ivecs, count;
> @@ -2026,17 +1965,6 @@ static int scsi_mq_prep_fn(struct request *req)
> (struct scatterlist *)(cmd->prot_sdb + 1);
> }
>
> - if (blk_bidi_rq(req)) {
> - struct request *next_rq = req->next_rq;
> - struct scsi_data_buffer *bidi_sdb = blk_mq_rq_to_pdu(next_rq);
> -
> - memset(bidi_sdb, 0, sizeof(struct scsi_data_buffer));
> - bidi_sdb->table.sgl =
> - (struct scatterlist *)(bidi_sdb + 1);
> -
> - next_rq->special = bidi_sdb;
> - }
> -
> blk_mq_start_request(req);
>
> return scsi_setup_cmnd(sdev, req);
> diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
> index 1c72db94270e..fd54c12a5ed3 100644
> --- a/drivers/scsi/virtio_scsi.c
> +++ b/drivers/scsi/virtio_scsi.c
> @@ -127,16 +127,8 @@ static inline struct Scsi_Host *virtio_scsi_host(struct virtio_device *vdev)
>
> static void virtscsi_compute_resid(struct scsi_cmnd *sc, u32 resid)
> {
> - if (!resid)
> - return;
> -
> - if (!scsi_bidi_cmnd(sc)) {
> + if (resid)
> scsi_set_resid(sc, resid);
> - return;
> - }
> -
> - scsi_in(sc)->resid = min(resid, scsi_in(sc)->length);
> - scsi_out(sc)->resid = resid - scsi_in(sc)->resid;
> }
>
> /**
> @@ -430,9 +422,9 @@ static int virtscsi_add_cmd(struct virtqueue *vq,
>
> if (sc && sc->sc_data_direction != DMA_NONE) {
> if (sc->sc_data_direction != DMA_FROM_DEVICE)
> - out = &scsi_out(sc)->table;
> + out = &sc->sdb.table;
> if (sc->sc_data_direction != DMA_TO_DEVICE)
> - in = &scsi_in(sc)->table;
> + in = &sc->sdb.table;
> }
>
> /* Request header. */
> diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
> index bc8918f382e4..a43bb76cccf6 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c
> @@ -128,14 +128,6 @@ static void tcm_loop_submission_work(struct work_struct *work)
> set_host_byte(sc, DID_ERROR);
> goto out_done;
> }
> - if (scsi_bidi_cmnd(sc)) {
> - struct scsi_data_buffer *sdb = scsi_in(sc);
> -
> - sgl_bidi = sdb->table.sgl;
> - sgl_bidi_count = sdb->table.nents;
> - se_cmd->se_cmd_flags |= SCF_BIDI;
> -
> - }
>
> transfer_length = scsi_transfer_length(sc);
> if (!scsi_prot_sg_count(sc) &&
> @@ -304,12 +296,6 @@ static int tcm_loop_target_reset(struct scsi_cmnd *sc)
> return FAILED;
> }
>
> -static int tcm_loop_slave_alloc(struct scsi_device *sd)
> -{
> - blk_queue_flag_set(QUEUE_FLAG_BIDI, sd->request_queue);
> - return 0;
> -}
> -
> static struct scsi_host_template tcm_loop_driver_template = {
> .show_info = tcm_loop_show_info,
> .proc_name = "tcm_loopback",
> @@ -325,7 +311,6 @@ static struct scsi_host_template tcm_loop_driver_template = {
> .cmd_per_lun = 1024,
> .max_sectors = 0xFFFF,
> .use_clustering = DISABLE_CLUSTERING,
> - .slave_alloc = tcm_loop_slave_alloc,
> .module = THIS_MODULE,
> .track_queue_depth = 1,
> };
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
> index 1f7b401c4d04..1c3bff3d57b0 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -368,25 +368,19 @@ static void uas_data_cmplt(struct urb *urb)
> struct scsi_cmnd *cmnd = urb->context;
> struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
> - struct scsi_data_buffer *sdb = NULL;
> + struct scsi_data_buffer *sdb = &cmnd->sdb;
> unsigned long flags;
> int status = urb->status;
>
> spin_lock_irqsave(&devinfo->lock, flags);
>
> if (cmdinfo->data_in_urb == urb) {
> - sdb = scsi_in(cmnd);
> cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
> cmdinfo->data_in_urb = NULL;
> } else if (cmdinfo->data_out_urb == urb) {
> - sdb = scsi_out(cmnd);
> cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
> cmdinfo->data_out_urb = NULL;
> }
> - if (sdb == NULL) {
> - WARN_ON_ONCE(1);
> - goto out;
> - }
>
> if (devinfo->resetting)
> goto out;
> @@ -426,8 +420,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp,
> struct usb_device *udev = devinfo->udev;
> struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> struct urb *urb = usb_alloc_urb(0, gfp);
> - struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
> - ? scsi_in(cmnd) : scsi_out(cmnd);
> + struct scsi_data_buffer *sdb = &cmnd->sdb;
> unsigned int pipe = (dir == DMA_FROM_DEVICE)
> ? devinfo->data_in_pipe : devinfo->data_out_pipe;
>
> diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
> index c891ada3c5c2..681f0ca808d7 100644
> --- a/include/scsi/scsi_cmnd.h
> +++ b/include/scsi/scsi_cmnd.h
> @@ -209,23 +209,6 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd)
> #define scsi_for_each_sg(cmd, sg, nseg, __i) \
> for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
>
> -static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd)
> -{
> - return blk_bidi_rq(cmd->request) &&
> - (cmd->request->next_rq->special != NULL);
> -}
> -
> -static inline struct scsi_data_buffer *scsi_in(struct scsi_cmnd *cmd)
> -{
> - return scsi_bidi_cmnd(cmd) ?
> - cmd->request->next_rq->special : &cmd->sdb;
> -}
> -
> -static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd)
> -{
> - return &cmd->sdb;
> -}
> -
> static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
> void *buf, int buflen)
> {
> @@ -347,7 +330,7 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)
>
> static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
> {
> - unsigned int xfer_len = scsi_out(scmd)->length;
> + unsigned int xfer_len = scmd->sdb.length;
> unsigned int prot_interval = scsi_prot_interval(scmd);
>
> if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
> diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
> index 2b7e227960e1..3810b340551c 100644
> --- a/include/scsi/scsi_eh.h
> +++ b/include/scsi/scsi_eh.h
> @@ -39,7 +39,6 @@ struct scsi_eh_save {
> unsigned char prot_op;
> unsigned char *cmnd;
> struct scsi_data_buffer sdb;
> - struct request *next_rq;
> /* new command support */
> unsigned char eh_cmnd[BLK_MAX_CDB];
> struct scatterlist sense_sgl;
>