aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/target/target_core_spc.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 556ea1b2cdd8..f87d4cef6d39 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -1203,17 +1203,13 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
1203 struct se_dev_entry *deve; 1203 struct se_dev_entry *deve;
1204 struct se_session *sess = cmd->se_sess; 1204 struct se_session *sess = cmd->se_sess;
1205 struct se_node_acl *nacl; 1205 struct se_node_acl *nacl;
1206 struct scsi_lun slun;
1206 unsigned char *buf; 1207 unsigned char *buf;
1207 u32 lun_count = 0, offset = 8; 1208 u32 lun_count = 0, offset = 8;
1208 1209 __be32 len;
1209 if (cmd->data_length < 16) {
1210 pr_warn("REPORT LUNS allocation length %u too small\n",
1211 cmd->data_length);
1212 return TCM_INVALID_CDB_FIELD;
1213 }
1214 1210
1215 buf = transport_kmap_data_sg(cmd); 1211 buf = transport_kmap_data_sg(cmd);
1216 if (!buf) 1212 if (cmd->data_length && !buf)
1217 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1213 return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
1218 1214
1219 /* 1215 /*
@@ -1234,10 +1230,12 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
1234 * See SPC2-R20 7.19. 1230 * See SPC2-R20 7.19.
1235 */ 1231 */
1236 lun_count++; 1232 lun_count++;
1237 if ((offset + 8) > cmd->data_length) 1233 if (offset >= cmd->data_length)
1238 continue; 1234 continue;
1239 1235
1240 int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); 1236 int_to_scsilun(deve->mapped_lun, &slun);
1237 memcpy(buf + offset, &slun,
1238 min(8u, cmd->data_length - offset));
1241 offset += 8; 1239 offset += 8;
1242 } 1240 }
1243 rcu_read_unlock(); 1241 rcu_read_unlock();
@@ -1250,16 +1248,18 @@ done:
1250 * If no LUNs are accessible, report virtual LUN 0. 1248 * If no LUNs are accessible, report virtual LUN 0.
1251 */ 1249 */
1252 if (lun_count == 0) { 1250 if (lun_count == 0) {
1253 int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); 1251 int_to_scsilun(0, &slun);
1252 if (cmd->data_length > 8)
1253 memcpy(buf + offset, &slun,
1254 min(8u, cmd->data_length - offset));
1254 lun_count = 1; 1255 lun_count = 1;
1255 } 1256 }
1256 1257
1257 lun_count *= 8; 1258 if (buf) {
1258 buf[0] = ((lun_count >> 24) & 0xff); 1259 len = cpu_to_be32(lun_count * 8);
1259 buf[1] = ((lun_count >> 16) & 0xff); 1260 memcpy(buf, &len, min_t(int, sizeof len, cmd->data_length));
1260 buf[2] = ((lun_count >> 8) & 0xff); 1261 transport_kunmap_data_sg(cmd);
1261 buf[3] = (lun_count & 0xff); 1262 }
1262 transport_kunmap_data_sg(cmd);
1263 1263
1264 target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8); 1264 target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8);
1265 return 0; 1265 return 0;