Revision 24d3bd67
b/block/iscsi.c | ||
---|---|---|
1067 | 1067 |
}; |
1068 | 1068 |
|
1069 | 1069 |
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun, |
1070 |
int evpd, int pc, Error **errp) |
|
1070 |
int evpd, int pc, void **inq, Error **errp)
|
|
1071 | 1071 |
{ |
1072 | 1072 |
int full_size; |
1073 | 1073 |
struct scsi_task *task = NULL; |
... | ... | |
1086 | 1086 |
} |
1087 | 1087 |
} |
1088 | 1088 |
|
1089 |
*inq = scsi_datain_unmarshall(task); |
|
1090 |
if (*inq == NULL) { |
|
1091 |
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); |
|
1092 |
goto fail; |
|
1093 |
} |
|
1094 |
|
|
1089 | 1095 |
return task; |
1090 | 1096 |
|
1091 | 1097 |
fail: |
1092 | 1098 |
error_setg(errp, "iSCSI: Inquiry command failed : %s", |
1093 | 1099 |
iscsi_get_error(iscsi)); |
1094 |
if (task) { |
|
1100 |
if (task != NULL) {
|
|
1095 | 1101 |
scsi_free_scsi_task(task); |
1096 |
return NULL; |
|
1097 | 1102 |
} |
1098 | 1103 |
return NULL; |
1099 | 1104 |
} |
... | ... | |
1114 | 1119 |
struct iscsi_url *iscsi_url = NULL; |
1115 | 1120 |
struct scsi_task *task = NULL; |
1116 | 1121 |
struct scsi_inquiry_standard *inq = NULL; |
1122 |
struct scsi_inquiry_supported_pages *inq_vpd; |
|
1117 | 1123 |
char *initiator_name = NULL; |
1118 | 1124 |
QemuOpts *opts; |
1119 | 1125 |
Error *local_err = NULL; |
1120 | 1126 |
const char *filename; |
1121 |
int ret; |
|
1127 |
int i, ret;
|
|
1122 | 1128 |
|
1123 | 1129 |
if ((BDRV_SECTOR_SIZE % 512) != 0) { |
1124 | 1130 |
error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. " |
... | ... | |
1204 | 1210 |
|
1205 | 1211 |
iscsilun->iscsi = iscsi; |
1206 | 1212 |
iscsilun->lun = iscsi_url->lun; |
1213 |
iscsilun->has_write_same = true; |
|
1207 | 1214 |
|
1208 |
task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36); |
|
1209 |
|
|
1210 |
if (task == NULL || task->status != SCSI_STATUS_GOOD) { |
|
1211 |
error_setg(errp, "iSCSI: failed to send inquiry command."); |
|
1212 |
ret = -EINVAL; |
|
1213 |
goto out; |
|
1214 |
} |
|
1215 |
|
|
1216 |
inq = scsi_datain_unmarshall(task); |
|
1217 |
if (inq == NULL) { |
|
1218 |
error_setg(errp, "iSCSI: Failed to unmarshall inquiry data."); |
|
1215 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0, |
|
1216 |
(void **) &inq, errp); |
|
1217 |
if (task == NULL) { |
|
1219 | 1218 |
ret = -EINVAL; |
1220 | 1219 |
goto out; |
1221 | 1220 |
} |
1222 |
|
|
1223 | 1221 |
iscsilun->type = inq->periperal_device_type; |
1224 |
iscsilun->has_write_same = true; |
|
1222 |
scsi_free_scsi_task(task); |
|
1223 |
task = NULL; |
|
1225 | 1224 |
|
1226 | 1225 |
iscsi_readcapacity_sync(iscsilun, &local_err); |
1227 | 1226 |
if (local_err != NULL) { |
... | ... | |
1240 | 1239 |
bs->sg = 1; |
1241 | 1240 |
} |
1242 | 1241 |
|
1243 |
if (iscsilun->lbpme) { |
|
1244 |
struct scsi_inquiry_logical_block_provisioning *inq_lbp; |
|
1245 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, |
|
1246 |
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, |
|
1247 |
errp); |
|
1248 |
if (task == NULL) { |
|
1249 |
ret = -EINVAL; |
|
1250 |
goto out; |
|
1251 |
} |
|
1252 |
inq_lbp = scsi_datain_unmarshall(task); |
|
1253 |
if (inq_lbp == NULL) { |
|
1254 |
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); |
|
1255 |
ret = -EINVAL; |
|
1256 |
goto out; |
|
1257 |
} |
|
1258 |
memcpy(&iscsilun->lbp, inq_lbp, |
|
1259 |
sizeof(struct scsi_inquiry_logical_block_provisioning)); |
|
1260 |
scsi_free_scsi_task(task); |
|
1261 |
task = NULL; |
|
1242 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, |
|
1243 |
SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES, |
|
1244 |
(void **) &inq_vpd, errp); |
|
1245 |
if (task == NULL) { |
|
1246 |
ret = -EINVAL; |
|
1247 |
goto out; |
|
1262 | 1248 |
} |
1263 |
|
|
1264 |
if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) { |
|
1249 |
for (i = 0; i < inq_vpd->num_pages; i++) { |
|
1250 |
struct scsi_task *inq_task; |
|
1251 |
struct scsi_inquiry_logical_block_provisioning *inq_lbp; |
|
1265 | 1252 |
struct scsi_inquiry_block_limits *inq_bl; |
1266 |
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, |
|
1267 |
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp); |
|
1268 |
if (task == NULL) { |
|
1269 |
ret = -EINVAL; |
|
1270 |
goto out; |
|
1271 |
} |
|
1272 |
inq_bl = scsi_datain_unmarshall(task); |
|
1273 |
if (inq_bl == NULL) { |
|
1274 |
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob"); |
|
1275 |
ret = -EINVAL; |
|
1276 |
goto out; |
|
1253 |
switch (inq_vpd->pages[i]) { |
|
1254 |
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING: |
|
1255 |
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, |
|
1256 |
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING, |
|
1257 |
(void **) &inq_lbp, errp); |
|
1258 |
if (inq_task == NULL) { |
|
1259 |
ret = -EINVAL; |
|
1260 |
goto out; |
|
1261 |
} |
|
1262 |
memcpy(&iscsilun->lbp, inq_lbp, |
|
1263 |
sizeof(struct scsi_inquiry_logical_block_provisioning)); |
|
1264 |
scsi_free_scsi_task(inq_task); |
|
1265 |
break; |
|
1266 |
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS: |
|
1267 |
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1, |
|
1268 |
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, |
|
1269 |
(void **) &inq_bl, errp); |
|
1270 |
if (inq_task == NULL) { |
|
1271 |
ret = -EINVAL; |
|
1272 |
goto out; |
|
1273 |
} |
|
1274 |
memcpy(&iscsilun->bl, inq_bl, |
|
1275 |
sizeof(struct scsi_inquiry_block_limits)); |
|
1276 |
scsi_free_scsi_task(inq_task); |
|
1277 |
break; |
|
1278 |
default: |
|
1279 |
break; |
|
1277 | 1280 |
} |
1278 |
memcpy(&iscsilun->bl, inq_bl, |
|
1279 |
sizeof(struct scsi_inquiry_block_limits)); |
|
1280 |
scsi_free_scsi_task(task); |
|
1281 |
task = NULL; |
|
1282 | 1281 |
} |
1282 |
scsi_free_scsi_task(task); |
|
1283 |
task = NULL; |
|
1283 | 1284 |
|
1284 | 1285 |
#if defined(LIBISCSI_FEATURE_NOP_COUNTER) |
1285 | 1286 |
/* Set up a timer for sending out iSCSI NOPs */ |
Also available in: Unified diff