aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-08-31 18:09:26 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-02 14:37:11 -0400
commit98a9416af08385f8497e9c1595113a81aefa5d49 (patch)
tree0029f8f14bd70a366f2bebe54eb386cf1021ca60
parent60ecebf5a10e42f5e2d6e07eb9e24bdee8500b81 (diff)
[SCSI] attempt to complete r2t with data len greater than max burst
A couple targets like string bean and MDS, send r2ts with a data len greater than the max burst we agreed to. We were being strict in our enforcing of the iscsi rfc in that code path, but there is no driver limitation that prevents us from fullfilling the request. To allow those targets to work we will ignore the max_burst length and send as much data as the target asks for assuming it has consciously decided to override its max burst length. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/scsi/iscsi_tcp.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a97a3a4e99eb..d6927f1a6b65 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -358,8 +358,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
358 int r2tsn = be32_to_cpu(rhdr->r2tsn); 358 int r2tsn = be32_to_cpu(rhdr->r2tsn);
359 int rc; 359 int rc;
360 360
361 if (tcp_conn->in.datalen) 361 if (tcp_conn->in.datalen) {
362 printk(KERN_ERR "iscsi_tcp: invalid R2t with datalen %d\n",
363 tcp_conn->in.datalen);
362 return ISCSI_ERR_DATALEN; 364 return ISCSI_ERR_DATALEN;
365 }
363 366
364 if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn) 367 if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
365 return ISCSI_ERR_R2TSN; 368 return ISCSI_ERR_R2TSN;
@@ -385,15 +388,23 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
385 388
386 r2t->exp_statsn = rhdr->statsn; 389 r2t->exp_statsn = rhdr->statsn;
387 r2t->data_length = be32_to_cpu(rhdr->data_length); 390 r2t->data_length = be32_to_cpu(rhdr->data_length);
388 if (r2t->data_length == 0 || 391 if (r2t->data_length == 0) {
389 r2t->data_length > session->max_burst) { 392 printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n");
390 spin_unlock(&session->lock); 393 spin_unlock(&session->lock);
391 return ISCSI_ERR_DATALEN; 394 return ISCSI_ERR_DATALEN;
392 } 395 }
393 396
397 if (r2t->data_length > session->max_burst)
398 debug_scsi("invalid R2T with data len %u and max burst %u."
399 "Attempting to execute request.\n",
400 r2t->data_length, session->max_burst);
401
394 r2t->data_offset = be32_to_cpu(rhdr->data_offset); 402 r2t->data_offset = be32_to_cpu(rhdr->data_offset);
395 if (r2t->data_offset + r2t->data_length > ctask->total_length) { 403 if (r2t->data_offset + r2t->data_length > ctask->total_length) {
396 spin_unlock(&session->lock); 404 spin_unlock(&session->lock);
405 printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at "
406 "offset %u and total length %d\n", r2t->data_length,
407 r2t->data_offset, ctask->total_length);
397 return ISCSI_ERR_DATALEN; 408 return ISCSI_ERR_DATALEN;
398 } 409 }
399 410