All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
To: Bart Van Assche <Bart.VanAssche@sandisk.com>
Cc: "hch@lst.de" <hch@lst.de>, "ddiss@suse.de" <ddiss@suse.de>,
	"hare@suse.com" <hare@suse.com>,
	"target-devel@vger.kernel.org" <target-devel@vger.kernel.org>,
	"agrover@redhat.com" <agrover@redhat.com>,
	"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: Re: [PATCH 05/19] target: Allocate sg-list correctly
Date: Tue, 09 May 2017 23:12:31 -0700	[thread overview]
Message-ID: <1494396751.16894.106.camel@haakon3.risingtidesystems.com> (raw)
In-Reply-To: <1494389026.16894.69.camel@haakon3.risingtidesystems.com>

On Tue, 2017-05-09 at 21:03 -0700, Nicholas A. Bellinger wrote:
> On Mon, 2017-05-08 at 17:46 +0000, Bart Van Assche wrote:
> > On Sun, 2017-05-07 at 15:45 -0700, Nicholas A. Bellinger wrote:
> > > On Thu, 2017-05-04 at 15:50 -0700, Bart Van Assche wrote:
> > > > Avoid that the iSCSI target driver complains about "Initial page entry
> > > > out-of-bounds" and closes the connection if the SCSI Data-Out buffer
> > > > is larger than the buffer size specified through the CDB. This patch
> > > > prevents that running the libiscsi regression tests against LIO trigger
> > > > an infinite loop of libiscsi submitting a command, LIO closing the
> > > > connection and libiscsi resubmitting the same command.
> > > > 
> > > 
> > > This statement and patch is incorrect.
> > > 
> > > target-core has always rejected SCF_SCSI_DATA_CDB WRITEs with
> > > overflow/underflow since day one:
> > > 
> > > From target_cmd_size_check():
> > > 
> > >         } else if (size != cmd->data_length) {
> > >                 pr_warn("TARGET_CORE[%s]: Expected Transfer Length:"
> > >                         " %u does not match SCSI CDB Length: %u for SAM Opcode:"
> > >                         " 0x%02x\n", cmd->se_tfo->get_fabric_name(),
> > >                                 cmd->data_length, size, cmd->t_task_cdb[0]);
> > > 
> > >                 if (cmd->data_direction == DMA_TO_DEVICE &&
> > >                     cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
> > >                         pr_err("Rejecting underflow/overflow WRITE data\n");
> > >                         return TCM_INVALID_CDB_FIELD;
> > >                 }
> > > 
> > >                 ......
> > >         }
> > 
> > Hello Nic,
> > 
> > That behavior is as far as I know not compliant with the SCSI specs. In e.g.
> > the libiscsi test suite there are many tests that verify that a SCSI target
> > implementation reports OVERFLOW or UNDERFLOW where LIO today reports INVALID
> > FIELD IN CDB. See e.g. https://github.com/sahlberg/libiscsi/blob/master/test-tool/test_read10_residuals.c.
> 
> Yes, I understand what the test does.  In practice this has never been
> an issue, and we've not actually encountered a host that sends overflow
> or underflow for a WRITE CDB of type SCF_SCSI_DATA_CDB.
> 
> If there is a host environment that does, I'd like to hear about it.
> 
> In any event, the point is your patch to add sbc_parse_verify() broke
> existing behavior of WRITE_VERIFY_* by dropping SCF_SCSI_DATA_CDB
> assignment for all cases.
> 
> > From RFC 3720 (apparently written from the point-of-view of transfers from
> > target to initiator):
> > 
> >      bit 5 - (O) set for Residual Overflow.  In this case, the Residual
> >        Count indicates the number of bytes that were not transferred
> >        because the initiator's Expected Data Transfer Length was not
> >        sufficient.
> > 
> >      bit 6 - (U) set for Residual Underflow.  In this case, the Residual
> >        Count indicates the number of bytes that were not transferred out
> >        of the number of bytes that were expected to be transferred.
> > 
> > But even with the current implementation, why do you think that the reject by
> > target_cmd_size_check() would be sufficient to prevent the behavior I described?
> > From source file iscsi_target.c:
> > 
> > static int
> > iscsit_handle_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
> > 			   unsigned char *buf)
> > {
> > 	struct iscsi_scsi_req *hdr = (struct iscsi_scsi_req *)buf;
> > 	int rc, immed_data;
> > 	bool dump_payload = false;
> > 
> > 	rc = iscsit_setup_scsi_cmd(conn, cmd, buf);
> > 	if (rc < 0)
> > 		return 0;
> > 	/*
> > 	 * Allocation iovecs needed for struct socket operations for
> > 	 * traditional iSCSI block I/O.
> > 	 */
> > 	if (iscsit_allocate_iovecs(cmd) < 0) {
> > 		return iscsit_reject_cmd(cmd,
> > 				ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
> > 	}
> > 	immed_data = cmd->immediate_data;
> > 
> > 	rc = iscsit_process_scsi_cmd(conn, cmd, hdr);
> > 	if (rc < 0)
> > 		return rc;
> > 	else if (rc > 0)
> > 		dump_payload = true;
> > 
> > 	if (!immed_data)
> > 		return 0;
> > 
> > 	return iscsit_get_immediate_data(cmd, hdr, dump_payload);
> > }
> > 
> > In other words, if target_setup_cmd_from_cdb() returns a sense code (positive
> > value) iscsit_get_immediate_data() will call rx_data() to receive that immediate
> > data if there is immediate data and dump_payload == false. The code that controls
> > the value of dump_payload is as follows (from iscsit_process_scsi_cmd()):
> > 
> > 	if (cmd->sense_reason) {
> > 		if (cmd->reject_reason)
> > 			return 0;
> > 
> > 		return 1;
> > 	}
> > 
> > In other words, if both .sense_reason and .reject_reason are set before
> > iscsit_process_scsi_cmd() is called then iscsit_get_immediate_data() can call
> > rx_data() to receive more data than what fits in the allocated buffer.
> > 
> 
> Look again.  It's the code right below what you're referencing above, at
> the bottom of iscsit_process_scsi_cmd():
> 
>         /*
>          * Call directly into transport_generic_new_cmd() to perform
>          * the backend memory allocation.
>          */
>         cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
>         if (cmd->sense_reason)
>                 return 1;
> 
> which propigates '1' up to iscsit_handle_scsi_cmd(), passing
> 'dump_payload = true' into iscsit_get_immediate_data() and thereby calls
> iscsit_dump_data_payload() to discard immediate data into a separate
> throw away buffer.
> 
> Try it with sg_raw or libiscsi and you'll see.

Oh btw, to further clarify your earlier question about the following
code in iscsit_process_scsi_cmd() returning zero when cmd->sense_reason
&& cmd->reject_reason is true:

        if (cmd->sense_reason) {
                if (cmd->reject_reason)
                        return 0;

                return 1;
        }

The earlier callers that invoke iscsi_add_reject*() all return -1 from
iscsit_setup_scsi_cmd(), which ensures iscsit_handle_scsi_cmd() returns 
and this code to return '0' is never reached.

  reply	other threads:[~2017-05-10  6:12 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20170504225102.8931-1-bart.vanassche@sandisk.com>
2017-05-04 22:50 ` [PATCH 03/19] target: Avoid that aborting a command sporadically hangs Bart Van Assche
2017-05-05  6:12   ` Hannes Reinecke
2017-05-05  8:53   ` Christoph Hellwig
2017-05-05 15:00     ` Bart Van Assche
2017-05-11  0:23     ` Bart Van Assche
2017-05-07 22:20   ` Nicholas A. Bellinger
2017-05-08 21:25     ` Bart Van Assche
2017-05-10  4:48       ` Nicholas A. Bellinger
2017-05-04 22:50 ` [PATCH 04/19] target/fileio: Avoid that zero-length READ and WRITE commands hang Bart Van Assche
2017-05-05  6:14   ` Hannes Reinecke
2017-05-05  8:54   ` Christoph Hellwig
2017-05-07 22:28   ` Nicholas A. Bellinger
2017-05-04 22:50 ` [PATCH 05/19] target: Allocate sg-list correctly Bart Van Assche
2017-05-05  6:15   ` Hannes Reinecke
2017-05-05  9:06   ` Christoph Hellwig
2017-05-05 15:49     ` Bart Van Assche
2017-05-07 22:45   ` Nicholas A. Bellinger
2017-05-08 17:46     ` Bart Van Assche
2017-05-10  4:03       ` Nicholas A. Bellinger
2017-05-10  6:12         ` Nicholas A. Bellinger [this message]
2017-05-10 20:31         ` Bart Van Assche
2017-05-11  5:28           ` Nicholas A. Bellinger
2017-05-04 22:50 ` [PATCH 06/19] target: Fix data buffer size for VERIFY and WRITE AND VERIFY commands Bart Van Assche
2017-05-05  9:42   ` Christoph Hellwig
2017-05-05 15:51     ` Bart Van Assche
2017-05-07 22:49   ` Nicholas A. Bellinger
2017-05-08 18:07     ` Bart Van Assche
2017-05-10  4:28       ` Nicholas A. Bellinger
2017-05-10 15:16         ` Bart Van Assche
2017-05-11  5:09           ` Nicholas A. Bellinger
2017-05-04 22:51 ` [PATCH 17/19] target/iscsi: Simplify timer manipulation code Bart Van Assche
2017-05-05 11:24   ` Hannes Reinecke

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1494396751.16894.106.camel@haakon3.risingtidesystems.com \
    --to=nab@linux-iscsi.org \
    --cc=Bart.VanAssche@sandisk.com \
    --cc=agrover@redhat.com \
    --cc=ddiss@suse.de \
    --cc=hare@suse.com \
    --cc=hch@lst.de \
    --cc=stable@vger.kernel.org \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.