int T0200_read16_simple(const char *initiator, const char *url, int data_loss _U_, int show_info) { struct iscsi_context *iscsi; struct scsi_task *task; struct scsi_readcapacity10 *rc10; int ret, i, lun; uint32_t block_size, num_blocks; printf("0200_read16_simple:\n"); printf("===================\n"); if (show_info) { printf("Test basic READ16 functionality.\n"); printf("1, Verify we can read the first 1-256 blocks of the LUN.\n"); printf("2, Verify we can read the last 1-256 blocks of the LUN.\n"); printf("\n"); return 0; } iscsi = iscsi_context_login(initiator, url, &lun); if (iscsi == NULL) { printf("Failed to login to target\n"); return -1; } /* find the size of the LUN */ task = iscsi_readcapacity10_sync(iscsi, lun, 0, 0); if (task == NULL) { printf("Failed to send readcapacity10 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("Readcapacity command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } rc10 = scsi_datain_unmarshall(task); if (rc10 == NULL) { printf("failed to unmarshall readcapacity10 data. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } block_size = rc10->block_size; num_blocks = rc10->lba; scsi_free_scsi_task(task); ret = 0; /* read the first 1 - 256 blocks at the start of the LUN */ printf("Reading first 1-256 blocks ... "); for (i=1; i<=256; i++) { task = iscsi_read16_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } scsi_free_scsi_task(task); } printf("[OK]\n"); /* read the last 1 - 256 blocks at the end of the LUN */ printf("Reading last 1-256 blocks ... "); for (i=1; i<=256; i++) { task = iscsi_read16_sync(iscsi, lun, num_blocks +1 - i, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } scsi_free_scsi_task(task); } printf("[OK]\n"); finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
int T0270_verify16_simple(const char *initiator, const char *url, int data_loss _U_, int show_info) { struct iscsi_context *iscsi; struct scsi_task *task; struct scsi_task *vtask; struct scsi_readcapacity16 *rc16; int ret, i, lun; uint32_t block_size; printf("0270_verify16_simple:\n"); printf("=====================\n"); if (show_info) { printf("Test basic VERIFY16 functionality.\n"); printf("1, Read and verify the first 1-256 blocks of the LUN using READ16/VERIFY16.\n"); printf("\n"); return 0; } iscsi = iscsi_context_login(initiator, url, &lun); if (iscsi == NULL) { printf("Failed to login to target\n"); return -1; } /* find the size of the LUN */ task = iscsi_readcapacity16_sync(iscsi, lun); if (task == NULL) { printf("Failed to send readcapacity16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("Readcapacity16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } rc16 = scsi_datain_unmarshall(task); if (rc16 == NULL) { printf("failed to unmarshall readcapacity16 data. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } block_size = rc16->block_length; scsi_free_scsi_task(task); ret = 0; /* read and verify the first 1 - 256 blocks at the start of the LUN */ printf("Read+verify first 1-256 blocks ... "); for (i = 1; i <= 256; i++) { unsigned char *buf; task = iscsi_read16_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto test2; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto test2; } buf = task->datain.data; if (buf == NULL) { printf("[FAILED]\n"); printf("Failed to access DATA-IN buffer %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto test2; } vtask = iscsi_verify16_sync(iscsi, lun, buf, i * block_size, 0, 0, 1, 1, block_size); if (vtask == NULL) { printf("[FAILED]\n"); printf("Failed to send verify16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto test2; } if (vtask->status == SCSI_STATUS_CHECK_CONDITION && vtask->sense.key == SCSI_SENSE_ILLEGAL_REQUEST && vtask->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) { printf("[SKIPPED]\n"); printf("Opcode is not implemented on target\n"); scsi_free_scsi_task(task); scsi_free_scsi_task(vtask); ret = -2; goto finished; } if (vtask->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Verify16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); scsi_free_scsi_task(vtask); goto test2; } scsi_free_scsi_task(task); scsi_free_scsi_task(vtask); } printf("[OK]\n"); test2: finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
int T0350_orwrite_simple(const char *initiator, const char *url, int data_loss, int show_info) { struct iscsi_context *iscsi; struct scsi_task *task; struct scsi_readcapacity16 *rc16; int ret, i, j, lun; uint32_t block_size; uint64_t num_blocks; unsigned char r1data[4096 * 256]; unsigned char r2data[4096 * 256]; unsigned char ordata[4096 * 256]; printf("0350_orwrite_simple:\n"); printf("===================\n"); if (show_info) { printf("Test basic ORWRITE functionality.\n"); printf("1, Verify we can write the first 1-255 blocks of the LUN.\n"); printf("2, Verify we can write the last 1-255 blocks of the LUN.\n"); printf("\n"); return 0; } iscsi = iscsi_context_login(initiator, url, &lun); if (iscsi == NULL) { printf("Failed to login to target\n"); return -1; } /* find the size of the LUN */ task = iscsi_readcapacity16_sync(iscsi, lun); if (task == NULL) { printf("Failed to send READCAPACITY16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("READCAPACITY16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } rc16 = scsi_datain_unmarshall(task); if (rc16 == NULL) { printf("failed to unmarshall READCAPACITY16 data. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } block_size = rc16->block_length; num_blocks = rc16->returned_lba; scsi_free_scsi_task(task); if (!data_loss) { printf("--dataloss flag is not set. Skipping test\n"); ret = -2; goto finished; } ret = 0; /* write the first 1 - 255 blocks at the start of the LUN */ printf("Orwrite first 1-255 blocks ... "); for (i = 1; i < 256; i++) { task = iscsi_read16_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send READ16 command: %s\n", iscsi_get_error(iscsi)); ret++; goto test2; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("READ16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test2; } if (task->datain.data == NULL) { printf("[FAILED]\n"); printf("Failed to access DATA-IN buffer %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test2; } memcpy(r1data, task->datain.data, i * block_size); memset(ordata, 0x5a, i * block_size); for (j = 0; j < (int)(i * block_size); j++) { r2data[j] = r1data[j] | ordata[j]; } scsi_free_scsi_task(task); task = iscsi_orwrite_sync(iscsi, lun, 0, ordata, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send ORWRITE command: %s\n", iscsi_get_error(iscsi)); ret++; goto test2; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("ORWRITE command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test2; } scsi_free_scsi_task(task); task = iscsi_read16_sync(iscsi, lun, 0, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send READ16 command: %s\n", iscsi_get_error(iscsi)); ret++; goto test2; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("READ16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test2; } if (task->datain.data == NULL) { printf("[FAILED]\n"); printf("Failed to access DATA-IN buffer %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test2; } if (memcmp(r2data, task->datain.data, i * block_size)) { printf("[FAILED]\n"); printf("Blocks were not updated as expected.\n"); ret++; scsi_free_scsi_task(task); goto test2; } scsi_free_scsi_task(task); } printf("[OK]\n"); test2: /* write the last 1 - 255 blocks at the end of the LUN */ printf("Orwrite last 1-255 blocks ... "); for (i = 1; i < 256; i++) { task = iscsi_read16_sync(iscsi, lun, num_blocks + 1 - i, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send READ16 command: %s\n", iscsi_get_error(iscsi)); ret++; goto test3; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("READ16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test3; } if (task->datain.data == NULL) { printf("[FAILED]\n"); printf("Failed to access DATA-IN buffer %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test3; } memcpy(r1data, task->datain.data, i * block_size); memcpy(r1data, task->datain.data, i * block_size); memset(ordata, 0xa5, i * block_size); for (j = 0; j < (int)(i * block_size); j++) { r2data[j] = r1data[j] | ordata[j]; } scsi_free_scsi_task(task); task = iscsi_orwrite_sync(iscsi, lun, num_blocks + 1 - i, ordata, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send ORWRITE command: %s\n", iscsi_get_error(iscsi)); ret++; goto test3; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("ORWRITE command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test3; } scsi_free_scsi_task(task); task = iscsi_read16_sync(iscsi, lun, num_blocks + 1 - i, i * block_size, block_size, 0, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send READ16 command: %s\n", iscsi_get_error(iscsi)); ret++; goto test3; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("READ16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test3; } if (task->datain.data == NULL) { printf("[FAILED]\n"); printf("Failed to access DATA-IN buffer %s\n", iscsi_get_error(iscsi)); ret++; scsi_free_scsi_task(task); goto test3; } if (memcmp(r2data, task->datain.data, i * block_size)) { printf("[FAILED]\n"); printf("Blocks were not updated as expected.\n"); ret++; scsi_free_scsi_task(task); goto test3; } scsi_free_scsi_task(task); } printf("[OK]\n"); test3: finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
int T0201_read16_rdprotect(const char *initiator, const char *url, int data_loss _U_, int show_info) { struct iscsi_context *iscsi; struct scsi_task *task; struct scsi_readcapacity16 *rc16; int ret = 0, i, lun; uint32_t block_size; printf("0201_read16_rdprotect:\n"); printf("======================\n"); if (show_info) { printf("Test how READ16 handles the rdprotect bits\n"); printf("1, Any non-zero valued for rdprotect should fail.\n"); printf("\n"); return 0; } iscsi = iscsi_context_login(initiator, url, &lun); if (iscsi == NULL) { printf("Failed to login to target\n"); return -1; } /* find the size of the LUN */ task = iscsi_readcapacity16_sync(iscsi, lun); if (task == NULL) { printf("Failed to send READCAPACITY16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("READCAPACITY16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } rc16 = scsi_datain_unmarshall(task); if (rc16 == NULL) { printf("failed to unmarshall READCAPACITY16 data. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } block_size = rc16->block_length; if(rc16->prot_en != 0) { printf("device is formatted with protection information, skipping test\n"); scsi_free_scsi_task(task); ret = -2; goto finished; } scsi_free_scsi_task(task); printf("Read16 with RDPROTECT "); for (i = 1; i <= 7; i++) { task = iscsi_read16_sync(iscsi, lun, 0, block_size, block_size, i, 0, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_CHECK_CONDITION || task->sense.key != SCSI_SENSE_ILLEGAL_REQUEST || task->sense.ascq != SCSI_SENSE_ASCQ_INVALID_FIELD_IN_CDB) { printf("[FAILED]\n"); printf("Read16 with RDPROTECT!=0 should have failed with CHECK_CONDITION/ILLEGAL_REQUEST/INVALID_FIELD_IN_CDB\n"); ret = -1; scsi_free_scsi_task(task); goto finished; } scsi_free_scsi_task(task); } printf("[OK]\n"); finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
int T0202_read16_flags(const char *initiator, const char *url) { struct iscsi_context *iscsi; struct scsi_task *task; int ret = 0, lun; printf("0202_read16_flags:\n"); printf("==================\n"); if (show_info) { printf("Test how READ16 handles the flag bits\n"); printf("1, Reading with DPO should work\n"); printf("2, Reading with FUA should work\n"); printf("3, Reading with FUA_NV should work\n"); printf("4, Reading with FUA+FUA_NV should work\n"); printf("\n"); return 0; } iscsi = iscsi_context_login(initiator, url, &lun); if (iscsi == NULL) { printf("Failed to login to target\n"); return -1; } /* This test is only valid for SBC devices */ if (device_type != SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) { printf("LUN is not SBC device. Skipping test\n"); return -2; } printf("Read16 with DPO "); task = iscsi_read16_sync(iscsi, lun, 0, block_size, block_size, 0, 1, 0, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } printf("[OK]\n"); printf("Read16 with FUA "); task = iscsi_read16_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 1, 0, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } printf("[OK]\n"); printf("Read16 with FUA_NV "); task = iscsi_read16_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 0, 1, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } printf("[OK]\n"); printf("Read16 with FUA+FUA_NV "); task = iscsi_read16_sync(iscsi, lun, 0, block_size, block_size, 0, 0, 1, 1, 0); if (task == NULL) { printf("[FAILED]\n"); printf("Failed to send read16 command: %s\n", iscsi_get_error(iscsi)); ret = -1; goto finished; } if (task->status != SCSI_STATUS_GOOD) { printf("[FAILED]\n"); printf("Read16 command: failed with sense. %s\n", iscsi_get_error(iscsi)); ret = -1; scsi_free_scsi_task(task); goto finished; } printf("[OK]\n"); finished: iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi); return ret; }
ssize_t read(int fd, void *buf, size_t count) { if ((iscsi_fd_list[fd].is_iscsi == 1) && (iscsi_fd_list[fd].in_flight == 0)) { uint64_t offset; uint64_t num_blocks, lba; struct scsi_task *task; struct scsi_get_lba_status *lbas; if (iscsi_fd_list[fd].dup2fd >= 0) { return read(iscsi_fd_list[fd].dup2fd, buf, count); } offset = iscsi_fd_list[fd].offset / iscsi_fd_list[fd].block_size * iscsi_fd_list[fd].block_size; num_blocks = (iscsi_fd_list[fd].offset - offset + count + iscsi_fd_list[fd].block_size - 1) / iscsi_fd_list[fd].block_size; lba = offset / iscsi_fd_list[fd].block_size; /* Don't try to read beyond the last LBA */ if (lba >= iscsi_fd_list[fd].num_blocks) { return 0; } /* Trim num_blocks requested to last lba */ if ((lba + num_blocks) > iscsi_fd_list[fd].num_blocks) { num_blocks = iscsi_fd_list[fd].num_blocks - lba; count = num_blocks * iscsi_fd_list[fd].block_size; } iscsi_fd_list[fd].in_flight = 1; if (iscsi_fd_list[fd].get_lba_status != 0) { uint32_t i; uint32_t _num_allocated=0; uint32_t _num_blocks=0; if (iscsi_fd_list[fd].lbasd_cache_valid==1) { LD_ISCSI_DPRINTF(5,"cached get_lba_status_descriptor is lba %"PRIu64", num_blocks %d, provisioning %d",iscsi_fd_list[fd].lbasd_cached.lba,iscsi_fd_list[fd].lbasd_cached.num_blocks,iscsi_fd_list[fd].lbasd_cached.provisioning); if (iscsi_fd_list[fd].lbasd_cached.provisioning != 0x00 && lba >= iscsi_fd_list[fd].lbasd_cached.lba && lba+num_blocks < iscsi_fd_list[fd].lbasd_cached.lba+iscsi_fd_list[fd].lbasd_cached.num_blocks) { LD_ISCSI_DPRINTF(4,"skipped read16_sync for non-allocated blocks: lun %d, lba %"PRIu64", num_blocks: %"PRIu64", block_size: %d, offset: %"PRIu64" count: %lu",iscsi_fd_list[fd].lun,lba,num_blocks,iscsi_fd_list[fd].block_size,offset,(unsigned long)count); memset(buf, 0x00, count); iscsi_fd_list[fd].offset += count; iscsi_fd_list[fd].in_flight = 0; return count; } } LD_ISCSI_DPRINTF(4,"get_lba_status_sync: lun %d, lba %"PRIu64", num_blocks: %"PRIu64,iscsi_fd_list[fd].lun,lba,num_blocks); task = iscsi_get_lba_status_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, lba, 8+16); if (task == NULL || task->status != SCSI_STATUS_GOOD) { LD_ISCSI_DPRINTF(0,"failed to send get_lba_status command"); iscsi_fd_list[fd].in_flight = 0; errno = EIO; return -1; } lbas = scsi_datain_unmarshall(task); if (lbas == NULL) { LD_ISCSI_DPRINTF(0,"failed to unmarshall get_lba_status data"); scsi_free_scsi_task(task); iscsi_fd_list[fd].in_flight = 0; errno = EIO; return -1; } LD_ISCSI_DPRINTF(5,"get_lba_status: num_descriptors: %d",lbas->num_descriptors); for (i=0;i<lbas->num_descriptors;i++) { struct scsi_lba_status_descriptor *lbasd = &lbas->descriptors[i]; LD_ISCSI_DPRINTF(5,"get_lba_status_descriptor %d, lba %"PRIu64", num_blocks %d, provisioning %d",i,lbasd->lba,lbasd->num_blocks,lbasd->provisioning); if (lbasd->lba != _num_blocks+lba) { LD_ISCSI_DPRINTF(0,"get_lba_status response is non-continuous"); scsi_free_scsi_task(task); iscsi_fd_list[fd].in_flight = 0; errno = EIO; return -1; } _num_allocated+=(lbasd->provisioning==0x00)?lbasd->num_blocks:0; _num_blocks+=lbasd->num_blocks; iscsi_fd_list[fd].lbasd_cached=lbas->descriptors[i]; iscsi_fd_list[fd].lbasd_cache_valid=1; } scsi_free_scsi_task(task); if (_num_allocated == 0 && _num_blocks >= num_blocks) { LD_ISCSI_DPRINTF(4,"skipped read16_sync for non-allocated blocks: lun %d, lba %"PRIu64", num_blocks: %"PRIu64", block_size: %d, offset: %"PRIu64" count: %lu",iscsi_fd_list[fd].lun,lba,num_blocks,iscsi_fd_list[fd].block_size,offset,(unsigned long)count); memset(buf, 0x00, count); iscsi_fd_list[fd].offset += count; iscsi_fd_list[fd].in_flight = 0; return count; } } LD_ISCSI_DPRINTF(4,"read16_sync: lun %d, lba %"PRIu64", num_blocks: %"PRIu64", block_size: %d, offset: %"PRIu64" count: %lu",iscsi_fd_list[fd].lun,lba,num_blocks,iscsi_fd_list[fd].block_size,offset,(unsigned long)count); task = iscsi_read16_sync(iscsi_fd_list[fd].iscsi, iscsi_fd_list[fd].lun, lba, num_blocks * iscsi_fd_list[fd].block_size, iscsi_fd_list[fd].block_size, 0, 0, 0, 0, 0); iscsi_fd_list[fd].in_flight = 0; if (task == NULL || task->status != SCSI_STATUS_GOOD) { LD_ISCSI_DPRINTF(0,"failed to send read16 command"); errno = EIO; return -1; } memcpy(buf, &task->datain.data[iscsi_fd_list[fd].offset - offset], count); iscsi_fd_list[fd].offset += count; scsi_free_scsi_task(task); return count; } return real_read(fd, buf, count); }