version 1.1.1.1, 2012/02/21 16:42:02
|
version 1.1.1.2, 2012/10/09 09:13:23
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (C) 2008-2011 Daisuke Aoyama <aoyama@peach.ne.jp>. | * Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>. |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
Line 59
|
Line 59
|
#include "istgt_scsi.h" |
#include "istgt_scsi.h" |
#include "istgt_queue.h" |
#include "istgt_queue.h" |
|
|
|
#if !defined(__GNUC__) |
|
#undef __attribute__ |
|
#define __attribute__(x) |
|
#endif |
|
|
#ifndef O_FSYNC |
#ifndef O_FSYNC |
#define O_FSYNC O_SYNC |
#define O_FSYNC O_SYNC |
#endif |
#endif |
Line 83 typedef enum {
|
Line 88 typedef enum {
|
#define PR_ALLOW_WERR 0x0002 |
#define PR_ALLOW_WERR 0x0002 |
#define PR_ALLOW_EARR 0x0001 |
#define PR_ALLOW_EARR 0x0001 |
|
|
typedef struct istgt_lu_pr_key_t { |
|
uint64_t key; |
|
|
|
/* transport IDs */ |
|
char *registered_initiator_port; |
|
char *registered_target_port; |
|
/* PERSISTENT RESERVE OUT received from */ |
|
int pg_idx; /* relative target port */ |
|
int pg_tag; /* target port group */ |
|
|
|
int ninitiator_ports; |
|
char **initiator_ports; |
|
int all_tpg; |
|
} ISTGT_LU_PR_KEY; |
|
|
|
typedef struct istgt_lu_disk_t { |
|
ISTGT_LU_Ptr lu; |
|
int num; |
|
int lun; |
|
|
|
int fd; |
|
const char *file; |
|
uint64_t fsize; |
|
uint64_t foffset; |
|
uint64_t size; |
|
uint64_t blocklen; |
|
uint64_t blockcnt; |
|
|
|
#ifdef HAVE_UUID_H |
|
uuid_t uuid; |
|
#endif /* HAVE_UUID_H */ |
|
|
|
/* cache flags */ |
|
int read_cache; |
|
int write_cache; |
|
/* parts for cache */ |
|
int wbufsize; |
|
uint8_t *wbuf; |
|
uint64_t woffset; |
|
uint64_t wnbytes; |
|
int req_write_cache; |
|
int err_write_cache; |
|
|
|
/* thin provisioning */ |
|
int thin_provisioning; |
|
|
|
/* for ats */ |
|
pthread_mutex_t ats_mutex; |
|
|
|
int queue_depth; |
|
pthread_mutex_t cmd_queue_mutex; |
|
ISTGT_QUEUE cmd_queue; |
|
pthread_mutex_t wait_lu_task_mutex; |
|
ISTGT_LU_TASK_Ptr wait_lu_task; |
|
|
|
/* PERSISTENT RESERVE */ |
|
int npr_keys; |
|
ISTGT_LU_PR_KEY pr_keys[MAX_LU_RESERVE]; |
|
uint32_t pr_generation; |
|
|
|
char *rsv_port; |
|
uint64_t rsv_key; |
|
int rsv_scope; |
|
int rsv_type; |
|
|
|
/* SCSI sense code */ |
|
volatile int sense; |
|
} ISTGT_LU_DISK; |
|
|
|
#define BUILD_SENSE(SK,ASC,ASCQ) \ |
#define BUILD_SENSE(SK,ASC,ASCQ) \ |
do { \ |
do { \ |
*sense_len = \ |
*sense_len = \ |
Line 172 static int istgt_lu_disk_build_sense_data(ISTGT_LU_DIS
|
Line 108 static int istgt_lu_disk_build_sense_data(ISTGT_LU_DIS
|
static int istgt_lu_disk_queue_abort_ITL(ISTGT_LU_DISK *spec, const char *initiator_port); |
static int istgt_lu_disk_queue_abort_ITL(ISTGT_LU_DISK *spec, const char *initiator_port); |
|
|
static int |
static int |
istgt_lu_disk_open(ISTGT_LU_DISK *spec, int flags, int mode) | istgt_lu_disk_open_raw(ISTGT_LU_DISK *spec, int flags, int mode) |
{ |
{ |
int rc; |
int rc; |
|
|
Line 186 istgt_lu_disk_open(ISTGT_LU_DISK *spec, int flags, int
|
Line 122 istgt_lu_disk_open(ISTGT_LU_DISK *spec, int flags, int
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_close(ISTGT_LU_DISK *spec) | istgt_lu_disk_close_raw(ISTGT_LU_DISK *spec) |
{ |
{ |
int rc; |
int rc; |
|
|
Line 203 istgt_lu_disk_close(ISTGT_LU_DISK *spec)
|
Line 139 istgt_lu_disk_close(ISTGT_LU_DISK *spec)
|
|
|
#if 0 |
#if 0 |
static off_t |
static off_t |
istgt_lu_disk_lseek(ISTGT_LU_DISK *spec, off_t offset, int whence) | istgt_lu_disk_lseek_raw(ISTGT_LU_DISK *spec, off_t offset, int whence) |
{ |
{ |
off_t rc; |
off_t rc; |
|
|
Line 217 istgt_lu_disk_lseek(ISTGT_LU_DISK *spec, off_t offset,
|
Line 153 istgt_lu_disk_lseek(ISTGT_LU_DISK *spec, off_t offset,
|
#endif |
#endif |
|
|
static int64_t |
static int64_t |
istgt_lu_disk_seek(ISTGT_LU_DISK *spec, uint64_t offset) | istgt_lu_disk_seek_raw(ISTGT_LU_DISK *spec, uint64_t offset) |
{ |
{ |
off_t rc; |
off_t rc; |
|
|
Line 230 istgt_lu_disk_seek(ISTGT_LU_DISK *spec, uint64_t offse
|
Line 166 istgt_lu_disk_seek(ISTGT_LU_DISK *spec, uint64_t offse
|
} |
} |
|
|
static int64_t |
static int64_t |
istgt_lu_disk_read(ISTGT_LU_DISK *spec, void *buf, uint64_t nbytes) | istgt_lu_disk_read_raw(ISTGT_LU_DISK *spec, void *buf, uint64_t nbytes) |
{ |
{ |
int64_t rc; |
int64_t rc; |
|
|
Line 256 istgt_lu_disk_read(ISTGT_LU_DISK *spec, void *buf, uin
|
Line 192 istgt_lu_disk_read(ISTGT_LU_DISK *spec, void *buf, uin
|
if (rc < 0) { |
if (rc < 0) { |
return -1; |
return -1; |
} |
} |
if (rc != request) { | if ((uint64_t) rc != request) { |
/* read size < request */ |
/* read size < request */ |
if (spec->foffset + rc >= spec->size) { |
if (spec->foffset + rc >= spec->size) { |
rc = spec->size - spec->foffset; |
rc = spec->size - spec->foffset; |
Line 286 istgt_lu_disk_read(ISTGT_LU_DISK *spec, void *buf, uin
|
Line 222 istgt_lu_disk_read(ISTGT_LU_DISK *spec, void *buf, uin
|
} |
} |
|
|
static int64_t |
static int64_t |
istgt_lu_disk_write(ISTGT_LU_DISK *spec, const void *buf, uint64_t nbytes) | istgt_lu_disk_write_raw(ISTGT_LU_DISK *spec, const void *buf, uint64_t nbytes) |
{ |
{ |
int64_t rc; |
int64_t rc; |
|
|
Line 345 istgt_lu_disk_write(ISTGT_LU_DISK *spec, const void *b
|
Line 281 istgt_lu_disk_write(ISTGT_LU_DISK *spec, const void *b
|
} |
} |
|
|
static int64_t |
static int64_t |
istgt_lu_disk_sync(ISTGT_LU_DISK *spec, uint64_t offset, uint64_t nbytes) | istgt_lu_disk_sync_raw(ISTGT_LU_DISK *spec, uint64_t offset, uint64_t nbytes) |
{ |
{ |
int64_t rc; |
int64_t rc; |
|
|
Line 358 istgt_lu_disk_sync(ISTGT_LU_DISK *spec, uint64_t offse
|
Line 294 istgt_lu_disk_sync(ISTGT_LU_DISK *spec, uint64_t offse
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_allocate(ISTGT_LU_DISK *spec) | istgt_lu_disk_allocate_raw(ISTGT_LU_DISK *spec) |
{ |
{ |
uint8_t *data; |
uint8_t *data; |
uint64_t fsize; |
uint64_t fsize; |
Line 382 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
Line 318 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
spec->fsize = fsize; |
spec->fsize = fsize; |
|
|
offset = size - nbytes; |
offset = size - nbytes; |
rc = istgt_lu_disk_seek(spec, offset); | rc = istgt_lu_disk_seek_raw(spec, offset); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
xfree(data); |
xfree(data); |
return -1; |
return -1; |
} |
} |
rc = istgt_lu_disk_read(spec, data, nbytes); | rc = istgt_lu_disk_read_raw(spec, data, nbytes); |
/* EOF is OK */ |
/* EOF is OK */ |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
Line 403 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
Line 339 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
fsize = size; |
fsize = size; |
} |
} |
offset = fsize - nbytes; |
offset = fsize - nbytes; |
rc = istgt_lu_disk_seek(spec, offset); | rc = istgt_lu_disk_seek_raw(spec, offset); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
xfree(data); |
xfree(data); |
return -1; |
return -1; |
} |
} |
rc = istgt_lu_disk_write(spec, data, nbytes); | rc = istgt_lu_disk_write_raw(spec, data, nbytes); |
if (rc == -1 || rc != nbytes) { | if (rc == -1 || (uint64_t) rc != nbytes) { |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
xfree(data); |
xfree(data); |
return -1; |
return -1; |
Line 420 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
Line 356 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
} |
} |
} else { |
} else { |
/* allocate complete size */ |
/* allocate complete size */ |
rc = istgt_lu_disk_seek(spec, offset); | rc = istgt_lu_disk_seek_raw(spec, offset); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
xfree(data); |
xfree(data); |
return -1; |
return -1; |
} |
} |
rc = istgt_lu_disk_write(spec, data, nbytes); | rc = istgt_lu_disk_write_raw(spec, data, nbytes); |
if (rc == -1 || rc != nbytes) { | if (rc == -1 || (uint64_t) rc != nbytes) { |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
xfree(data); |
xfree(data); |
return -1; |
return -1; |
Line 440 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
Line 376 istgt_lu_disk_allocate(ISTGT_LU_DISK *spec)
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_setcache(ISTGT_LU_DISK *spec) | istgt_lu_disk_setcache_raw(ISTGT_LU_DISK *spec) |
{ |
{ |
int flags; |
int flags; |
int rc; |
int rc; |
Line 478 istgt_lu_disk_setcache(ISTGT_LU_DISK *spec)
|
Line 414 istgt_lu_disk_setcache(ISTGT_LU_DISK *spec)
|
return 0; |
return 0; |
} |
} |
|
|
|
static const char * |
|
istgt_get_disktype_by_ext(const char *file) |
|
{ |
|
size_t n; |
|
|
|
if (file == NULL || file[0] == '\n') |
|
return "RAW"; |
|
|
|
n = strlen(file); |
|
if (n > 4 && strcasecmp(file + (n - 4), ".vdi") == 0) |
|
return "VDI"; |
|
if (n > 4 && strcasecmp(file + (n - 4), ".vhd") == 0) |
|
return "VHD"; |
|
if (n > 5 && strcasecmp(file + (n - 5), ".vmdk") == 0) |
|
return "VMDK"; |
|
|
|
if (n > 5 && strcasecmp(file + (n - 5), ".qcow") == 0) |
|
return "QCOW"; |
|
if (n > 6 && strcasecmp(file + (n - 6), ".qcow2") == 0) |
|
return "QCOW"; |
|
if (n > 4 && strcasecmp(file + (n - 4), ".qed") == 0) |
|
return "QED"; |
|
if (n > 5 && strcasecmp(file + (n - 5), ".vhdx") == 0) |
|
return "VHDX"; |
|
|
|
return "RAW"; |
|
} |
|
|
int |
int |
istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu) | istgt_lu_disk_init(ISTGT_Ptr istgt __attribute__((__unused__)), ISTGT_LU_Ptr lu) |
{ |
{ |
ISTGT_LU_DISK *spec; |
ISTGT_LU_DISK *spec; |
uint64_t gb_size; |
uint64_t gb_size; |
Line 541 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
Line 505 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
spec->req_write_cache = 0; |
spec->req_write_cache = 0; |
spec->err_write_cache = 0; |
spec->err_write_cache = 0; |
spec->thin_provisioning = 0; |
spec->thin_provisioning = 0; |
|
spec->watssize = 0; |
|
spec->watsbuf = NULL; |
|
|
rc = pthread_mutex_init(&spec->ats_mutex, NULL); |
rc = pthread_mutex_init(&spec->ats_mutex, NULL); |
if (rc != 0) { |
if (rc != 0) { |
Line 549 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
Line 515 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
} |
} |
|
|
spec->queue_depth = lu->queue_depth; |
spec->queue_depth = lu->queue_depth; |
rc = pthread_mutex_init(&spec->cmd_queue_mutex, NULL); | rc = pthread_mutex_init(&spec->cmd_queue_mutex, &istgt->mutex_attr); |
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("LU%d: mutex_init() failed\n", lu->num); |
ISTGT_ERRLOG("LU%d: mutex_init() failed\n", lu->num); |
return -1; |
return -1; |
Line 588 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
Line 554 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
uuid_create(&spec->uuid, &status); |
uuid_create(&spec->uuid, &status); |
if (status != uuid_s_ok) { |
if (status != uuid_s_ok) { |
ISTGT_ERRLOG("LU%d: LUN%d: uuid_create() failed\n", lu->num, i); |
ISTGT_ERRLOG("LU%d: LUN%d: uuid_create() failed\n", lu->num, i); |
|
(void) pthread_mutex_destroy(&spec->wait_lu_task_mutex); |
(void) pthread_mutex_destroy(&spec->cmd_queue_mutex); |
(void) pthread_mutex_destroy(&spec->cmd_queue_mutex); |
|
(void) pthread_mutex_destroy(&spec->ats_mutex); |
istgt_queue_destroy(&spec->cmd_queue); |
istgt_queue_destroy(&spec->cmd_queue); |
xfree(spec); |
xfree(spec); |
return -1; |
return -1; |
Line 597 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
Line 565 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
|
|
spec->file = lu->lun[i].u.storage.file; |
spec->file = lu->lun[i].u.storage.file; |
spec->size = lu->lun[i].u.storage.size; |
spec->size = lu->lun[i].u.storage.size; |
spec->blocklen = lu->blocklen; | spec->disktype = istgt_get_disktype_by_ext(spec->file); |
if (spec->blocklen != 512 | if (strcasecmp(spec->disktype, "VDI") == 0 |
&& spec->blocklen != 1024 | || strcasecmp(spec->disktype, "VHD") == 0 |
&& spec->blocklen != 2048 | || strcasecmp(spec->disktype, "VMDK") == 0 |
&& spec->blocklen != 4096 | || strcasecmp(spec->disktype, "QCOW") == 0 |
&& spec->blocklen != 8192 | || strcasecmp(spec->disktype, "QED") == 0 |
&& spec->blocklen != 16384 | || strcasecmp(spec->disktype, "VHDX") == 0) { |
&& spec->blocklen != 32768 | rc = istgt_lu_disk_vbox_lun_init(spec, istgt, lu); |
&& spec->blocklen != 65536 | if (rc < 0) { |
&& spec->blocklen != 131072 | ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_vbox_lun_init() failed\n", |
&& spec->blocklen != 262144 | lu->num, i); |
&& spec->blocklen != 524288) { | goto error_return; |
ISTGT_ERRLOG("LU%d: LUN%d: invalid blocklen %"PRIu64"\n", | } |
lu->num, i, spec->blocklen); | } else if (strcasecmp(spec->disktype, "RAW") == 0) { |
error_return: | spec->open = istgt_lu_disk_open_raw; |
(void) pthread_mutex_destroy(&spec->cmd_queue_mutex); | spec->close = istgt_lu_disk_close_raw; |
istgt_queue_destroy(&spec->cmd_queue); | spec->seek = istgt_lu_disk_seek_raw; |
xfree(spec); | spec->read = istgt_lu_disk_read_raw; |
return -1; | spec->write = istgt_lu_disk_write_raw; |
} | spec->sync = istgt_lu_disk_sync_raw; |
spec->blockcnt = spec->size / spec->blocklen; | spec->allocate = istgt_lu_disk_allocate_raw; |
if (spec->blockcnt == 0) { | spec->setcache = istgt_lu_disk_setcache_raw; |
ISTGT_ERRLOG("LU%d: LUN%d: size zero\n", lu->num, i); | |
goto error_return; | |
} | |
|
|
|
spec->blocklen = lu->blocklen; |
|
if (spec->blocklen != 512 |
|
&& spec->blocklen != 1024 |
|
&& spec->blocklen != 2048 |
|
&& spec->blocklen != 4096 |
|
&& spec->blocklen != 8192 |
|
&& spec->blocklen != 16384 |
|
&& spec->blocklen != 32768 |
|
&& spec->blocklen != 65536 |
|
&& spec->blocklen != 131072 |
|
&& spec->blocklen != 262144 |
|
&& spec->blocklen != 524288) { |
|
ISTGT_ERRLOG("LU%d: LUN%d: invalid blocklen %"PRIu64"\n", |
|
lu->num, i, spec->blocklen); |
|
error_return: |
|
(void) pthread_mutex_destroy(&spec->wait_lu_task_mutex); |
|
(void) pthread_mutex_destroy(&spec->cmd_queue_mutex); |
|
(void) pthread_mutex_destroy(&spec->ats_mutex); |
|
istgt_queue_destroy(&spec->cmd_queue); |
|
xfree(spec); |
|
return -1; |
|
} |
|
spec->blockcnt = spec->size / spec->blocklen; |
|
if (spec->blockcnt == 0) { |
|
ISTGT_ERRLOG("LU%d: LUN%d: size zero\n", lu->num, i); |
|
goto error_return; |
|
} |
|
|
#if 0 |
#if 0 |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"LU%d: LUN%d file=%s, size=%"PRIu64"\n", | "LU%d: LUN%d file=%s, size=%"PRIu64"\n", |
lu->num, i, spec->file, spec->size); | lu->num, i, spec->file, spec->size); |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"LU%d: LUN%d %"PRIu64" blocks, %" | "LU%d: LUN%d %"PRIu64" blocks, %" |
PRIu64" bytes/block\n", | PRIu64" bytes/block\n", |
lu->num, i, spec->blockcnt, spec->blocklen); | lu->num, i, spec->blockcnt, spec->blocklen); |
#endif |
#endif |
printf("LU%d: LUN%d file=%s, size=%"PRIu64"\n", | printf("LU%d: LUN%d file=%s, size=%"PRIu64"\n", |
lu->num, i, spec->file, spec->size); | lu->num, i, spec->file, spec->size); |
printf("LU%d: LUN%d %"PRIu64" blocks, %"PRIu64" bytes/block\n", | printf("LU%d: LUN%d %"PRIu64" blocks, %"PRIu64" bytes/block\n", |
lu->num, i, spec->blockcnt, spec->blocklen); | lu->num, i, spec->blockcnt, spec->blocklen); |
| |
flags = lu->readonly ? O_RDONLY : O_RDWR; | flags = lu->readonly ? O_RDONLY : O_RDWR; |
newfile = 0; | newfile = 0; |
rc = istgt_lu_disk_open(spec, flags, 0666); | rc = spec->open(spec, flags, 0666); |
if (rc < 0) { | |
newfile = 1; | |
flags = lu->readonly ? O_RDONLY : (O_CREAT | O_EXCL | O_RDWR); | |
rc = istgt_lu_disk_open(spec, flags, 0666); | |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("LU%d: LUN%d: open error\n", lu->num, i); | newfile = 1; |
goto error_return; | flags = lu->readonly ? O_RDONLY : (O_CREAT | O_EXCL | O_RDWR); |
| rc = spec->open(spec, flags, 0666); |
| if (rc < 0) { |
| ISTGT_ERRLOG("LU%d: LUN%d: open error(errno=%d)\n", |
| lu->num, i, errno); |
| goto error_return; |
| } |
} |
} |
} | if (!lu->readonly) { |
if (!lu->readonly) { | rc = spec->allocate(spec); |
rc = istgt_lu_disk_allocate(spec); | if (rc < 0) { |
| ISTGT_ERRLOG("LU%d: LUN%d: allocate error\n", |
| lu->num, i); |
| goto error_return; |
| } |
| } |
| rc = spec->setcache(spec); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("LU%d: LUN%d: allocate error\n", lu->num, i); | ISTGT_ERRLOG("LU%d: LUN%d: setcache error\n", lu->num, i); |
goto error_return; |
goto error_return; |
} |
} |
} | } else { |
rc = istgt_lu_disk_setcache(spec); | ISTGT_ERRLOG("LU%d: LUN%d: unsupported format\n", lu->num, i); |
if (rc < 0) { | |
ISTGT_ERRLOG("LU%d: LUN%d: setcache error\n", lu->num, i); | |
goto error_return; |
goto error_return; |
} |
} |
|
|
Line 728 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
Line 727 istgt_lu_disk_init(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu)
|
} |
} |
|
|
int |
int |
istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr lu) | istgt_lu_disk_shutdown(ISTGT_Ptr istgt __attribute__((__unused__)), ISTGT_LU_Ptr lu) |
{ |
{ |
ISTGT_LU_DISK *spec; |
ISTGT_LU_DISK *spec; |
ISTGT_LU_PR_KEY *prkey; |
ISTGT_LU_PR_KEY *prkey; |
Line 751 istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr l
|
Line 750 istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr l
|
} |
} |
spec = (ISTGT_LU_DISK *) lu->lun[i].spec; |
spec = (ISTGT_LU_DISK *) lu->lun[i].spec; |
|
|
if (!spec->lu->readonly) { | if (strcasecmp(spec->disktype, "VDI") == 0 |
rc = istgt_lu_disk_sync(spec, 0, spec->size); | || strcasecmp(spec->disktype, "VHD") == 0 |
| || strcasecmp(spec->disktype, "VMDK") == 0 |
| || strcasecmp(spec->disktype, "QCOW") == 0 |
| || strcasecmp(spec->disktype, "QED") == 0 |
| || strcasecmp(spec->disktype, "VHDX") == 0) { |
| rc = istgt_lu_disk_vbox_lun_shutdown(spec, istgt, lu); |
if (rc < 0) { |
if (rc < 0) { |
//ISTGT_ERRLOG("LU%d: lu_disk_sync() failed\n", lu->num); | ISTGT_ERRLOG("LU%d: lu_disk_vbox_lun_shutdown() failed\n", |
| lu->num); |
/* ignore error */ |
/* ignore error */ |
} |
} |
|
} else if (strcasecmp(spec->disktype, "RAW") == 0) { |
|
if (!spec->lu->readonly) { |
|
rc = spec->sync(spec, 0, spec->size); |
|
if (rc < 0) { |
|
//ISTGT_ERRLOG("LU%d: lu_disk_sync() failed\n", lu->num); |
|
/* ignore error */ |
|
} |
|
} |
|
rc = spec->close(spec); |
|
if (rc < 0) { |
|
//ISTGT_ERRLOG("LU%d: lu_disk_close() failed\n", lu->num); |
|
/* ignore error */ |
|
} |
|
} else { |
|
ISTGT_ERRLOG("LU%d: LUN%d: unsupported format\n", lu->num, i); |
|
return -1; |
} |
} |
rc = istgt_lu_disk_close(spec); |
|
if (rc < 0) { |
|
//ISTGT_ERRLOG("LU%d: lu_disk_close() failed\n", lu->num); |
|
/* ignore error */ |
|
} |
|
|
|
for (j = 0; j < spec->npr_keys; j++) { |
for (j = 0; j < spec->npr_keys; j++) { |
prkey = &spec->pr_keys[j]; |
prkey = &spec->pr_keys[j]; |
Line 790 istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr l
|
Line 806 istgt_lu_disk_shutdown(ISTGT_Ptr istgt, ISTGT_LU_Ptr l
|
//ISTGT_ERRLOG("LU%d: mutex_destroy() failed\n", lu->num); |
//ISTGT_ERRLOG("LU%d: mutex_destroy() failed\n", lu->num); |
/* ignore error */ |
/* ignore error */ |
} |
} |
|
xfree(spec->watsbuf); |
xfree(spec->wbuf); |
xfree(spec->wbuf); |
xfree(spec); |
xfree(spec); |
lu->lun[i].spec = NULL; |
lu->lun[i].spec = NULL; |
Line 1000 istgt_lu_set_extid(uint8_t *buf, uint64_t vid, uint64_
|
Line 1017 istgt_lu_set_extid(uint8_t *buf, uint64_t vid, uint64_
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_scsi_report_luns(ISTGT_LU_Ptr lu, CONN_Ptr conn, uint8_t *cdb, int sel, uint8_t *data, int alloc_len) | istgt_lu_disk_scsi_report_luns(ISTGT_LU_Ptr lu, CONN_Ptr conn __attribute__((__unused__)), uint8_t *cdb __attribute__((__unused__)), int sel, uint8_t *data, int alloc_len) |
{ |
{ |
uint64_t fmt_lun, lun, method; |
uint64_t fmt_lun, lun, method; |
int hlen = 0, len = 0; |
int hlen = 0, len = 0; |
Line 1043 istgt_lu_disk_scsi_report_luns(ISTGT_LU_Ptr lu, CONN_P
|
Line 1060 istgt_lu_disk_scsi_report_luns(ISTGT_LU_Ptr lu, CONN_P
|
method = 0x00U; |
method = 0x00U; |
fmt_lun = (method & 0x03U) << 62; |
fmt_lun = (method & 0x03U) << 62; |
fmt_lun |= (lun & 0x00ffU) << 48; |
fmt_lun |= (lun & 0x00ffU) << 48; |
} else if (lu->maxlun <= 0x4000U) { | } else if (lu->maxlun <= 0x4000) { |
/* below 16384 */ |
/* below 16384 */ |
method = 0x01U; |
method = 0x01U; |
fmt_lun = (method & 0x03U) << 62; |
fmt_lun = (method & 0x03U) << 62; |
Line 1249 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
Line 1266 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
|
|
/* IDENTIFIER */ |
/* IDENTIFIER */ |
plen = snprintf((char *) &cp[4], MAX_TARGET_NAME, |
plen = snprintf((char *) &cp[4], MAX_TARGET_NAME, |
"%s", | "%s", spec->lu->name); |
spec->lu->name); | |
cp[3] = plen; |
cp[3] = plen; |
len += 4 + plen; |
len += 4 + plen; |
|
|
Line 1272 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
Line 1288 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
|
|
/* IDENTIFIER */ |
/* IDENTIFIER */ |
plen = snprintf((char *) &cp[4], MAX_TARGET_NAME, |
plen = snprintf((char *) &cp[4], MAX_TARGET_NAME, |
"%s"",t,0x""%4.4x", | "%s"",t,0x""%4.4x", spec->lu->name, conn->portal.tag); |
spec->lu->name, | |
conn->portal.tag); | |
cp[3] = plen; |
cp[3] = plen; |
len += 4 + plen; |
len += 4 + plen; |
|
|
Line 1525 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
Line 1539 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
|
|
/* IDENTIFIER */ |
/* IDENTIFIER */ |
plen = snprintf((char *) &cp2[4], MAX_TARGET_NAME, |
plen = snprintf((char *) &cp2[4], MAX_TARGET_NAME, |
"%s"",t,0x""%4.4x", | "%s"",t,0x""%4.4x", spec->lu->name, pg_tag); |
spec->lu->name, | |
pg_tag); | |
cp2[3] = plen; |
cp2[3] = plen; |
plen2 += 4 + plen; |
plen2 += 4 + plen; |
|
|
Line 1558 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
Line 1570 istgt_lu_disk_scsi_inquiry(ISTGT_LU_DISK *spec, CONN_P
|
/* WSNZ(0) */ |
/* WSNZ(0) */ |
BDSET8(&data[4], 0, 0); /* support zero length in WRITE SAME */ |
BDSET8(&data[4], 0, 0); /* support zero length in WRITE SAME */ |
/* MAXIMUM COMPARE AND WRITE LENGTH */ |
/* MAXIMUM COMPARE AND WRITE LENGTH */ |
blocks = ISTGT_LU_WORK_BLOCK_SIZE / (uint32_t) spec->blocklen; | blocks = ISTGT_LU_WORK_ATS_BLOCK_SIZE / (uint32_t) spec->blocklen; |
if (blocks > 0xff) { |
if (blocks > 0xff) { |
blocks = 0xff; |
blocks = 0xff; |
} |
} |
Line 1791 istgt_lu_disk_scsi_mode_sense_page(ISTGT_LU_DISK *spec
|
Line 1803 istgt_lu_disk_scsi_mode_sense_page(ISTGT_LU_DISK *spec
|
/* Changeable values */ |
/* Changeable values */ |
if (page != 0x08) { |
if (page != 0x08) { |
/* not supported */ |
/* not supported */ |
return 0; | return -1; |
} |
} |
} else if (pc == 0x02) { |
} else if (pc == 0x02) { |
/* Default values */ |
/* Default values */ |
Line 2088 istgt_lu_disk_scsi_mode_sense6(ISTGT_LU_DISK *spec, CO
|
Line 2100 istgt_lu_disk_scsi_mode_sense6(ISTGT_LU_DISK *spec, CO
|
data[3] = len; /* Block Descripter Length */ |
data[3] = len; /* Block Descripter Length */ |
|
|
plen = istgt_lu_disk_scsi_mode_sense_page(spec, conn, cdb, pc, page, subpage, &cp[0], alloc_len); |
plen = istgt_lu_disk_scsi_mode_sense_page(spec, conn, cdb, pc, page, subpage, &cp[0], alloc_len); |
|
if (plen < 0) { |
|
return -1; |
|
} |
cp += plen; |
cp += plen; |
|
|
total = hlen + len + plen; |
total = hlen + len + plen; |
Line 2146 istgt_lu_disk_scsi_mode_sense10(ISTGT_LU_DISK *spec, C
|
Line 2161 istgt_lu_disk_scsi_mode_sense10(ISTGT_LU_DISK *spec, C
|
DSET16(&data[6], len); /* Block Descripter Length */ |
DSET16(&data[6], len); /* Block Descripter Length */ |
|
|
plen = istgt_lu_disk_scsi_mode_sense_page(spec, conn, cdb, pc, page, subpage, &cp[0], alloc_len); |
plen = istgt_lu_disk_scsi_mode_sense_page(spec, conn, cdb, pc, page, subpage, &cp[0], alloc_len); |
|
if (plen < 0) { |
|
return -1; |
|
} |
cp += plen; |
cp += plen; |
|
|
total = hlen + len + plen; |
total = hlen + len + plen; |
Line 2161 istgt_lu_disk_transfer_data(CONN_Ptr conn, ISTGT_LU_CM
|
Line 2179 istgt_lu_disk_transfer_data(CONN_Ptr conn, ISTGT_LU_CM
|
|
|
if (lu_cmd->lu->queue_depth == 0) { |
if (lu_cmd->lu->queue_depth == 0) { |
if (len > bufsize) { |
if (len > bufsize) { |
ISTGT_ERRLOG("bufsize(%d) too small\n", bufsize); | ISTGT_ERRLOG("bufsize(%zd) too small\n", bufsize); |
return -1; |
return -1; |
} |
} |
rc = istgt_iscsi_transfer_out(conn, lu_cmd, buf, bufsize, len); |
rc = istgt_iscsi_transfer_out(conn, lu_cmd, buf, bufsize, len); |
Line 2176 istgt_lu_disk_transfer_data(CONN_Ptr conn, ISTGT_LU_CM
|
Line 2194 istgt_lu_disk_transfer_data(CONN_Ptr conn, ISTGT_LU_CM
|
static int |
static int |
istgt_lu_disk_scsi_mode_select_page(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb, int pf, int sp, uint8_t *data, size_t len) |
istgt_lu_disk_scsi_mode_select_page(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb, int pf, int sp, uint8_t *data, size_t len) |
{ |
{ |
|
size_t hlen, plen; |
int ps, spf, page, subpage; |
int ps, spf, page, subpage; |
int hlen, plen; |
|
int rc; |
int rc; |
|
|
if (pf == 0) { |
if (pf == 0) { |
Line 2271 istgt_lu_disk_scsi_mode_select_page(ISTGT_LU_DISK *spe
|
Line 2289 istgt_lu_disk_scsi_mode_select_page(ISTGT_LU_DISK *spe
|
return 0; |
return 0; |
} |
} |
|
|
|
static int |
|
istgt_lu_disk_scsi_read_defect10(ISTGT_LU_DISK *spec __attribute__((__unused__)), CONN_Ptr conn __attribute__((__unused__)), uint8_t *cdb __attribute__((__unused__)), int req_plist, int req_glist, int list_format, uint8_t *data, int alloc_len) |
|
{ |
|
uint8_t *cp; |
|
int hlen = 0, len = 0; |
|
int total; |
|
|
|
if (alloc_len < 4) { |
|
return -1; |
|
} |
|
|
|
data[0] = 0; /* Reserved */ |
|
data[1] = 0; |
|
if (req_plist) { |
|
BDADD8(&data[1], 1, 4); /* PLISTV */ |
|
} |
|
if (req_glist) { |
|
BDADD8(&data[1], 1, 3); /* GLISTV */ |
|
} |
|
BDADD8W(&data[1], list_format, 2, 3); /* DEFECT LIST FORMAT */ |
|
DSET16(&data[2], 0); /* DEFECT LIST LENGTH */ |
|
hlen = 4; |
|
|
|
cp = &data[4]; |
|
/* defect list (if any) */ |
|
len = 0; |
|
|
|
total = hlen + len; |
|
DSET16(&data[2], total - hlen); /* DEFECT LIST LENGTH */ |
|
return total; |
|
} |
|
|
|
static int |
|
istgt_lu_disk_scsi_read_defect12(ISTGT_LU_DISK *spec __attribute__((__unused__)), CONN_Ptr conn __attribute__((__unused__)), uint8_t *cdb __attribute__((__unused__)), int req_plist, int req_glist, int list_format, uint8_t *data, int alloc_len) |
|
{ |
|
uint8_t *cp; |
|
int hlen = 0, len = 0; |
|
int total; |
|
|
|
if (alloc_len < 8) { |
|
return -1; |
|
} |
|
|
|
data[0] = 0; /* Reserved */ |
|
data[1] = 0; |
|
if (req_plist) { |
|
BDADD8(&data[1], 1, 4); /* PLISTV */ |
|
} |
|
if (req_glist) { |
|
BDADD8(&data[1], 1, 3); /* GLISTV */ |
|
} |
|
BDADD8W(&data[1], list_format, 2, 3); /* DEFECT LIST FORMAT */ |
|
data[2] = 0; /* Reserved */ |
|
data[3] = 0; /* Reserved */ |
|
DSET32(&data[4], 0); /* DEFECT LIST LENGTH */ |
|
hlen = 8; |
|
|
|
cp = &data[8]; |
|
/* defect list (if any) */ |
|
len = 0; |
|
|
|
total = hlen + len; |
|
DSET32(&data[4], total - hlen); /* DEFECT LIST LENGTH */ |
|
return total; |
|
} |
|
|
#if 0 |
#if 0 |
static int |
static int |
istgt_lu_disk_scsi_request_sense(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb, int desc, uint8_t *data, int alloc_len) |
istgt_lu_disk_scsi_request_sense(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb, int desc, uint8_t *data, int alloc_len) |
Line 2349 istgt_lu_disk_scsi_request_sense(ISTGT_LU_DISK *spec,
|
Line 2433 istgt_lu_disk_scsi_request_sense(ISTGT_LU_DISK *spec,
|
#endif |
#endif |
|
|
static int |
static int |
istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb, uint8_t *data, int alloc_len) | istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_DISK *spec, CONN_Ptr conn, uint8_t *cdb __attribute__((__unused__)), uint8_t *data, int alloc_len) |
{ |
{ |
ISTGT_Ptr istgt; |
ISTGT_Ptr istgt; |
ISTGT_LU_Ptr lu; |
ISTGT_LU_Ptr lu; |
Line 2359 istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_
|
Line 2443 istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_
|
int total; |
int total; |
int pg_tag; |
int pg_tag; |
int nports; |
int nports; |
int i, j; | int i, j, k; |
| int ridx; |
|
|
if (alloc_len < 0xfff) { |
if (alloc_len < 0xfff) { |
return -1; |
return -1; |
Line 2436 istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_
|
Line 2521 istgt_lu_disk_scsi_report_target_port_groups(ISTGT_LU_
|
len += plen; |
len += plen; |
|
|
nports = 0; |
nports = 0; |
for (j = 0; j < istgt->nportal; j ++) { | ridx = 0; |
if (istgt->portal[j].tag != pg_tag) | MTX_LOCK(&istgt->mutex); |
continue; | for (j = 0; j < istgt->nportal_group; j++) { |
/* Target port descriptor(s) */ | if (istgt->portal_group[j].tag == pg_tag) { |
cp = &data[hlen + len]; | for (k = 0; k < istgt->portal_group[j].nportals; k++) { |
/* Obsolete */ | /* Target port descriptor(s) */ |
DSET16(&cp[0], 0); | cp = &data[hlen + len]; |
/* RELATIVE TARGET PORT IDENTIFIER */ | /* Obsolete */ |
DSET16(&cp[2], (uint16_t) (1 + istgt->portal[j].idx)); | DSET16(&cp[0], 0); |
plen = 4; | /* RELATIVE TARGET PORT IDENTIFIER */ |
len += plen; | DSET16(&cp[2], (uint16_t) (1 + ridx)); |
nports++; | plen = 4; |
| len += plen; |
| nports++; |
| ridx++; |
| } |
| } else { |
| ridx += istgt->portal_group[j].nportals; |
| } |
} |
} |
|
MTX_UNLOCK(&istgt->mutex); |
|
|
if (nports > 0xff) { |
if (nports > 0xff) { |
ISTGT_ERRLOG("too many portals in portal group\n"); |
ISTGT_ERRLOG("too many portals in portal group\n"); |
Line 2611 istgt_lu_disk_find_pr_key(ISTGT_LU_DISK *spec, const c
|
Line 2704 istgt_lu_disk_find_pr_key(ISTGT_LU_DISK *spec, const c
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_remove_other_pr_key(ISTGT_LU_DISK *spec, CONN_Ptr conn, const char *initiator_port, const char *target_port, uint64_t key) | istgt_lu_disk_remove_other_pr_key(ISTGT_LU_DISK *spec, CONN_Ptr conn __attribute__((__unused__)), const char *initiator_port, const char *target_port, uint64_t key) |
{ |
{ |
ISTGT_LU_PR_KEY *prkey, *prkey1, *prkey2; |
ISTGT_LU_PR_KEY *prkey, *prkey1, *prkey2; |
int i, j; |
int i, j; |
Line 2664 istgt_lu_disk_remove_other_pr_key(ISTGT_LU_DISK *spec,
|
Line 2757 istgt_lu_disk_remove_other_pr_key(ISTGT_LU_DISK *spec,
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_remove_pr_key(ISTGT_LU_DISK *spec, CONN_Ptr conn, const char *initiator_port, const char *target_port, uint64_t key) | istgt_lu_disk_remove_pr_key(ISTGT_LU_DISK *spec, CONN_Ptr conn __attribute__((__unused__)), const char *initiator_port, const char *target_port, uint64_t key) |
{ |
{ |
ISTGT_LU_PR_KEY *prkey, *prkey1, *prkey2; |
ISTGT_LU_PR_KEY *prkey, *prkey1, *prkey2; |
int i, j; |
int i, j; |
Line 2763 istgt_lu_parse_transport_id(char **tid, uint8_t *data,
|
Line 2856 istgt_lu_parse_transport_id(char **tid, uint8_t *data,
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_scsi_persistent_reserve_in(ISTGT_LU_DISK *spec, CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, int sa, uint8_t *data, int alloc_len) | istgt_lu_disk_scsi_persistent_reserve_in(ISTGT_LU_DISK *spec, CONN_Ptr conn __attribute__((__unused__)), ISTGT_LU_CMD_Ptr lu_cmd, int sa, uint8_t *data, int alloc_len __attribute__((__unused__))) |
{ |
{ |
ISTGT_LU_PR_KEY *prkey; |
ISTGT_LU_PR_KEY *prkey; |
|
size_t hlen = 0, len = 0, plen; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
uint8_t *cp; |
uint8_t *cp; |
int hlen = 0, len = 0, plen; |
|
int total; |
int total; |
int i; |
int i; |
|
|
Line 2925 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
Line 3018 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
{ |
{ |
ISTGT_LU_PR_KEY *prkey; |
ISTGT_LU_PR_KEY *prkey; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
char *old_rsv_port = NULL; |
char *old_rsv_port = NULL; |
char **initiator_ports; |
char **initiator_ports; |
int maxports, nports; |
int maxports, nports; |
Line 2998 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
Line 3091 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
} |
} |
/* remove existing keys */ |
/* remove existing keys */ |
rc = istgt_lu_disk_remove_pr_key(spec, conn, |
rc = istgt_lu_disk_remove_pr_key(spec, conn, |
conn->initiator_port, conn->target_port, rkey); | conn->initiator_port, conn->target_port, 0); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_remove_pr_key() failed\n"); |
ISTGT_ERRLOG("lu_disk_remove_pr_key() failed\n"); |
/* INTERNAL TARGET FAILURE */ |
/* INTERNAL TARGET FAILURE */ |
Line 3461 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
Line 3554 istgt_lu_disk_scsi_persistent_reserve_out(ISTGT_LU_DIS
|
return -1; |
return -1; |
} |
} |
} |
} |
|
/* unregister? */ |
|
if (sarkey == 0) { |
|
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
|
return 0; |
|
} |
} else { |
} else { |
/* registered port */ |
/* registered port */ |
if (spec_i_pt) { |
if (spec_i_pt) { |
Line 3735 istgt_lu_disk_scsi_release(ISTGT_LU_DISK *spec, CONN_P
|
Line 3833 istgt_lu_disk_scsi_release(ISTGT_LU_DISK *spec, CONN_P
|
{ |
{ |
ISTGT_LU_CMD lu_cmd2; |
ISTGT_LU_CMD lu_cmd2; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
uint64_t LUI; |
uint64_t LUI; |
uint64_t rkey; |
uint64_t rkey; |
uint8_t cdb[10]; |
uint8_t cdb[10]; |
Line 3822 istgt_lu_disk_scsi_reserve(ISTGT_LU_DISK *spec, CONN_P
|
Line 3920 istgt_lu_disk_scsi_reserve(ISTGT_LU_DISK *spec, CONN_P
|
{ |
{ |
ISTGT_LU_CMD lu_cmd2; |
ISTGT_LU_CMD lu_cmd2; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
uint64_t LUI; |
uint64_t LUI; |
uint64_t rkey; |
uint64_t rkey; |
uint8_t cdb[10]; |
uint8_t cdb[10]; |
Line 3905 istgt_lu_disk_scsi_reserve(ISTGT_LU_DISK *spec, CONN_P
|
Line 4003 istgt_lu_disk_scsi_reserve(ISTGT_LU_DISK *spec, CONN_P
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_lbread(ISTGT_LU_DISK *spec, CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint64_t lba, uint32_t len) | istgt_lu_disk_lbread(ISTGT_LU_DISK *spec, CONN_Ptr conn __attribute__((__unused__)), ISTGT_LU_CMD_Ptr lu_cmd, uint64_t lba, uint32_t len) |
{ |
{ |
uint8_t *data; |
uint8_t *data; |
uint64_t maxlba; |
uint64_t maxlba; |
Line 3937 istgt_lu_disk_lbread(ISTGT_LU_DISK *spec, CONN_Ptr con
|
Line 4035 istgt_lu_disk_lbread(ISTGT_LU_DISK *spec, CONN_Ptr con
|
} |
} |
|
|
if (nbytes > lu_cmd->iobufsize) { |
if (nbytes > lu_cmd->iobufsize) { |
ISTGT_ERRLOG("nbytes(%u) > iobufsize(%u)\n", | ISTGT_ERRLOG("nbytes(%zu) > iobufsize(%zu)\n", |
nbytes, lu_cmd->iobufsize); | (size_t) nbytes, lu_cmd->iobufsize); |
return -1; |
return -1; |
} |
} |
data = lu_cmd->iobuf; |
data = lu_cmd->iobuf; |
|
|
rc = istgt_lu_disk_seek(spec, offset); | rc = spec->seek(spec, offset); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
return -1; |
return -1; |
} |
} |
|
|
rc = istgt_lu_disk_read(spec, data, nbytes); | rc = spec->read(spec, data, nbytes); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
return -1; |
return -1; |
Line 3995 istgt_lu_disk_lbwrite(ISTGT_LU_DISK *spec, CONN_Ptr co
|
Line 4093 istgt_lu_disk_lbwrite(ISTGT_LU_DISK *spec, CONN_Ptr co
|
} |
} |
|
|
if (nbytes > lu_cmd->iobufsize) { |
if (nbytes > lu_cmd->iobufsize) { |
ISTGT_ERRLOG("nbytes(%u) > iobufsize(%u)\n", | ISTGT_ERRLOG("nbytes(%zu) > iobufsize(%zu)\n", |
nbytes, lu_cmd->iobufsize); | (size_t) nbytes, lu_cmd->iobufsize); |
return -1; |
return -1; |
} |
} |
data = lu_cmd->iobuf; |
data = lu_cmd->iobuf; |
Line 4014 istgt_lu_disk_lbwrite(ISTGT_LU_DISK *spec, CONN_Ptr co
|
Line 4112 istgt_lu_disk_lbwrite(ISTGT_LU_DISK *spec, CONN_Ptr co
|
} |
} |
|
|
spec->req_write_cache = 0; |
spec->req_write_cache = 0; |
rc = istgt_lu_disk_seek(spec, offset); | rc = spec->seek(spec, offset); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
return -1; |
return -1; |
} |
} |
|
|
rc = istgt_lu_disk_write(spec, data, nbytes); | rc = spec->write(spec, data, nbytes); |
if (rc < 0 || rc != nbytes) { | if (rc < 0 || (uint64_t) rc != nbytes) { |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
return -1; |
return -1; |
} |
} |
Line 4069 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
Line 4167 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
} |
} |
|
|
if (nbytes > lu_cmd->iobufsize) { |
if (nbytes > lu_cmd->iobufsize) { |
ISTGT_ERRLOG("nbytes(%u) > iobufsize(%u)\n", | ISTGT_ERRLOG("nbytes(%zu) > iobufsize(%zu)\n", |
nbytes, lu_cmd->iobufsize); | (size_t) nbytes, lu_cmd->iobufsize); |
return -1; |
return -1; |
} |
} |
data = lu_cmd->iobuf; |
data = lu_cmd->iobuf; |
Line 4098 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
Line 4196 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
} |
} |
|
|
spec->req_write_cache = 0; |
spec->req_write_cache = 0; |
rc = istgt_lu_disk_seek(spec, offset); | rc = spec->seek(spec, offset); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
return -1; |
return -1; |
Line 4107 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
Line 4205 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
#if 0 |
#if 0 |
nblocks = 0; |
nblocks = 0; |
while (nblocks < llen) { |
while (nblocks < llen) { |
rc = istgt_lu_disk_write(spec, data, nbytes); | rc = spec->write(spec, data, nbytes); |
if (rc < 0 || rc != nbytes) { |
if (rc < 0 || rc != nbytes) { |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
return -1; |
return -1; |
Line 4124 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
Line 4222 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
nblocks = 0; |
nblocks = 0; |
while (nblocks < llen) { |
while (nblocks < llen) { |
uint64_t reqblocks = DMIN64(wblocks, (llen - nblocks)); |
uint64_t reqblocks = DMIN64(wblocks, (llen - nblocks)); |
rc = istgt_lu_disk_write(spec, conn->workbuf, (reqblocks * nbytes)); | rc = spec->write(spec, conn->workbuf, (reqblocks * nbytes)); |
if (rc < 0 || rc != (reqblocks * nbytes)) { | if (rc < 0 || (uint64_t) rc != (reqblocks * nbytes)) { |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
return -1; |
return -1; |
} |
} |
Line 4143 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
Line 4241 istgt_lu_disk_lbwrite_same(ISTGT_LU_DISK *spec, CONN_P
|
static int |
static int |
istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint64_t lba, uint32_t len) |
istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint64_t lba, uint32_t len) |
{ |
{ |
uint8_t *tmp; |
|
uint8_t *data; |
uint8_t *data; |
uint64_t maxlba; |
uint64_t maxlba; |
uint64_t llen; |
uint64_t llen; |
Line 4152 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
Line 4249 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
uint64_t nbytes; |
uint64_t nbytes; |
int64_t rc; |
int64_t rc; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
|
|
if (len == 0) { |
if (len == 0) { |
lu_cmd->data_len = 0; |
lu_cmd->data_len = 0; |
Line 4179 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
Line 4276 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
} |
} |
|
|
if (nbytes > lu_cmd->iobufsize) { |
if (nbytes > lu_cmd->iobufsize) { |
ISTGT_ERRLOG("nbytes(%u) > iobufsize(%u)\n", | ISTGT_ERRLOG("nbytes(%zu) > iobufsize(%zu)\n", |
nbytes, lu_cmd->iobufsize); | (size_t) nbytes, lu_cmd->iobufsize); |
return -1; |
return -1; |
} |
} |
data = lu_cmd->iobuf; |
data = lu_cmd->iobuf; |
Line 4197 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
Line 4294 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
return -1; |
return -1; |
} |
} |
|
|
tmp = xmalloc(nbytes); | if (spec->watsbuf == NULL) { |
| spec->watssize = ISTGT_LU_WORK_ATS_BLOCK_SIZE; |
| spec->watsbuf = xmalloc(spec->watssize); |
| } |
| if (nbytes > (uint64_t) spec->watssize) { |
| ISTGT_ERRLOG("nbytes(%zu) > watssize(%zu)\n", |
| (size_t) nbytes, (size_t) spec->watssize); |
| return -1; |
| } |
| |
spec->req_write_cache = 0; |
spec->req_write_cache = 0; |
/* start atomic test and set */ |
/* start atomic test and set */ |
MTX_LOCK(&spec->ats_mutex); |
MTX_LOCK(&spec->ats_mutex); |
|
|
rc = istgt_lu_disk_seek(spec, offset); | rc = spec->seek(spec, offset); |
if (rc < 0) { |
if (rc < 0) { |
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
xfree(tmp); |
|
return -1; |
return -1; |
} |
} |
|
|
rc = istgt_lu_disk_read(spec, tmp, nbytes); | rc = spec->read(spec, spec->watsbuf, nbytes); |
if (rc < 0 || rc != nbytes) { | if (rc < 0 || (uint64_t) rc != nbytes) { |
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
ISTGT_ERRLOG("lu_disk_read() failed\n"); |
xfree(tmp); |
|
return -1; |
return -1; |
} |
} |
|
|
#if 0 |
#if 0 |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS VERIFY", data, nbytes); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS VERIFY", data, nbytes); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS WRITE", data + nbytes, nbytes); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS WRITE", data + nbytes, nbytes); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS DATA", tmp, nbytes); | ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "ATS DATA", spec->watsbuf, nbytes); |
#endif |
#endif |
if (memcmp(tmp, data, nbytes) != 0) { | if (memcmp(spec->watsbuf, data, nbytes) != 0) { |
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
//ISTGT_ERRLOG("compare failed\n"); |
//ISTGT_ERRLOG("compare failed\n"); |
xfree(tmp); |
|
/* MISCOMPARE DURING VERIFY OPERATION */ |
/* MISCOMPARE DURING VERIFY OPERATION */ |
BUILD_SENSE(MISCOMPARE, 0x1d, 0x00); |
BUILD_SENSE(MISCOMPARE, 0x1d, 0x00); |
return -1; |
return -1; |
} |
} |
|
|
rc = istgt_lu_disk_seek(spec, offset); | rc = spec->seek(spec, offset); |
if (rc < 0) { |
if (rc < 0) { |
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
ISTGT_ERRLOG("lu_disk_seek() failed\n"); |
xfree(tmp); |
|
return -1; |
return -1; |
} |
} |
rc = istgt_lu_disk_write(spec, data + nbytes, nbytes); | rc = spec->write(spec, data + nbytes, nbytes); |
if (rc < 0 || rc != nbytes) { | if (rc < 0 || (uint64_t) rc != nbytes) { |
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
ISTGT_ERRLOG("lu_disk_write() failed\n"); |
xfree(tmp); |
|
return -1; |
return -1; |
} |
} |
ISTGT_TRACELOG(ISTGT_TRACE_SCSI, "Wrote %"PRId64"/%"PRIu64" bytes\n", |
ISTGT_TRACELOG(ISTGT_TRACE_SCSI, "Wrote %"PRId64"/%"PRIu64" bytes\n", |
Line 4251 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
Line 4352 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
|
|
MTX_UNLOCK(&spec->ats_mutex); |
MTX_UNLOCK(&spec->ats_mutex); |
/* end atomic test and set */ |
/* end atomic test and set */ |
xfree(tmp); |
|
|
|
lu_cmd->data_len = nbytes * 2; |
lu_cmd->data_len = nbytes * 2; |
|
|
Line 4259 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
Line 4359 istgt_lu_disk_lbwrite_ats(ISTGT_LU_DISK *spec, CONN_Pt
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_lbsync(ISTGT_LU_DISK *spec, CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint64_t lba, uint32_t len) | istgt_lu_disk_lbsync(ISTGT_LU_DISK *spec, CONN_Ptr conn __attribute__((__unused__)), ISTGT_LU_CMD_Ptr lu_cmd __attribute__((__unused__)), uint64_t lba, uint32_t len) |
{ |
{ |
uint64_t maxlba; |
uint64_t maxlba; |
uint64_t llen; |
uint64_t llen; |
Line 4287 istgt_lu_disk_lbsync(ISTGT_LU_DISK *spec, CONN_Ptr con
|
Line 4387 istgt_lu_disk_lbsync(ISTGT_LU_DISK *spec, CONN_Ptr con
|
return -1; |
return -1; |
} |
} |
|
|
rc = istgt_lu_disk_sync(spec, offset, nbytes); | rc = spec->sync(spec, offset, nbytes); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("lu_disk_sync() failed\n"); |
ISTGT_ERRLOG("lu_disk_sync() failed\n"); |
return -1; |
return -1; |
Line 4354 istgt_lu_scsi_build_sense_data(uint8_t *data, int sk,
|
Line 4454 istgt_lu_scsi_build_sense_data(uint8_t *data, int sk,
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_build_sense_data(ISTGT_LU_DISK *spec, uint8_t *data, int sk, int asc, int ascq) | istgt_lu_disk_build_sense_data(ISTGT_LU_DISK *spec __attribute__((__unused__)), uint8_t *data, int sk, int asc, int ascq) |
{ |
{ |
int rc; |
int rc; |
|
|
Line 4423 istgt_lu_scsi_build_sense_data2(uint8_t *data, int sk,
|
Line 4523 istgt_lu_scsi_build_sense_data2(uint8_t *data, int sk,
|
} |
} |
|
|
static int |
static int |
istgt_lu_disk_build_sense_data2(ISTGT_LU_DISK *spec, uint8_t *data, int sk, int asc, int ascq) | istgt_lu_disk_build_sense_data2(ISTGT_LU_DISK *spec __attribute__((__unused__)), uint8_t *data, int sk, int asc, int ascq) |
{ |
{ |
int rc; |
int rc; |
|
|
Line 4472 istgt_lu_disk_reset(ISTGT_LU_Ptr lu, int lun)
|
Line 4572 istgt_lu_disk_reset(ISTGT_LU_Ptr lu, int lun)
|
|
|
/* re-open file */ |
/* re-open file */ |
if (!spec->lu->readonly) { |
if (!spec->lu->readonly) { |
rc = istgt_lu_disk_sync(spec, 0, spec->size); | rc = spec->sync(spec, 0, spec->size); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_sync() failed\n", |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_sync() failed\n", |
lu->num, lun); |
lu->num, lun); |
/* ignore error */ |
/* ignore error */ |
} |
} |
} |
} |
rc = istgt_lu_disk_close(spec); | rc = spec->close(spec); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_close() failed\n", |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_close() failed\n", |
lu->num, lun); |
lu->num, lun); |
/* ignore error */ |
/* ignore error */ |
} |
} |
flags = lu->readonly ? O_RDONLY : O_RDWR; |
flags = lu->readonly ? O_RDONLY : O_RDWR; |
rc = istgt_lu_disk_open(spec, flags, 0666); | rc = spec->open(spec, flags, 0666); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_open() failed\n", |
ISTGT_ERRLOG("LU%d: LUN%d: lu_disk_open() failed\n", |
lu->num, lun); |
lu->num, lun); |
Line 4526 istgt_lu_disk_queue_clear_internal(ISTGT_LU_DISK *spec
|
Line 4626 istgt_lu_disk_queue_clear_internal(ISTGT_LU_DISK *spec
|
if (((all_cmds != 0) || (lu_task->lu_cmd.CmdSN == CmdSN)) |
if (((all_cmds != 0) || (lu_task->lu_cmd.CmdSN == CmdSN)) |
&& (strcasecmp(lu_task->initiator_port, |
&& (strcasecmp(lu_task->initiator_port, |
initiator_port) == 0)) { |
initiator_port) == 0)) { |
ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%u cleared\n", | ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%lu cleared\n", |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.cdb[0], |
lu_task->lu_cmd.cdb[0], |
(now - lu_task->create_time)); | (unsigned long) (now - lu_task->create_time)); |
rc = istgt_lu_destroy_task(lu_task); |
rc = istgt_lu_destroy_task(lu_task); |
if (rc < 0) { |
if (rc < 0) { |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
Line 4568 istgt_lu_disk_queue_clear_internal(ISTGT_LU_DISK *spec
|
Line 4668 istgt_lu_disk_queue_clear_internal(ISTGT_LU_DISK *spec
|
/* conn had gone? */ |
/* conn had gone? */ |
rc = pthread_mutex_trylock(&lu_task->trans_mutex); |
rc = pthread_mutex_trylock(&lu_task->trans_mutex); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%u aborted\n", | ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%lu aborted\n", |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.cdb[0], |
lu_task->lu_cmd.cdb[0], |
(now - lu_task->create_time)); | (unsigned long) (now - lu_task->create_time)); |
/* force error */ |
/* force error */ |
lu_task->error = 1; |
lu_task->error = 1; |
lu_task->abort = 1; |
lu_task->abort = 1; |
Line 4723 istgt_lu_disk_queue_clear_all(ISTGT_LU_Ptr lu, int lun
|
Line 4823 istgt_lu_disk_queue_clear_all(ISTGT_LU_Ptr lu, int lun
|
lu_task = istgt_queue_dequeue(&spec->cmd_queue); |
lu_task = istgt_queue_dequeue(&spec->cmd_queue); |
if (lu_task == NULL) |
if (lu_task == NULL) |
break; |
break; |
ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%u cleared\n", | ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%lu cleared\n", |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.cdb[0], |
lu_task->lu_cmd.cdb[0], |
(now - lu_task->create_time)); | (unsigned long) (now - lu_task->create_time)); |
rc = istgt_lu_destroy_task(lu_task); |
rc = istgt_lu_destroy_task(lu_task); |
if (rc < 0) { |
if (rc < 0) { |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
Line 4743 istgt_lu_disk_queue_clear_all(ISTGT_LU_Ptr lu, int lun
|
Line 4843 istgt_lu_disk_queue_clear_all(ISTGT_LU_Ptr lu, int lun
|
/* conn had gone? */ |
/* conn had gone? */ |
rc = pthread_mutex_trylock(&lu_task->trans_mutex); |
rc = pthread_mutex_trylock(&lu_task->trans_mutex); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%u aborted\n", | ISTGT_LOG("CmdSN(%u), OP=0x%x, ElapsedTime=%lu aborted\n", |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.CmdSN, |
lu_task->lu_cmd.cdb[0], |
lu_task->lu_cmd.cdb[0], |
(now - lu_task->create_time)); | (unsigned long) (now - lu_task->create_time)); |
/* force error */ |
/* force error */ |
lu_task->error = 1; |
lu_task->error = 1; |
lu_task->abort = 1; |
lu_task->abort = 1; |
Line 4782 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 4882 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
int data_len; |
int data_len; |
int data_alloc_len; |
int data_alloc_len; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
int lun_i; |
int lun_i; |
int maxq; |
int maxq; |
int qcnt; |
int qcnt; |
Line 4811 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 4911 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
#endif /* ISTGT_TRACE_DISK */ |
#endif /* ISTGT_TRACE_DISK */ |
if (cdb[0] == SPC_INQUIRY) { |
if (cdb[0] == SPC_INQUIRY) { |
allocation_len = DGET16(&cdb[3]); |
allocation_len = DGET16(&cdb[3]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 4825 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 4925 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
memset(&data[1], 0, data_len - 1); |
memset(&data[1], 0, data_len - 1); |
/* ADDITIONAL LENGTH */ |
/* ADDITIONAL LENGTH */ |
data[4] = data_len - 5; |
data[4] = data_len - 5; |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
return ISTGT_LU_TASK_RESULT_IMMEDIATE; |
return ISTGT_LU_TASK_RESULT_IMMEDIATE; |
} else { |
} else { |
Line 4856 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 4956 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
return -1; |
return -1; |
} |
} |
|
|
MTX_LOCK(&lu->queue_mutex); |
|
/* enqueue SCSI command */ |
/* enqueue SCSI command */ |
MTX_LOCK(&spec->cmd_queue_mutex); |
MTX_LOCK(&spec->cmd_queue_mutex); |
rc = istgt_queue_count(&spec->cmd_queue); |
rc = istgt_queue_count(&spec->cmd_queue); |
maxq = spec->queue_depth * lu->istgt->MaxSessions; |
maxq = spec->queue_depth * lu->istgt->MaxSessions; |
if (rc > maxq) { |
if (rc > maxq) { |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
MTX_UNLOCK(&lu->queue_mutex); |
|
lu_cmd->data_len = 0; |
lu_cmd->data_len = 0; |
lu_cmd->status = ISTGT_SCSI_STATUS_TASK_SET_FULL; |
lu_cmd->status = ISTGT_SCSI_STATUS_TASK_SET_FULL; |
rc = istgt_lu_destroy_task(lu_task); |
rc = istgt_lu_destroy_task(lu_task); |
Line 4907 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 5005 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
} |
} |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
MTX_UNLOCK(&spec->cmd_queue_mutex); |
if (rc < 0) { |
if (rc < 0) { |
MTX_UNLOCK(&lu->queue_mutex); |
|
ISTGT_ERRLOG("queue_enqueue() failed\n"); |
ISTGT_ERRLOG("queue_enqueue() failed\n"); |
error_return: |
error_return: |
rc = istgt_lu_destroy_task(lu_task); |
rc = istgt_lu_destroy_task(lu_task); |
Line 4919 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
Line 5016 istgt_lu_disk_queue(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu
|
} |
} |
|
|
/* notify LUN thread */ |
/* notify LUN thread */ |
|
MTX_LOCK(&lu->queue_mutex); |
|
lu->queue_check = 1; |
rc = pthread_cond_broadcast(&lu->queue_cond); |
rc = pthread_cond_broadcast(&lu->queue_cond); |
MTX_UNLOCK(&lu->queue_mutex); |
MTX_UNLOCK(&lu->queue_mutex); |
if (rc != 0) { |
if (rc != 0) { |
Line 5143 istgt_lu_disk_queue_start(ISTGT_LU_Ptr lu, int lun)
|
Line 5242 istgt_lu_disk_queue_start(ISTGT_LU_Ptr lu, int lun)
|
abstime.tv_sec = 0; |
abstime.tv_sec = 0; |
abstime.tv_nsec = 0; |
abstime.tv_nsec = 0; |
|
|
MTX_LOCK(&lu_task->trans_mutex); |
|
MTX_LOCK(&conn->task_queue_mutex); |
MTX_LOCK(&conn->task_queue_mutex); |
rc = istgt_queue_enqueue(&conn->task_queue, lu_task); |
rc = istgt_queue_enqueue(&conn->task_queue, lu_task); |
MTX_UNLOCK(&conn->task_queue_mutex); |
MTX_UNLOCK(&conn->task_queue_mutex); |
Line 5165 istgt_lu_disk_queue_start(ISTGT_LU_Ptr lu, int lun)
|
Line 5263 istgt_lu_disk_queue_start(ISTGT_LU_Ptr lu, int lun)
|
#if 0 |
#if 0 |
ISTGT_LOG("wait CmdSN=%u\n", lu_task->lu_cmd.CmdSN); |
ISTGT_LOG("wait CmdSN=%u\n", lu_task->lu_cmd.CmdSN); |
#endif |
#endif |
|
MTX_LOCK(&lu_task->trans_mutex); |
MTX_LOCK(&spec->wait_lu_task_mutex); |
MTX_LOCK(&spec->wait_lu_task_mutex); |
spec->wait_lu_task = lu_task; |
spec->wait_lu_task = lu_task; |
MTX_UNLOCK(&spec->wait_lu_task_mutex); |
MTX_UNLOCK(&spec->wait_lu_task_mutex); |
|
rc = 0; |
while (lu_task->req_transfer_out == 1) { |
while (lu_task->req_transfer_out == 1) { |
rc = pthread_cond_timedwait(&lu_task->trans_cond, |
rc = pthread_cond_timedwait(&lu_task->trans_cond, |
&lu_task->trans_mutex, |
&lu_task->trans_mutex, |
Line 5359 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5459 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
uint32_t transfer_len; |
uint32_t transfer_len; |
uint32_t parameter_len; |
uint32_t parameter_len; |
uint8_t *sense_data; |
uint8_t *sense_data; |
int *sense_len; | size_t *sense_len; |
int lun_i; |
int lun_i; |
int rc; |
int rc; |
|
|
Line 5386 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5486 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
#endif /* ISTGT_TRACE_DISK */ |
#endif /* ISTGT_TRACE_DISK */ |
if (cdb[0] == SPC_INQUIRY) { |
if (cdb[0] == SPC_INQUIRY) { |
allocation_len = DGET16(&cdb[3]); |
allocation_len = DGET16(&cdb[3]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5400 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5500 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
memset(&data[1], 0, data_len - 1); |
memset(&data[1], 0, data_len - 1); |
/* ADDITIONAL LENGTH */ |
/* ADDITIONAL LENGTH */ |
data[4] = data_len - 5; |
data[4] = data_len - 5; |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
return 0; |
return 0; |
} else { |
} else { |
Line 5478 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5578 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
return -1; |
return -1; |
} |
} |
allocation_len = DGET16(&cdb[3]); |
allocation_len = DGET16(&cdb[3]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5492 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5592 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
break; |
break; |
} |
} |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "INQUIRY", data, data_len); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "INQUIRY", data, data_len); |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
|
|
Line 5510 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5610 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "sel=%x\n", sel); |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "sel=%x\n", sel); |
|
|
allocation_len = DGET32(&cdb[6]); |
allocation_len = DGET32(&cdb[6]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); | data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
return -1; |
return -1; |
} |
} |
Line 5530 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5630 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
break; |
break; |
} |
} |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "REPORT LUNS", data, data_len); |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, "REPORT LUNS", data, data_len); |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
} |
} |
break; |
break; |
Line 5597 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5697 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
return -1; |
return -1; |
} |
} |
allocation_len = DGET32(&cdb[10]); |
allocation_len = DGET32(&cdb[10]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5609 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5709 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
data[12] = 0; /* RTO_EN(1) PROT_EN(0) */ |
data[12] = 0; /* RTO_EN(1) PROT_EN(0) */ |
memset(&data[13], 0, 32 - (8 + 4 + 1)); /* Reserved */ |
memset(&data[13], 0, 32 - (8 + 4 + 1)); /* Reserved */ |
data_len = 32; |
data_len = 32; |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
case SBC_SAI_READ_LONG_16: |
case SBC_SAI_READ_LONG_16: |
Line 5783 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5883 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
subpage = cdb[3]; |
subpage = cdb[3]; |
|
|
allocation_len = cdb[4]; |
allocation_len = cdb[4]; |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5793 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5893 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
|
|
data_len = istgt_lu_disk_scsi_mode_sense6(spec, conn, cdb, dbd, pc, page, subpage, data, data_alloc_len); |
data_len = istgt_lu_disk_scsi_mode_sense6(spec, conn, cdb, dbd, pc, page, subpage, data, data_alloc_len); |
if (data_len < 0) { |
if (data_len < 0) { |
|
/* INVALID FIELD IN CDB */ |
|
BUILD_SENSE(ILLEGAL_REQUEST, 0x24, 0x00); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
break; |
break; |
} |
} |
#if 0 |
#if 0 |
istgt_dump("MODE SENSE(6)", data, data_len); |
istgt_dump("MODE SENSE(6)", data, data_len); |
#endif |
#endif |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
} |
} |
Line 5833 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5935 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
subpage = cdb[3]; |
subpage = cdb[3]; |
|
|
allocation_len = DGET16(&cdb[7]); |
allocation_len = DGET16(&cdb[7]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5843 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5945 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
|
|
data_len = istgt_lu_disk_scsi_mode_sense10(spec, conn, cdb, llbaa, dbd, pc, page, subpage, data, data_alloc_len); |
data_len = istgt_lu_disk_scsi_mode_sense10(spec, conn, cdb, llbaa, dbd, pc, page, subpage, data, data_alloc_len); |
if (data_len < 0) { |
if (data_len < 0) { |
|
/* INVALID FIELD IN CDB */ |
|
BUILD_SENSE(ILLEGAL_REQUEST, 0x24, 0x00); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
break; |
break; |
} |
} |
#if 0 |
#if 0 |
istgt_dump("MODE SENSE(10)", data, data_len); |
istgt_dump("MODE SENSE(10)", data, data_len); |
#endif |
#endif |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
} |
} |
|
|
#if 0 |
|
case SPC_LOG_SELECT: |
case SPC_LOG_SELECT: |
case SPC_LOG_SENSE: |
case SPC_LOG_SENSE: |
/* INVALID COMMAND OPERATION CODE */ |
/* INVALID COMMAND OPERATION CODE */ |
BUILD_SENSE(ILLEGAL_REQUEST, 0x20, 0x00); |
BUILD_SENSE(ILLEGAL_REQUEST, 0x20, 0x00); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
break; |
break; |
#endif |
|
|
|
case SPC_REQUEST_SENSE: |
case SPC_REQUEST_SENSE: |
{ |
{ |
Line 5883 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 5985 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
} |
} |
|
|
allocation_len = cdb[4]; |
allocation_len = cdb[4]; |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 5913 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6015 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
#if 0 |
#if 0 |
istgt_dump("REQUEST SENSE", data, data_len); |
istgt_dump("REQUEST SENSE", data, data_len); |
#endif |
#endif |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
} |
} |
Line 6416 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6518 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
transfer_len = (uint32_t) DGET8(&cdb[13]); |
transfer_len = (uint32_t) DGET8(&cdb[13]); |
group_no = BGET8W(&cdb[14], 4, 5); |
group_no = BGET8W(&cdb[14], 4, 5); |
|
|
maxlen = ISTGT_LU_WORK_BLOCK_SIZE / spec->blocklen; | maxlen = ISTGT_LU_WORK_ATS_BLOCK_SIZE / spec->blocklen; |
if (maxlen > 0xff) { |
if (maxlen > 0xff) { |
maxlen = 0xff; |
maxlen = 0xff; |
} |
} |
Line 6509 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6611 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
break; |
break; |
} |
} |
|
|
|
case SBC_READ_DEFECT_DATA_10: |
|
{ |
|
int req_plist, req_glist, list_format; |
|
|
|
if (lu_cmd->R_bit == 0) { |
|
ISTGT_ERRLOG("R_bit == 0\n"); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
return -1; |
|
} |
|
|
|
req_plist = BGET8(&cdb[2], 4); |
|
req_glist = BGET8(&cdb[2], 3); |
|
list_format = BGET8W(&cdb[2], 2, 3); |
|
|
|
allocation_len = (uint32_t) DGET16(&cdb[7]); |
|
if (allocation_len > (size_t) data_alloc_len) { |
|
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
|
data_alloc_len); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
return -1; |
|
} |
|
memset(data, 0, allocation_len); |
|
|
|
data_len = istgt_lu_disk_scsi_read_defect10(spec, conn, cdb, |
|
req_plist, req_glist, list_format, data, data_alloc_len); |
|
if (data_len < 0) { |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
break; |
|
} |
|
lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
|
break; |
|
} |
|
|
|
case SBC_READ_DEFECT_DATA_12: |
|
{ |
|
int req_plist, req_glist, list_format; |
|
|
|
if (lu_cmd->R_bit == 0) { |
|
ISTGT_ERRLOG("R_bit == 0\n"); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
return -1; |
|
} |
|
|
|
req_plist = BGET8(&cdb[2], 4); |
|
req_glist = BGET8(&cdb[2], 3); |
|
list_format = BGET8W(&cdb[2], 2, 3); |
|
|
|
allocation_len = DGET32(&cdb[6]); |
|
if (allocation_len > (size_t) data_alloc_len) { |
|
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
|
data_alloc_len); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
return -1; |
|
} |
|
memset(data, 0, allocation_len); |
|
|
|
data_len = istgt_lu_disk_scsi_read_defect12(spec, conn, cdb, |
|
req_plist, req_glist, list_format, data, data_alloc_len); |
|
if (data_len < 0) { |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
break; |
|
} |
|
lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
|
break; |
|
} |
|
|
case SCC_MAINTENANCE_IN: |
case SCC_MAINTENANCE_IN: |
ISTGT_TRACELOG(ISTGT_TRACE_SCSI, "MAINTENANCE_IN\n"); |
ISTGT_TRACELOG(ISTGT_TRACE_SCSI, "MAINTENANCE_IN\n"); |
switch (BGET8W(&cdb[1], 4, 5)) { /* SERVICE ACTION */ |
switch (BGET8W(&cdb[1], 4, 5)) { /* SERVICE ACTION */ |
Line 6520 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6690 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
return -1; |
return -1; |
} |
} |
allocation_len = DGET32(&cdb[6]); |
allocation_len = DGET32(&cdb[6]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 6534 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6704 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
} |
} |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, |
"REPORT_TARGET_PORT_GROUPS", data, data_len); |
"REPORT_TARGET_PORT_GROUPS", data, data_len); |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
break; |
break; |
default: |
default: |
Line 6623 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6793 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
|
|
sa = BGET8W(&cdb[1], 4, 5); |
sa = BGET8W(&cdb[1], 4, 5); |
allocation_len = DGET16(&cdb[7]); |
allocation_len = DGET16(&cdb[7]); |
if (allocation_len > data_alloc_len) { | if (allocation_len > (size_t) data_alloc_len) { |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
ISTGT_ERRLOG("data_alloc_len(%d) too small\n", |
data_alloc_len); |
data_alloc_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
Line 6638 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6808 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
} |
} |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, |
ISTGT_TRACEDUMP(ISTGT_TRACE_DEBUG, |
"PERSISTENT_RESERVE_IN", data, data_len); |
"PERSISTENT_RESERVE_IN", data, data_len); |
lu_cmd->data_len = DMIN32(data_len, lu_cmd->transfer_len); | lu_cmd->data_len = DMIN32((size_t)data_len, lu_cmd->transfer_len); |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
lu_cmd->status = ISTGT_SCSI_STATUS_GOOD; |
} |
} |
break; |
break; |
Line 6690 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
Line 6860 istgt_lu_disk_execute(CONN_Ptr conn, ISTGT_LU_CMD_Ptr
|
break; |
break; |
|
|
/* XXX TODO: fix */ |
/* XXX TODO: fix */ |
|
case 0x85: /* ATA PASS-THROUGH(16) */ |
|
case 0xA1: /* ATA PASS-THROUGH(12) */ |
|
/* INVALID COMMAND OPERATION CODE */ |
|
BUILD_SENSE(ILLEGAL_REQUEST, 0x20, 0x00); |
|
lu_cmd->status = ISTGT_SCSI_STATUS_CHECK_CONDITION; |
|
break; |
case SPC_EXTENDED_COPY: |
case SPC_EXTENDED_COPY: |
/* INVALID COMMAND OPERATION CODE */ |
/* INVALID COMMAND OPERATION CODE */ |
BUILD_SENSE(ILLEGAL_REQUEST, 0x20, 0x00); |
BUILD_SENSE(ILLEGAL_REQUEST, 0x20, 0x00); |