Fixes for EqualLogic iSCSI targets:
Allow port numbers in iSCSI redirection. Wait for SCSI status, not just the final data-in (which may be followed by an explicit SCSI Response PDU if the S bit is not set).
This commit is contained in:
parent
5e4e267177
commit
428c6342bc
|
@ -270,7 +270,7 @@ static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi,
|
||||||
*/
|
*/
|
||||||
static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
|
static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
|
||||||
const void *data, size_t len,
|
const void *data, size_t len,
|
||||||
size_t remaining __unused ) {
|
size_t remaining ) {
|
||||||
struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
|
struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
|
|
||||||
|
@ -281,14 +281,16 @@ static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
|
||||||
assert ( ( offset + len ) <= iscsi->command->data_in_len );
|
assert ( ( offset + len ) <= iscsi->command->data_in_len );
|
||||||
copy_to_user ( iscsi->command->data_in, offset, data, len );
|
copy_to_user ( iscsi->command->data_in, offset, data, len );
|
||||||
|
|
||||||
/* Record SCSI status, if present */
|
/* Wait for whole SCSI response to arrive */
|
||||||
if ( data_in->flags & ISCSI_DATA_FLAG_STATUS )
|
if ( remaining )
|
||||||
iscsi->command->status = data_in->status;
|
return 0;
|
||||||
|
|
||||||
/* If this is the end, flag as complete */
|
/* Mark as completed if status is present */
|
||||||
if ( ( offset + len ) == iscsi->command->data_in_len ) {
|
if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
|
||||||
|
assert ( ( offset + len ) == iscsi->command->data_in_len );
|
||||||
assert ( data_in->flags & ISCSI_FLAG_FINAL );
|
assert ( data_in->flags & ISCSI_FLAG_FINAL );
|
||||||
assert ( remaining == 0 );
|
iscsi->command->status = data_in->status;
|
||||||
|
/* iSCSI cannot return an error status via a data-in */
|
||||||
iscsi_scsi_done ( iscsi, 0 );
|
iscsi_scsi_done ( iscsi, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,6 +570,7 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
|
||||||
*/
|
*/
|
||||||
static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
|
static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
|
||||||
const char *value ) {
|
const char *value ) {
|
||||||
|
char *separator;
|
||||||
|
|
||||||
DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
|
DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
|
||||||
|
|
||||||
|
@ -576,6 +579,15 @@ static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
|
||||||
iscsi->target_address = strdup ( value );
|
iscsi->target_address = strdup ( value );
|
||||||
if ( ! iscsi->target_address )
|
if ( ! iscsi->target_address )
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Replace target port */
|
||||||
|
iscsi->target_port = htons ( ISCSI_PORT );
|
||||||
|
separator = strchr ( iscsi->target_address, ':' );
|
||||||
|
if ( separator ) {
|
||||||
|
*separator = '\0';
|
||||||
|
iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue