Author: mav
Date: Sat Sep 12 16:30:01 2015
New Revision: 287715
URL: https://svnweb.freebsd.org/changeset/base/287715

Log:
  Improve XCOPY error reporting.

Modified:
  head/sys/cam/ctl/ctl_tpc.c
  head/sys/cam/ctl/ctl_tpc_local.c

Modified: head/sys/cam/ctl/ctl_tpc.c
==============================================================================
--- head/sys/cam/ctl/ctl_tpc.c  Sat Sep 12 14:20:11 2015        (r287714)
+++ head/sys/cam/ctl/ctl_tpc.c  Sat Sep 12 16:30:01 2015        (r287715)
@@ -1589,6 +1589,10 @@ ctl_extended_copy_lid1(struct ctl_scsiio
        cdb = (struct scsi_extended_copy *)ctsio->cdb;
        len = scsi_4btoul(cdb->length);
 
+       if (len == 0) {
+               ctl_set_success(ctsio);
+               goto done;
+       }
        if (len < sizeof(struct scsi_extended_copy_lid1_data) ||
            len > sizeof(struct scsi_extended_copy_lid1_data) +
            TPC_MAX_LIST + TPC_MAX_INLINE) {
@@ -1619,20 +1623,22 @@ ctl_extended_copy_lid1(struct ctl_scsiio
        lencscd = scsi_2btoul(data->cscd_list_length);
        lenseg = scsi_4btoul(data->segment_list_length);
        leninl = scsi_4btoul(data->inline_data_length);
-       if (len < sizeof(struct scsi_extended_copy_lid1_data) +
-           lencscd + lenseg + leninl ||
-           leninl > TPC_MAX_INLINE) {
-               ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 0,
-                   /*field*/ 2, /*bit_valid*/ 0, /*bit*/ 0);
-               goto done;
-       }
        if (lencscd > TPC_MAX_CSCDS * sizeof(struct scsi_ec_cscd)) {
                ctl_set_sense(ctsio, /*current_error*/ 1,
                    /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
                    /*asc*/ 0x26, /*ascq*/ 0x06, SSD_ELEM_NONE);
                goto done;
        }
-       if (lencscd + lenseg > TPC_MAX_LIST) {
+       if (lenseg > TPC_MAX_SEGS * sizeof(struct scsi_ec_segment)) {
+               ctl_set_sense(ctsio, /*current_error*/ 1,
+                   /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
+                   /*asc*/ 0x26, /*ascq*/ 0x08, SSD_ELEM_NONE);
+               goto done;
+       }
+       if (lencscd + lenseg > TPC_MAX_LIST ||
+           leninl > TPC_MAX_INLINE ||
+           len < sizeof(struct scsi_extended_copy_lid1_data) +
+            lencscd + lenseg + leninl) {
                ctl_set_param_len_error(ctsio);
                goto done;
        }
@@ -1716,6 +1722,10 @@ ctl_extended_copy_lid4(struct ctl_scsiio
        cdb = (struct scsi_extended_copy *)ctsio->cdb;
        len = scsi_4btoul(cdb->length);
 
+       if (len == 0) {
+               ctl_set_success(ctsio);
+               goto done;
+       }
        if (len < sizeof(struct scsi_extended_copy_lid4_data) ||
            len > sizeof(struct scsi_extended_copy_lid4_data) +
            TPC_MAX_LIST + TPC_MAX_INLINE) {
@@ -1746,20 +1756,22 @@ ctl_extended_copy_lid4(struct ctl_scsiio
        lencscd = scsi_2btoul(data->cscd_list_length);
        lenseg = scsi_2btoul(data->segment_list_length);
        leninl = scsi_2btoul(data->inline_data_length);
-       if (len < sizeof(struct scsi_extended_copy_lid4_data) +
-           lencscd + lenseg + leninl ||
-           leninl > TPC_MAX_INLINE) {
-               ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 0,
-                   /*field*/ 2, /*bit_valid*/ 0, /*bit*/ 0);
-               goto done;
-       }
        if (lencscd > TPC_MAX_CSCDS * sizeof(struct scsi_ec_cscd)) {
                ctl_set_sense(ctsio, /*current_error*/ 1,
                    /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
                    /*asc*/ 0x26, /*ascq*/ 0x06, SSD_ELEM_NONE);
                goto done;
        }
-       if (lencscd + lenseg > TPC_MAX_LIST) {
+       if (lenseg > TPC_MAX_SEGS * sizeof(struct scsi_ec_segment)) {
+               ctl_set_sense(ctsio, /*current_error*/ 1,
+                   /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
+                   /*asc*/ 0x26, /*ascq*/ 0x08, SSD_ELEM_NONE);
+               goto done;
+       }
+       if (lencscd + lenseg > TPC_MAX_LIST ||
+           leninl > TPC_MAX_INLINE ||
+           len < sizeof(struct scsi_extended_copy_lid1_data) +
+            lencscd + lenseg + leninl) {
                ctl_set_param_len_error(ctsio);
                goto done;
        }

Modified: head/sys/cam/ctl/ctl_tpc_local.c
==============================================================================
--- head/sys/cam/ctl/ctl_tpc_local.c    Sat Sep 12 14:20:11 2015        
(r287714)
+++ head/sys/cam/ctl/ctl_tpc_local.c    Sat Sep 12 16:30:01 2015        
(r287715)
@@ -281,7 +281,8 @@ tpcl_resolve(struct ctl_softc *softc, in
        struct ctl_lun *lun;
        uint64_t lunid = UINT64_MAX;
 
-       if (cscd->type_code != EC_CSCD_ID)
+       if (cscd->type_code != EC_CSCD_ID ||
+           (cscd->luidt_pdt & EC_LUIDT_MASK) != EC_LUIDT_LUN)
                return (lunid);
 
        cscdid = (struct scsi_ec_cscd_id *)cscd;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to