Procházet zdrojové kódy

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).
tags/v0.9.3
Michael Brown před 16 roky
rodič
revize
428c6342bc
1 změnil soubory, kde provedl 19 přidání a 7 odebrání
  1. 19
    7
      src/net/tcp/iscsi.c

+ 19
- 7
src/net/tcp/iscsi.c Zobrazit soubor

@@ -270,7 +270,7 @@ static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi,
270 270
  */
271 271
 static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
272 272
 			      const void *data, size_t len,
273
-			      size_t remaining __unused ) {
273
+			      size_t remaining ) {
274 274
 	struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
275 275
 	unsigned long offset;
276 276
 
@@ -281,14 +281,16 @@ static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
281 281
 	assert ( ( offset + len ) <= iscsi->command->data_in_len );
282 282
 	copy_to_user ( iscsi->command->data_in, offset, data, len );
283 283
 
284
-	/* Record SCSI status, if present */
285
-	if ( data_in->flags & ISCSI_DATA_FLAG_STATUS )
286
-		iscsi->command->status = data_in->status;
284
+	/* Wait for whole SCSI response to arrive */
285
+	if ( remaining )
286
+		return 0;
287 287
 
288
-	/* If this is the end, flag as complete */
289
-	if ( ( offset + len ) == iscsi->command->data_in_len ) {
288
+	/* Mark as completed if status is present */
289
+	if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
290
+		assert ( ( offset + len ) == iscsi->command->data_in_len );
290 291
 		assert ( data_in->flags & ISCSI_FLAG_FINAL );
291
-		assert ( remaining == 0 );
292
+		iscsi->command->status = data_in->status;
293
+		/* iSCSI cannot return an error status via a data-in */
292 294
 		iscsi_scsi_done ( iscsi, 0 );
293 295
 	}
294 296
 
@@ -568,6 +570,7 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
568 570
  */
569 571
 static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
570 572
 					      const char *value ) {
573
+	char *separator;
571 574
 
572 575
 	DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
573 576
 
@@ -576,6 +579,15 @@ static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
576 579
 	iscsi->target_address = strdup ( value );
577 580
 	if ( ! iscsi->target_address )
578 581
 		return -ENOMEM;
582
+
583
+	/* Replace target port */
584
+	iscsi->target_port = htons ( ISCSI_PORT );
585
+	separator = strchr ( iscsi->target_address, ':' );
586
+	if ( separator ) {
587
+		*separator = '\0';
588
+		iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
589
+	}
590
+
579 591
 	return 0;
580 592
 }
581 593
 

Načítá se…
Zrušit
Uložit