From: <ag...@us...> - 2014-01-03 08:03:34
|
Revision: 497 http://sourceforge.net/p/iscsitarget/code/497 Author: agr1 Date: 2014-01-03 08:03:31 +0000 (Fri, 03 Jan 2014) Log Message: ----------- Fix SERVICE ACTION IN / READ CAPACITY (16) Rev. 488 "Fix SAI/READ CAPACITY(16) parameter data length" was fauly in that didn't respect the requirement that SCSI commands which have an ALLOCATION LENGTH in the request field must not set an iSCSI residual - cf. RFC 5048, 3.1.2: "If the Expected Data Transfer Length (EDTL) in the iSCSI header of the SCSI Command PDU [...] is set to at least as large as that ALLOCATION LENGTH, the SCSI layer truncation prevents an iSCSI Residual Overflow from occurring. A SCSI initiator can detect that such truncation has occurred via other information at the SCSI layer." Signed-off-by: Arne Redlich <arn...@go...> Modified Paths: -------------- trunk/kernel/target_disk.c Modified: trunk/kernel/target_disk.c =================================================================== --- trunk/kernel/target_disk.c 2013-07-03 19:34:10 UTC (rev 496) +++ trunk/kernel/target_disk.c 2014-01-03 08:03:31 UTC (rev 497) @@ -9,6 +9,7 @@ #include <linux/ctype.h> #include <scsi/scsi.h> +#include <asm/unaligned.h> #include "iscsi.h" #include "iscsi_dbg.h" @@ -357,16 +358,18 @@ struct tio *tio = cmnd->tio; u32 *data; u64 *data64; - + u32 alloc_len; + const u8* cdb = cmnd_hdr(cmnd)->scb; assert(!tio); /* only READ_CAPACITY_16 service action is currently supported */ - if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) != 0x10) { + if ((cdb[1] & 0x1F) != 0x10) { /* Invalid Field In CDB */ iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0); return; } + alloc_len = get_unaligned_be32(&cdb[10]); tio = cmnd->tio = tio_alloc(1); data = page_address(tio->pvec[0]); assert(data); @@ -375,7 +378,7 @@ data64[0] = cpu_to_be64(cmnd->lun->blk_cnt - 1); data[2] = cpu_to_be32(1UL << cmnd->lun->blk_shift); - tio_set(tio, 32, 0); + tio_set(tio, min_t(u32, alloc_len, 32), 0); } static void build_read_response(struct iscsi_cmnd *cmnd) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |