version 1.1.1.1, 2012/02/21 16:42:02
|
version 1.1.1.3, 2013/07/21 23:49:22
|
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 68
|
Line 68
|
#include <sys/time.h> |
#include <sys/time.h> |
#endif |
#endif |
|
|
|
#if !defined(__GNUC__) |
|
#undef __attribute__ |
|
#define __attribute__(x) |
|
#endif |
|
|
/* according to RFC1982 */ |
/* according to RFC1982 */ |
#define SN32_CMPMAX (((uint32_t)1U) << (32 - 1)) |
#define SN32_CMPMAX (((uint32_t)1U) << (32 - 1)) |
#define SN32_LT(S1,S2) \ |
#define SN32_LT(S1,S2) \ |
Line 83
|
Line 88
|
|| ((uint32_t)(S1) > (uint32_t)(S2) \ |
|| ((uint32_t)(S1) > (uint32_t)(S2) \ |
&& ((uint32_t)(S1) - (uint32_t)(S2) < SN32_CMPMAX)))) |
&& ((uint32_t)(S1) - (uint32_t)(S2) < SN32_CMPMAX)))) |
|
|
#define POLLWAIT 3000 | #define POLLWAIT 5000 |
#define MAX_MCSREVWAIT (10 * 1000) |
#define MAX_MCSREVWAIT (10 * 1000) |
#define ISCMDQ 8 |
#define ISCMDQ 8 |
|
|
Line 112 static void istgt_remove_conn(CONN_Ptr conn);
|
Line 117 static void istgt_remove_conn(CONN_Ptr conn);
|
static int istgt_iscsi_drop_all_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_all_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_old_conns(CONN_Ptr conn); |
static int istgt_iscsi_drop_old_conns(CONN_Ptr conn); |
|
|
|
/* Switch to use readv/writev (assume blocking) */ |
|
#define ISTGT_USE_IOVEC |
|
|
|
#if defined (ISTGT_USE_IOVEC) |
|
#include <sys/uio.h> |
|
#endif |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
#if 0 |
#if 0 |
#define ISTGT_USE_RECVBLOCK |
#define ISTGT_USE_RECVBLOCK |
#define ISTGT_USE_SENDBLOCK |
#define ISTGT_USE_SENDBLOCK |
Line 157 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
Line 170 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
} while (total < nbytes); |
} while (total < nbytes); |
if (total != (nbytes + pad_bytes)) { |
if (total != (nbytes + pad_bytes)) { |
/* incomplete bytes */ |
/* incomplete bytes */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d/%d+%d bytes\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd/%zd+%zd bytes\n", |
total, nbytes, pad_bytes); |
total, nbytes, pad_bytes); |
if (total > nbytes) { |
if (total > nbytes) { |
total = nbytes; |
total = nbytes; |
Line 167 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
Line 180 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
|
|
if (pad_bytes != 0) { |
if (pad_bytes != 0) { |
/* complete padding */ |
/* complete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (padding %d)\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (padding %zd)\n", |
nbytes, pad_bytes); |
nbytes, pad_bytes); |
} else { |
} else { |
/* just aligned */ |
/* just aligned */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (no padding)\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (no padding)\n", |
nbytes); |
nbytes); |
} |
} |
#else /* !ISTGT_USE_RECVBLOCK */ |
#else /* !ISTGT_USE_RECVBLOCK */ |
Line 197 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
Line 210 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
|
|
if (total != nbytes) { |
if (total != nbytes) { |
/* incomplete bytes */ |
/* incomplete bytes */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d/%d bytes\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd/%zd bytes\n", |
total, nbytes); |
total, nbytes); |
return total; |
return total; |
} |
} |
Line 213 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
Line 226 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
if (r < 0) { |
if (r < 0) { |
/* error */ |
/* error */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Read %d bytes (padding error) (errno=%d)\n", | "Read %zd bytes (padding error) (errno=%d)\n", |
nbytes, errno); |
nbytes, errno); |
return nbytes; |
return nbytes; |
} |
} |
if (r == 0) { |
if (r == 0) { |
/* EOF */ |
/* EOF */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Read %d bytes (padding EOF)\n", | "Read %zd bytes (padding EOF)\n", |
nbytes); |
nbytes); |
return nbytes; |
return nbytes; |
} |
} |
Line 230 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
Line 243 istgt_iscsi_read(CONN_Ptr conn, void *buf, size_t nbyt
|
if (total != pad_bytes) { |
if (total != pad_bytes) { |
/* incomplete padding */ |
/* incomplete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Read %d bytes (padding %d)\n", | "Read %zd bytes (padding %zd)\n", |
nbytes, total); |
nbytes, total); |
return nbytes; |
return nbytes; |
} |
} |
/* complete padding */ |
/* complete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (padding %d)\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (padding %zd)\n", |
nbytes, pad_bytes); |
nbytes, pad_bytes); |
return nbytes; |
return nbytes; |
} |
} |
|
|
/* just aligned */ |
/* just aligned */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %d bytes (no padding)\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Read %zd bytes (no padding)\n", |
nbytes); |
nbytes); |
#endif /* ISTGT_USE_RECVBLOCK */ |
#endif /* ISTGT_USE_RECVBLOCK */ |
return nbytes; |
return nbytes; |
Line 273 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 286 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
|
|
if (total != nbytes) { |
if (total != nbytes) { |
/* incomplete bytes */ |
/* incomplete bytes */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d/%d bytes\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd/%zd bytes\n", |
total, nbytes); |
total, nbytes); |
return total; |
return total; |
} |
} |
Line 287 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 300 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
if (r < 0) { |
if (r < 0) { |
/* error */ |
/* error */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding error) (errno=%d)\n", | "Write %zd bytes (padding error) (errno=%d)\n", |
nbytes, errno); |
nbytes, errno); |
return nbytes; |
return nbytes; |
} |
} |
Line 297 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 310 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
if (total != pad_bytes) { |
if (total != pad_bytes) { |
/* incomplete padding */ |
/* incomplete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding %d)\n", | "Write %zd bytes (padding %zd)\n", |
nbytes, total); |
nbytes, total); |
return nbytes; |
return nbytes; |
} |
} |
|
|
/* complete padding */ |
/* complete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding %d)\n", | "Write %zd bytes (padding %zd)\n", |
nbytes, pad_bytes); |
nbytes, pad_bytes); |
} else { |
} else { |
/* just aligned */ |
/* just aligned */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (no padding)\n", | "Write %zd bytes (no padding)\n", |
nbytes); |
nbytes); |
} |
} |
#else /* !ISTGT_USE_SENDBLOCK */ |
#else /* !ISTGT_USE_SENDBLOCK */ |
Line 327 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 340 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
|
|
if (total != nbytes) { |
if (total != nbytes) { |
/* incomplete bytes */ |
/* incomplete bytes */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d/%d bytes\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd/%zd bytes\n", |
total, nbytes); |
total, nbytes); |
return r; |
return r; |
} |
} |
Line 344 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 357 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
if (r < 0) { |
if (r < 0) { |
/* error */ |
/* error */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding error) (errno=%d)\n", | "Write %zd bytes (padding error) (errno=%d)\n", |
nbytes, errno); |
nbytes, errno); |
return nbytes; |
return nbytes; |
} |
} |
Line 354 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
Line 367 istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
|
if (total != pad_bytes) { |
if (total != pad_bytes) { |
/* incomplete padding */ |
/* incomplete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding %d)\n", | "Write %zd bytes (padding %zd)\n", |
nbytes, total); |
nbytes, total); |
return nbytes; |
return nbytes; |
} |
} |
/* complete padding */ |
/* complete padding */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
ISTGT_TRACELOG(ISTGT_TRACE_NET, |
"Write %d bytes (padding %d)\n", | "Write %zd bytes (padding %zd)\n", |
nbytes, pad_bytes); |
nbytes, pad_bytes); |
return nbytes; |
return nbytes; |
} |
} |
|
|
/* just aligned */ |
/* just aligned */ |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %d bytes (no padding)\n", | ISTGT_TRACELOG(ISTGT_TRACE_NET, "Write %zd bytes (no padding)\n", |
nbytes); |
nbytes); |
#endif /* ISTGT_USE_SENDBLOCK */ |
#endif /* ISTGT_USE_SENDBLOCK */ |
return nbytes; |
return nbytes; |
} |
} |
|
#endif /* !defined (ISTGT_USE_IOVEC) */ |
|
|
#define MATCH_DIGEST_WORD(BUF, CRC32C) \ |
#define MATCH_DIGEST_WORD(BUF, CRC32C) \ |
( ((((uint32_t) *((uint8_t *)(BUF)+0)) << 0) \ |
( ((((uint32_t) *((uint8_t *)(BUF)+0)) << 0) \ |
Line 412 istgt_make_digest_word(uint8_t *buf, size_t len, uint3
|
Line 426 istgt_make_digest_word(uint8_t *buf, size_t len, uint3
|
} |
} |
#endif |
#endif |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
static int |
static int |
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
{ |
{ |
Line 442 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 457 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
conn->initiator_name); |
conn->initiator_name); |
conn->state = CONN_STATE_EXITING; |
conn->state = CONN_STATE_EXITING; |
} else { |
} else { |
ISTGT_ERRLOG("iscsi_read() failed (errno=%d)\n", | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
errno); | errno, conn->initiator_name); |
} |
} |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_TRACELOG(ISTGT_TRACE_NET, "iscsi_read() EOF\n"); | ISTGT_TRACELOG(ISTGT_TRACE_NET, "iscsi_read() EOF (%s)\n", |
| conn->initiator_name); |
conn->state = CONN_STATE_EXITING; |
conn->state = CONN_STATE_EXITING; |
return -1; |
return -1; |
} |
} |
Line 466 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 482 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
(4 * total_ahs_len)); |
(4 * total_ahs_len)); |
rc = istgt_iscsi_read(conn, pdu->ahs, (4 * total_ahs_len)); |
rc = istgt_iscsi_read(conn, pdu->ahs, (4 * total_ahs_len)); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 492 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 509 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
rc = istgt_iscsi_read(conn, pdu->header_digest, |
rc = istgt_iscsi_read(conn, pdu->header_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
{ |
{ |
int opcode = BGET8W(&pdu->bhs.opcode, 5, 6); |
int opcode = BGET8W(&pdu->bhs.opcode, 5, 6); |
ISTGT_ERRLOG("Header Digest read error (opcode = 0x%x)\n", |
ISTGT_ERRLOG("Header Digest read error (opcode = 0x%x)\n", |
Line 535 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 553 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
data_len); |
data_len); |
rc = istgt_iscsi_read(conn, pdu->data, data_len); |
rc = istgt_iscsi_read(conn, pdu->data, data_len); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed (%d,errno=%d)\n", | ISTGT_ERRLOG("iscsi_read() failed (%d,errno=%d,%s)\n", |
rc, errno); | rc, errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 572 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 590 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
rc = istgt_iscsi_read(conn, pdu->data_digest, |
rc = istgt_iscsi_read(conn, pdu->data_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_read() failed\n"); | ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc == 0) { |
if (rc == 0) { |
Line 606 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 625 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_ERRLOG("header digest error\n"); | ISTGT_ERRLOG("header digest error (%s)\n", conn->initiator_name); |
return -1; |
return -1; |
} |
} |
} |
} |
Line 614 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 633 istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
crc32c = istgt_crc32c(pdu->data, data_len); |
crc32c = istgt_crc32c(pdu->data, data_len); |
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
if (rc == 0) { |
if (rc == 0) { |
ISTGT_ERRLOG("data digest error\n"); | ISTGT_ERRLOG("data digest error (%s)\n", conn->initiator_name); |
return -1; |
return -1; |
} |
} |
} |
} |
|
|
return total; |
return total; |
} |
} |
|
#else /* defined (ISTGT_USE_IOVEC) */ |
|
static int |
|
istgt_iscsi_read_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
|
{ |
|
struct iovec iovec[4]; /* AHS+HD+DATA+DD */ |
|
uint32_t crc32c; |
|
time_t start, now; |
|
int nbytes; |
|
int total_ahs_len; |
|
int data_len; |
|
int segment_len; |
|
int total; |
|
int rc; |
|
int i; |
|
|
|
pdu->ahs = NULL; |
|
pdu->total_ahs_len = 0; |
|
pdu->data = NULL; |
|
pdu->data_segment_len = 0; |
|
total = 0; |
|
|
|
/* BHS (require for all PDU) */ |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "BHS read %d\n", |
|
ISCSI_BHS_LEN); |
|
errno = 0; |
|
start = time(NULL); |
|
rc = recv(conn->sock, &pdu->bhs, ISCSI_BHS_LEN, MSG_WAITALL); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
if (errno == ECONNRESET) { |
|
ISTGT_WARNLOG("Connection reset by peer (%s,time=%d)\n", |
|
conn->initiator_name, (int)difftime(now, start)); |
|
conn->state = CONN_STATE_EXITING; |
|
} else if (errno == ETIMEDOUT) { |
|
ISTGT_WARNLOG("Operation timed out (%s,time=%d)\n", |
|
conn->initiator_name, (int)difftime(now, start)); |
|
conn->state = CONN_STATE_EXITING; |
|
} else { |
|
ISTGT_ERRLOG("iscsi_read() failed (errno=%d,%s,time=%d)\n", |
|
errno, conn->initiator_name, (int)difftime(now, start)); |
|
} |
|
return -1; |
|
} |
|
if (rc == 0) { |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "recv() EOF (%s)\n", |
|
conn->initiator_name); |
|
conn->state = CONN_STATE_EXITING; |
|
return -1; |
|
} |
|
if (rc != ISCSI_BHS_LEN) { |
|
ISTGT_ERRLOG("invalid BHS length (%d,%s)\n", rc, conn->initiator_name); |
|
return -1; |
|
} |
|
total += ISCSI_BHS_LEN; |
|
|
|
/* AHS */ |
|
total_ahs_len = DGET8(&pdu->bhs.total_ahs_len); |
|
if (total_ahs_len != 0) { |
|
pdu->ahs = xmalloc(ISCSI_ALIGN((4 * total_ahs_len))); |
|
pdu->total_ahs_len = total_ahs_len; |
|
total += (4 * total_ahs_len); |
|
} else { |
|
pdu->ahs = NULL; |
|
pdu->total_ahs_len = 0; |
|
} |
|
iovec[0].iov_base = pdu->ahs; |
|
iovec[0].iov_len = 4 * pdu->total_ahs_len; |
|
|
|
/* Header Digest */ |
|
iovec[1].iov_base = pdu->header_digest; |
|
if (conn->header_digest) { |
|
iovec[1].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[1].iov_len = 0; |
|
} |
|
|
|
/* Data Segment */ |
|
data_len = DGET24(&pdu->bhs.data_segment_len[0]); |
|
if (data_len != 0) { |
|
if (conn->sess == NULL) { |
|
segment_len = DEFAULT_FIRSTBURSTLENGTH; |
|
} else { |
|
segment_len = conn->MaxRecvDataSegmentLength; |
|
} |
|
if (data_len > segment_len) { |
|
ISTGT_ERRLOG("Data(%d) > Segment(%d)\n", |
|
data_len, segment_len); |
|
return -1; |
|
} |
|
if (ISCSI_ALIGN(data_len) <= ISTGT_SHORTDATASIZE) { |
|
pdu->data = pdu->shortdata; |
|
} else { |
|
pdu->data = xmalloc(ISCSI_ALIGN(segment_len)); |
|
} |
|
pdu->data_segment_len = data_len; |
|
total += ISCSI_ALIGN(data_len); |
|
} else { |
|
pdu->data = NULL; |
|
pdu->data_segment_len = 0; |
|
} |
|
iovec[2].iov_base = pdu->data; |
|
iovec[2].iov_len = ISCSI_ALIGN(pdu->data_segment_len); |
|
|
|
/* Data Digest */ |
|
iovec[3].iov_base = pdu->data_digest; |
|
if (conn->data_digest && data_len != 0) { |
|
iovec[3].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[3].iov_len = 0; |
|
} |
|
|
|
/* read all bytes to iovec */ |
|
nbytes = total - ISCSI_BHS_LEN; |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "PDU read %d\n", nbytes); |
|
errno = 0; |
|
start = time(NULL); |
|
while (nbytes > 0) { |
|
rc = readv(conn->sock, &iovec[0], 4); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
ISTGT_ERRLOG("readv() failed (%d,errno=%d,%s,time=%d)\n", |
|
rc, errno, conn->initiator_name, (int)difftime(now, start)); |
|
return -1; |
|
} |
|
if (rc == 0) { |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "readv() EOF (%s)\n", |
|
conn->initiator_name); |
|
conn->state = CONN_STATE_EXITING; |
|
return -1; |
|
} |
|
nbytes -= rc; |
|
if (nbytes == 0) |
|
break; |
|
/* adjust iovec length */ |
|
for (i = 0; i < 4; i++) { |
|
if (iovec[i].iov_len != 0 && iovec[i].iov_len > (size_t)rc) { |
|
iovec[i].iov_base |
|
= (void *) (((uintptr_t)iovec[i].iov_base) + rc); |
|
iovec[i].iov_len -= rc; |
|
break; |
|
} else { |
|
rc -= iovec[i].iov_len; |
|
iovec[i].iov_len = 0; |
|
} |
|
} |
|
} |
|
|
|
/* check digest */ |
|
if (conn->header_digest) { |
|
if (total_ahs_len == 0) { |
|
crc32c = istgt_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN); |
|
} else { |
|
int upd_total = 0; |
|
crc32c = ISTGT_CRC32C_INITIAL; |
|
crc32c = istgt_update_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN, crc32c); |
|
upd_total += ISCSI_BHS_LEN; |
|
crc32c = istgt_update_crc32c((uint8_t *) pdu->ahs, |
|
(4 * total_ahs_len), crc32c); |
|
upd_total += (4 * total_ahs_len); |
|
crc32c = istgt_fixup_crc32c(upd_total, crc32c); |
|
crc32c = crc32c ^ ISTGT_CRC32C_XOR; |
|
} |
|
rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); |
|
if (rc == 0) { |
|
ISTGT_ERRLOG("header digest error (%s)\n", conn->initiator_name); |
|
return -1; |
|
} |
|
} |
|
if (conn->data_digest && data_len != 0) { |
|
crc32c = istgt_crc32c(pdu->data, ISCSI_ALIGN(data_len)); |
|
rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); |
|
if (rc == 0) { |
|
ISTGT_ERRLOG("data digest error (%s)\n", conn->initiator_name); |
|
return -1; |
|
} |
|
} |
|
|
|
return total; |
|
} |
|
#endif /* defined (ISTGT_USE_IOVEC) */ |
|
|
static int istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu); |
static int istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu); |
|
static int istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit); |
|
|
|
static int istgt_update_pdu(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd) |
|
{ |
|
uint8_t *rsp; |
|
uint32_t task_tag; |
|
int opcode; |
|
int I_bit; |
|
|
|
I_bit = lu_cmd->I_bit; |
|
rsp = (uint8_t *) &lu_cmd->pdu->bhs; |
|
opcode = BGET8W(&rsp[0], 5, 6); |
|
task_tag = DGET32(&rsp[16]); |
|
if ((opcode == ISCSI_OP_R2T) |
|
|| (opcode == ISCSI_OP_NOPIN && task_tag == 0xffffffffU)) { |
|
SESS_MTX_LOCK(conn); |
|
DSET32(&rsp[24], conn->StatSN); |
|
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
|
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
|
} else if ((opcode == ISCSI_OP_TASK_RSP) |
|
|| (opcode == ISCSI_OP_NOPIN && task_tag != 0xffffffffU)) { |
|
SESS_MTX_LOCK(conn); |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
|
if (I_bit == 0) { |
|
conn->sess->ExpCmdSN++; |
|
conn->sess->MaxCmdSN++; |
|
} |
|
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
|
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
|
} |
|
return 0; |
|
} |
|
|
static int |
static int |
istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
{ |
{ |
Line 632 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 870 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
if (conn->use_sender == 0) { |
if (conn->use_sender == 0) { |
rc = istgt_iscsi_write_pdu_internal(conn, pdu); |
rc = istgt_iscsi_write_pdu_internal(conn, pdu); |
} else { |
} else { |
|
rc = istgt_iscsi_write_pdu_queue(conn, pdu, ISTGT_LU_TASK_REQPDU, 0); |
|
} |
|
return rc; |
|
} |
|
|
|
static int |
|
istgt_iscsi_write_pdu_upd(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int I_bit) |
|
{ |
|
int rc; |
|
|
|
if (conn->use_sender == 0) { |
|
rc = istgt_iscsi_write_pdu_internal(conn, pdu); |
|
} else { |
|
rc = istgt_iscsi_write_pdu_queue(conn, pdu, ISTGT_LU_TASK_REQUPDPDU, I_bit); |
|
} |
|
return rc; |
|
} |
|
|
|
static int |
|
istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit) |
|
{ |
|
int rc; |
|
|
|
if (conn->use_sender == 0) { |
|
rc = istgt_iscsi_write_pdu_internal(conn, pdu); |
|
} else { |
ISTGT_LU_TASK_Ptr lu_task; |
ISTGT_LU_TASK_Ptr lu_task; |
ISCSI_PDU_Ptr src_pdu, dst_pdu; |
ISCSI_PDU_Ptr src_pdu, dst_pdu; |
uint8_t *cp; |
uint8_t *cp; |
Line 656 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 920 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
alloc_len += ISCSI_ALIGN(data_len); |
alloc_len += ISCSI_ALIGN(data_len); |
lu_task = xmalloc(alloc_len); |
lu_task = xmalloc(alloc_len); |
memset(lu_task, 0, alloc_len); |
memset(lu_task, 0, alloc_len); |
lu_task->lu_cmd.pdu = (ISCSI_PDU_Ptr) ((uint8_t *)lu_task | lu_task->lu_cmd.pdu = (ISCSI_PDU_Ptr) ((uintptr_t)lu_task |
+ ISCSI_ALIGN(sizeof *lu_task)); |
+ ISCSI_ALIGN(sizeof *lu_task)); |
lu_task->lu_cmd.pdu->ahs = (ISCSI_AHS *) ((uint8_t *)lu_task->lu_cmd.pdu | lu_task->lu_cmd.pdu->ahs = (ISCSI_AHS *) ((uintptr_t)lu_task->lu_cmd.pdu |
+ ISCSI_ALIGN(sizeof *lu_task->lu_cmd.pdu)); |
+ ISCSI_ALIGN(sizeof *lu_task->lu_cmd.pdu)); |
lu_task->lu_cmd.pdu->data = (uint8_t *)lu_task->lu_cmd.pdu->ahs | lu_task->lu_cmd.pdu->data = (uint8_t *) ((uintptr_t)lu_task->lu_cmd.pdu->ahs |
+ ISCSI_ALIGN(4 * total_ahs_len); | + ISCSI_ALIGN(4 * total_ahs_len)); |
|
|
/* specify type and self conn */ |
/* specify type and self conn */ |
lu_task->type = ISTGT_LU_TASK_REQPDU; | //lu_task->type = ISTGT_LU_TASK_REQPDU; |
| lu_task->type = req_type; |
lu_task->conn = conn; |
lu_task->conn = conn; |
|
|
|
/* extra flags */ |
|
lu_task->lu_cmd.I_bit = I_bit; |
|
|
/* copy PDU structure */ |
/* copy PDU structure */ |
src_pdu = pdu; |
src_pdu = pdu; |
dst_pdu = lu_task->lu_cmd.pdu; |
dst_pdu = lu_task->lu_cmd.pdu; |
Line 717 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 985 istgt_iscsi_write_pdu(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
return rc; |
return rc; |
} |
} |
|
|
|
#if !defined (ISTGT_USE_IOVEC) |
static int |
static int |
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
{ |
{ |
Line 773 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1042 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
total); |
total); |
rc = istgt_iscsi_write(conn, spp, total); |
rc = istgt_iscsi_write(conn, spp, total); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed (errno=%d)\n", | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
errno); | errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != total) { |
if (rc != total) { |
Line 790 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1059 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
ISCSI_BHS_LEN); |
ISCSI_BHS_LEN); |
rc = istgt_iscsi_write(conn, &pdu->bhs, ISCSI_BHS_LEN); |
rc = istgt_iscsi_write(conn, &pdu->bhs, ISCSI_BHS_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed (errno=%d)\n", errno); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", errno, |
| conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_BHS_LEN) { |
if (rc != ISCSI_BHS_LEN) { |
Line 805 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1075 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
(4 * total_ahs_len)); |
(4 * total_ahs_len)); |
rc = istgt_iscsi_write(conn, pdu->ahs, (4 * total_ahs_len)); |
rc = istgt_iscsi_write(conn, pdu->ahs, (4 * total_ahs_len)); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != (4 * total_ahs_len)) { |
if (rc != (4 * total_ahs_len)) { |
Line 839 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1110 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
rc = istgt_iscsi_write(conn, pdu->header_digest, |
rc = istgt_iscsi_write(conn, pdu->header_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_DIGEST_LEN) { |
if (rc != ISCSI_DIGEST_LEN) { |
Line 856 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1128 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
data_len); |
data_len); |
rc = istgt_iscsi_write(conn, pdu->data, data_len); |
rc = istgt_iscsi_write(conn, pdu->data, data_len); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != data_len) { |
if (rc != data_len) { |
Line 879 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1152 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
rc = istgt_iscsi_write(conn, pdu->data_digest, |
rc = istgt_iscsi_write(conn, pdu->data_digest, |
ISCSI_DIGEST_LEN); |
ISCSI_DIGEST_LEN); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write() failed\n"); | ISTGT_ERRLOG("iscsi_write() failed (errno=%d,%s)\n", |
| errno, conn->initiator_name); |
return -1; |
return -1; |
} |
} |
if (rc != ISCSI_DIGEST_LEN) { |
if (rc != ISCSI_DIGEST_LEN) { |
Line 892 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
Line 1166 istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PD
|
|
|
return total; |
return total; |
} |
} |
|
#else /* defined (ISTGT_USE_IOVEC) */ |
|
static int |
|
istgt_iscsi_write_pdu_internal(CONN_Ptr conn, ISCSI_PDU_Ptr pdu) |
|
{ |
|
struct iovec iovec[5]; /* BHS+AHS+HD+DATA+DD */ |
|
uint8_t *cp; |
|
uint32_t crc32c; |
|
time_t start, now; |
|
int nbytes; |
|
int enable_digest; |
|
int opcode; |
|
int total_ahs_len; |
|
int data_len; |
|
int total; |
|
int rc; |
|
int i; |
|
|
|
cp = (uint8_t *) &pdu->bhs; |
|
total_ahs_len = DGET8(&cp[4]); |
|
data_len = DGET24(&cp[5]); |
|
total = 0; |
|
|
|
enable_digest = 1; |
|
opcode = BGET8W(&cp[0], 5, 6); |
|
if (opcode == ISCSI_OP_LOGIN_RSP) { |
|
/* this PDU should be sent without digest */ |
|
enable_digest = 0; |
|
} |
|
|
|
/* BHS */ |
|
iovec[0].iov_base = &pdu->bhs; |
|
iovec[0].iov_len = ISCSI_BHS_LEN; |
|
total += ISCSI_BHS_LEN; |
|
|
|
/* AHS */ |
|
iovec[1].iov_base = pdu->ahs; |
|
iovec[1].iov_len = 4 * total_ahs_len; |
|
total += (4 * total_ahs_len); |
|
|
|
/* Header Digest */ |
|
iovec[2].iov_base = pdu->header_digest; |
|
if (enable_digest && conn->header_digest) { |
|
if (total_ahs_len == 0) { |
|
crc32c = istgt_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN); |
|
} else { |
|
int upd_total = 0; |
|
crc32c = ISTGT_CRC32C_INITIAL; |
|
crc32c = istgt_update_crc32c((uint8_t *) &pdu->bhs, |
|
ISCSI_BHS_LEN, crc32c); |
|
upd_total += ISCSI_BHS_LEN; |
|
crc32c = istgt_update_crc32c((uint8_t *) pdu->ahs, |
|
(4 * total_ahs_len), crc32c); |
|
upd_total += (4 * total_ahs_len); |
|
crc32c = istgt_fixup_crc32c(upd_total, crc32c); |
|
crc32c = crc32c ^ ISTGT_CRC32C_XOR; |
|
} |
|
MAKE_DIGEST_WORD(pdu->header_digest, crc32c); |
|
|
|
iovec[2].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[2].iov_len = 0; |
|
} |
|
|
|
/* Data Segment */ |
|
iovec[3].iov_base = pdu->data; |
|
iovec[3].iov_len = ISCSI_ALIGN(data_len); |
|
total += ISCSI_ALIGN(data_len); |
|
|
|
/* Data Digest */ |
|
iovec[4].iov_base = pdu->data_digest; |
|
if (enable_digest && conn->data_digest && data_len != 0) { |
|
crc32c = istgt_crc32c(pdu->data, ISCSI_ALIGN(data_len)); |
|
MAKE_DIGEST_WORD(pdu->data_digest, crc32c); |
|
|
|
iovec[4].iov_len = ISCSI_DIGEST_LEN; |
|
total += ISCSI_DIGEST_LEN; |
|
} else { |
|
iovec[4].iov_len = 0; |
|
} |
|
|
|
/* write all bytes from iovec */ |
|
nbytes = total; |
|
ISTGT_TRACELOG(ISTGT_TRACE_NET, "PDU write %d\n", nbytes); |
|
errno = 0; |
|
start = time(NULL); |
|
while (nbytes > 0) { |
|
rc = writev(conn->sock, &iovec[0], 5); |
|
if (rc < 0) { |
|
now = time(NULL); |
|
ISTGT_ERRLOG("writev() failed (errno=%d,%s,time=%d)\n", |
|
errno, conn->initiator_name, (int)difftime(now, start)); |
|
return -1; |
|
} |
|
nbytes -= rc; |
|
if (nbytes == 0) |
|
break; |
|
/* adjust iovec length */ |
|
for (i = 0; i < 5; i++) { |
|
if (iovec[i].iov_len != 0 && iovec[i].iov_len > (size_t)rc) { |
|
iovec[i].iov_base |
|
= (void *) (((uintptr_t)iovec[i].iov_base) + rc); |
|
iovec[i].iov_len -= rc; |
|
break; |
|
} else { |
|
rc -= iovec[i].iov_len; |
|
iovec[i].iov_len = 0; |
|
} |
|
} |
|
} |
|
|
|
return total; |
|
} |
|
#endif /* defined (ISTGT_USE_IOVEC) */ |
|
|
int |
int |
istgt_iscsi_copy_pdu(ISCSI_PDU_Ptr dst_pdu, ISCSI_PDU_Ptr src_pdu) |
istgt_iscsi_copy_pdu(ISCSI_PDU_Ptr dst_pdu, ISCSI_PDU_Ptr src_pdu) |
{ |
{ |
Line 1346 istgt_iscsi_negotiate_params(CONN_Ptr conn, ISCSI_PARA
|
Line 1735 istgt_iscsi_negotiate_params(CONN_Ptr conn, ISCSI_PARA
|
} |
} |
|
|
static int |
static int |
istgt_iscsi_append_text(CONN_Ptr conn, const char *key, const char *val, uint8_t *data, int alloc_len, int data_len) | istgt_iscsi_append_text(CONN_Ptr conn __attribute__((__unused__)), const char *key, const char *val, uint8_t *data, int alloc_len, int data_len) |
{ |
{ |
int total; |
int total; |
int len; |
int len; |
Line 1782 istgt_iscsi_reject(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, i
|
Line 2171 istgt_iscsi_reject(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, i
|
|
|
DSET32(&rsp[16], 0xffffffffU); |
DSET32(&rsp[16], 0xffffffffU); |
|
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
|
if (conn->sess != NULL) { |
if (conn->sess != NULL) { |
SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
} else { |
} else { |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
DSET32(&rsp[28], 1); |
DSET32(&rsp[28], 1); |
DSET32(&rsp[32], 1); |
DSET32(&rsp[32], 1); |
} |
} |
Line 2298 istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 2689 istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
|
|
/* initialize parameters */ |
/* initialize parameters */ |
conn->StatSN = ExpStatSN; |
|
SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); |
|
conn->StatSN = ExpStatSN; |
conn->MaxOutstandingR2T |
conn->MaxOutstandingR2T |
= conn->sess->MaxOutstandingR2T; |
= conn->sess->MaxOutstandingR2T; |
conn->sess->isid = isid; |
conn->sess->isid = isid; |
Line 2574 istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 2965 istgt_iscsi_op_login(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
DSET16(&rsp[14], tsih); |
DSET16(&rsp[14], tsih); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
|
if (conn->sess != NULL) { |
if (conn->sess != NULL) { |
SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
} else { |
} else { |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
DSET32(&rsp[28], CmdSN); |
DSET32(&rsp[28], CmdSN); |
DSET32(&rsp[32], CmdSN); |
DSET32(&rsp[32], CmdSN); |
} |
} |
Line 2683 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3076 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
ISTGT_ERRLOG("CmdSN(%u) error\n", CmdSN); |
ISTGT_ERRLOG("CmdSN(%u) error\n", CmdSN); |
return -1; |
return -1; |
} |
} |
SESS_MTX_UNLOCK(conn); |
|
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ExpStatSN); |
ExpStatSN); |
Line 2692 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3084 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
if (ExpStatSN != conn->StatSN) { |
if (ExpStatSN != conn->StatSN) { |
#if 0 |
#if 0 |
ISTGT_ERRLOG("StatSN(%u) error\n", ExpStatSN); |
ISTGT_ERRLOG("StatSN(%u) error\n", ExpStatSN); |
|
SESS_MTX_UNLOCK(conn); |
return -1; |
return -1; |
#else |
#else |
/* StarPort have a bug */ |
/* StarPort have a bug */ |
Line 2699 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3092 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
conn->StatSN = ExpStatSN; |
conn->StatSN = ExpStatSN; |
#endif |
#endif |
} |
} |
|
SESS_MTX_UNLOCK(conn); |
|
|
if (F_bit && C_bit) { |
if (F_bit && C_bit) { |
ISTGT_ERRLOG("final and continue\n"); |
ISTGT_ERRLOG("final and continue\n"); |
Line 2768 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3162 istgt_iscsi_op_text(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
DSET32(&rsp[20], transfer_tag); |
DSET32(&rsp[20], transfer_tag); |
} |
} |
|
|
|
SESS_MTX_LOCK(conn); |
DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[24], conn->StatSN); |
conn->StatSN++; |
conn->StatSN++; |
SESS_MTX_LOCK(conn); |
|
if (I_bit == 0) { |
if (I_bit == 0) { |
conn->sess->ExpCmdSN++; |
conn->sess->ExpCmdSN++; |
conn->sess->MaxCmdSN++; |
conn->sess->MaxCmdSN++; |
Line 2850 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 3244 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
"CmdSN=%u, ExpStatSN=%u, StatSN=%u\n", |
"CmdSN=%u, ExpStatSN=%u, StatSN=%u\n", |
CmdSN, ExpStatSN, conn->StatSN); |
CmdSN, ExpStatSN, conn->StatSN); |
} |
} |
|
if (conn->sess != NULL) { |
|
SESS_MTX_LOCK(conn); |
|
} |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ExpStatSN); |
ExpStatSN); |
Line 2860 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 3257 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
ExpStatSN, conn->StatSN); |
ExpStatSN, conn->StatSN); |
/* ignore error */ |
/* ignore error */ |
} |
} |
|
if (conn->sess != NULL) { |
|
SESS_MTX_UNLOCK(conn); |
|
} |
|
|
response = 0; // connection or session closed successfully |
response = 0; // connection or session closed successfully |
|
|
Line 2875 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 3275 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
|
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
|
if (conn->sess != NULL) { |
if (conn->sess != NULL) { |
SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
if (conn->sess->connections == 1) { |
if (conn->sess->connections == 1) { |
conn->sess->ExpCmdSN++; |
conn->sess->ExpCmdSN++; |
conn->sess->MaxCmdSN++; |
conn->sess->MaxCmdSN++; |
Line 2887 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 3287 istgt_iscsi_op_logout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
} else { |
} else { |
|
DSET32(&rsp[24], conn->StatSN); |
|
conn->StatSN++; |
DSET32(&rsp[28], CmdSN); |
DSET32(&rsp[28], CmdSN); |
DSET32(&rsp[32], CmdSN); |
DSET32(&rsp[32], CmdSN); |
} |
} |
Line 3053 istgt_iscsi_transfer_in_internal(CONN_Ptr conn, ISTGT_
|
Line 3455 istgt_iscsi_transfer_in_internal(CONN_Ptr conn, ISTGT_
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[20], transfer_tag); |
DSET32(&rsp[20], transfer_tag); |
|
|
|
SESS_MTX_LOCK(conn); |
if (S_bit) { |
if (S_bit) { |
DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[24], conn->StatSN); |
conn->StatSN++; |
conn->StatSN++; |
} else { |
} else { |
DSET32(&rsp[24], 0); // StatSN or Reserved |
DSET32(&rsp[24], 0); // StatSN or Reserved |
} |
} |
SESS_MTX_LOCK(conn); |
|
if (F_bit && S_bit && lu_cmd->I_bit == 0) { |
if (F_bit && S_bit && lu_cmd->I_bit == 0) { |
conn->sess->MaxCmdSN++; |
conn->sess->MaxCmdSN++; |
} |
} |
Line 3104 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3506 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
uint32_t transfer_len; |
uint32_t transfer_len; |
uint32_t CmdSN; |
uint32_t CmdSN; |
uint32_t ExpStatSN; |
uint32_t ExpStatSN; |
|
size_t bidi_residual_len; |
|
size_t residual_len; |
|
size_t data_len; |
|
size_t alloc_len; |
int I_bit, F_bit, R_bit, W_bit, Attr_bit; |
int I_bit, F_bit, R_bit, W_bit, Attr_bit; |
int o_bit, u_bit, O_bit, U_bit; |
int o_bit, u_bit, O_bit, U_bit; |
int bidi_residual_len; |
|
int residual_len; |
|
int data_len; |
|
int alloc_len; |
|
int rc; |
int rc; |
|
|
if (!conn->full_feature) { |
if (!conn->full_feature) { |
Line 3156 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3558 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
if (SN32_GT(CmdSN, conn->sess->ExpCmdSN)) { |
if (SN32_GT(CmdSN, conn->sess->ExpCmdSN)) { |
if (conn->sess->connections > 1) { |
if (conn->sess->connections > 1) { |
struct timespec abstime; |
struct timespec abstime; |
time_t now; | time_t start, now; |
|
|
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
now = time(NULL); | start = now = time(NULL); |
memset(&abstime, 0, sizeof abstime); |
memset(&abstime, 0, sizeof abstime); |
abstime.tv_sec = now + (MAX_MCSREVWAIT / 1000); |
abstime.tv_sec = now + (MAX_MCSREVWAIT / 1000); |
abstime.tv_nsec = (MAX_MCSREVWAIT % 1000) * 1000000; |
abstime.tv_nsec = (MAX_MCSREVWAIT % 1000) * 1000000; |
Line 3186 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3588 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
} |
} |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("MCS: CmdSN(%u) error ExpCmdSN=%u\n", | now = time(NULL); |
CmdSN, conn->sess->ExpCmdSN); | ISTGT_ERRLOG("MCS: CmdSN(%u) error ExpCmdSN=%u " |
| "(time=%d)\n", |
| CmdSN, conn->sess->ExpCmdSN, |
| (int)difftime(now, start)); |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
return -1; |
return -1; |
} |
} |
Line 3219 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3624 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
CmdSN, conn->sess->ExpCmdSN); |
CmdSN, conn->sess->ExpCmdSN); |
return -1; |
return -1; |
} |
} |
SESS_MTX_UNLOCK(conn); |
|
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ExpStatSN); |
ExpStatSN); |
Line 3227 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3631 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
} |
} |
{ |
{ |
uint32_t QCmdSN; |
uint32_t QCmdSN; |
SESS_MTX_LOCK(conn); | //SESS_MTX_LOCK(conn); |
QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; |
QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; |
SESS_MTX_UNLOCK(conn); | //SESS_MTX_UNLOCK(conn); |
QCmdSN += conn->queue_depth; |
QCmdSN += conn->queue_depth; |
if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { |
if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { |
ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", |
ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", |
ExpStatSN, conn->StatSN, QCmdSN); |
ExpStatSN, conn->StatSN, QCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
return -1; |
return -1; |
} |
} |
} |
} |
|
SESS_MTX_UNLOCK(conn); |
|
|
lu_cmd.pdu = pdu; |
lu_cmd.pdu = pdu; |
SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); |
Line 3336 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3742 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
&& lu_cmd.status == ISTGT_SCSI_STATUS_GOOD) { |
&& lu_cmd.status == ISTGT_SCSI_STATUS_GOOD) { |
if (data_len < transfer_len) { |
if (data_len < transfer_len) { |
/* underflow */ |
/* underflow */ |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %u/%u\n", | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %zu/%u\n", |
data_len, transfer_len); |
data_len, transfer_len); |
residual_len = transfer_len - data_len; |
residual_len = transfer_len - data_len; |
U_bit = 1; |
U_bit = 1; |
} else if (data_len > transfer_len) { |
} else if (data_len > transfer_len) { |
/* overflow */ |
/* overflow */ |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %u/%u\n", | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %zu/%u\n", |
data_len, transfer_len); |
data_len, transfer_len); |
residual_len = data_len - transfer_len; |
residual_len = data_len - transfer_len; |
O_bit = 1; |
O_bit = 1; |
Line 3371 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3777 istgt_iscsi_op_scsi(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[20], 0); // SNACK Tag |
DSET32(&rsp[20], 0); // SNACK Tag |
|
|
|
SESS_MTX_LOCK(conn); |
DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[24], conn->StatSN); |
conn->StatSN++; |
conn->StatSN++; |
SESS_MTX_LOCK(conn); |
|
if (I_bit == 0) { |
if (I_bit == 0) { |
conn->sess->MaxCmdSN++; |
conn->sess->MaxCmdSN++; |
} |
} |
Line 3418 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
Line 3824 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
uint32_t task_tag; |
uint32_t task_tag; |
uint32_t transfer_len; |
uint32_t transfer_len; |
uint32_t CmdSN; |
uint32_t CmdSN; |
|
size_t residual_len; |
|
size_t data_len; |
int I_bit; |
int I_bit; |
int o_bit, u_bit, O_bit, U_bit; |
int o_bit, u_bit, O_bit, U_bit; |
int bidi_residual_len; |
int bidi_residual_len; |
int residual_len; |
|
int data_len; |
|
int rc; |
int rc; |
|
|
lu_cmd = &lu_task->lu_cmd; |
lu_cmd = &lu_task->lu_cmd; |
Line 3460 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
Line 3866 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
&& lu_cmd->status == ISTGT_SCSI_STATUS_GOOD) { |
&& lu_cmd->status == ISTGT_SCSI_STATUS_GOOD) { |
if (data_len < transfer_len) { |
if (data_len < transfer_len) { |
/* underflow */ |
/* underflow */ |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %u/%u\n", | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Underflow %zu/%u\n", |
data_len, transfer_len); |
data_len, transfer_len); |
residual_len = transfer_len - data_len; |
residual_len = transfer_len - data_len; |
U_bit = 1; |
U_bit = 1; |
} else if (data_len > transfer_len) { |
} else if (data_len > transfer_len) { |
/* overflow */ |
/* overflow */ |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %u/%u\n", | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Overflow %zu/%u\n", |
data_len, transfer_len); |
data_len, transfer_len); |
residual_len = data_len - transfer_len; |
residual_len = data_len - transfer_len; |
O_bit = 1; |
O_bit = 1; |
Line 3495 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
Line 3901 istgt_iscsi_task_response(CONN_Ptr conn, ISTGT_LU_TASK
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[20], 0); // SNACK Tag |
DSET32(&rsp[20], 0); // SNACK Tag |
|
|
|
SESS_MTX_LOCK(conn); |
DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[24], conn->StatSN); |
conn->StatSN++; |
conn->StatSN++; |
SESS_MTX_LOCK(conn); |
|
if (I_bit == 0) { |
if (I_bit == 0) { |
conn->sess->MaxCmdSN++; |
conn->sess->MaxCmdSN++; |
} |
} |
Line 3570 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3976 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
conn->sess->ExpCmdSN); |
conn->sess->ExpCmdSN); |
conn->sess->ExpCmdSN = CmdSN; |
conn->sess->ExpCmdSN = CmdSN; |
} |
} |
SESS_MTX_UNLOCK(conn); |
|
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ExpStatSN); |
ExpStatSN); |
Line 3584 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 3989 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
conn->StatSN = ExpStatSN; |
conn->StatSN = ExpStatSN; |
} |
} |
#endif |
#endif |
|
SESS_MTX_UNLOCK(conn); |
|
|
response = 0; // Function complete. |
response = 0; // Function complete. |
switch (function) { |
switch (function) { |
Line 3675 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 4081 istgt_iscsi_op_task(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
|
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); | if (conn->use_sender == 0) { |
conn->StatSN++; | SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); | DSET32(&rsp[24], conn->StatSN); |
if (I_bit == 0) { | conn->StatSN++; |
conn->sess->ExpCmdSN++; | if (I_bit == 0) { |
conn->sess->MaxCmdSN++; | conn->sess->ExpCmdSN++; |
| conn->sess->MaxCmdSN++; |
| } |
| DSET32(&rsp[28], conn->sess->ExpCmdSN); |
| DSET32(&rsp[32], conn->sess->MaxCmdSN); |
| SESS_MTX_UNLOCK(conn); |
| } else { |
| // update by sender |
} |
} |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
|
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
|
|
|
rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); | rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, I_bit); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
return -1; |
return -1; |
Line 3752 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 4162 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
} |
} |
} else if (CmdSN != conn->sess->ExpCmdSN) { |
} else if (CmdSN != conn->sess->ExpCmdSN) { |
SESS_MTX_UNLOCK(conn); |
SESS_MTX_UNLOCK(conn); |
ISTGT_ERRLOG("CmdSN(%u) error\n", CmdSN); | ISTGT_ERRLOG("CmdSN(%u) error ExpCmdSN=%u\n", |
| CmdSN, conn->sess->ExpCmdSN); |
return -1; |
return -1; |
} |
} |
SESS_MTX_UNLOCK(conn); |
|
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
if (SN32_GT(ExpStatSN, conn->StatSN)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "StatSN(%u) advanced\n", |
ExpStatSN); |
ExpStatSN); |
Line 3763 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 4173 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
} |
} |
{ |
{ |
uint32_t QCmdSN; |
uint32_t QCmdSN; |
SESS_MTX_LOCK(conn); | //SESS_MTX_LOCK(conn); |
QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; |
QCmdSN = conn->sess->MaxCmdSN - conn->sess->ExpCmdSN + 1; |
SESS_MTX_UNLOCK(conn); | //SESS_MTX_UNLOCK(conn); |
QCmdSN += conn->queue_depth; |
QCmdSN += conn->queue_depth; |
if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { |
if (SN32_LT(ExpStatSN + QCmdSN, conn->StatSN)) { |
ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", |
ISTGT_ERRLOG("StatSN(%u/%u) QCmdSN(%u) error\n", |
ExpStatSN, conn->StatSN, QCmdSN); |
ExpStatSN, conn->StatSN, QCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
return -1; |
return -1; |
} |
} |
} |
} |
|
SESS_MTX_UNLOCK(conn); |
|
|
if (task_tag == 0xffffffffU) { |
if (task_tag == 0xffffffffU) { |
if (I_bit == 1) { |
if (I_bit == 1) { |
Line 3812 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
Line 4224 istgt_iscsi_op_nopout(CONN_Ptr conn, ISCSI_PDU_Ptr pdu
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[20], transfer_tag); |
DSET32(&rsp[20], transfer_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); | if (conn->use_sender == 0) { |
conn->StatSN++; | SESS_MTX_LOCK(conn); |
SESS_MTX_LOCK(conn); | DSET32(&rsp[24], conn->StatSN); |
if (I_bit == 0) { | conn->StatSN++; |
conn->sess->ExpCmdSN++; | if (I_bit == 0) { |
conn->sess->MaxCmdSN++; | conn->sess->ExpCmdSN++; |
| conn->sess->MaxCmdSN++; |
| } |
| DSET32(&rsp[28], conn->sess->ExpCmdSN); |
| DSET32(&rsp[32], conn->sess->MaxCmdSN); |
| SESS_MTX_UNLOCK(conn); |
| } else { |
| // update by sender |
} |
} |
DSET32(&rsp[28], conn->sess->ExpCmdSN); |
|
DSET32(&rsp[32], conn->sess->MaxCmdSN); |
|
SESS_MTX_UNLOCK(conn); |
|
|
|
rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); | rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, I_bit); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
return -1; |
return -1; |
Line 3890 istgt_add_transfer_task(CONN_Ptr conn, ISTGT_LU_CMD_Pt
|
Line 4306 istgt_add_transfer_task(CONN_Ptr conn, ISTGT_LU_CMD_Pt
|
ISTGT_R2T_TASK_Ptr r2t_task; |
ISTGT_R2T_TASK_Ptr r2t_task; |
uint32_t transfer_len; |
uint32_t transfer_len; |
uint32_t transfer_tag; |
uint32_t transfer_tag; |
int first_burst_len; | size_t first_burst_len; |
int max_burst_len; | size_t max_burst_len; |
int data_len; | size_t data_len; |
int offset = 0; | size_t offset = 0; |
int len; |
int len; |
int idx; |
int idx; |
int rc; |
int rc; |
Line 4049 istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 4465 istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
uint32_t ExpDataSN; |
uint32_t ExpDataSN; |
uint32_t DataSN; |
uint32_t DataSN; |
uint32_t buffer_offset; |
uint32_t buffer_offset; |
|
size_t data_len; |
|
size_t alloc_len; |
|
size_t offset; |
int F_bit; |
int F_bit; |
int data_len; |
|
int alloc_len; |
|
int offset; |
|
int rc; |
int rc; |
|
|
if (!conn->full_feature) { |
if (!conn->full_feature) { |
Line 4103 istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
Line 4519 istgt_iscsi_op_data(CONN_Ptr conn, ISCSI_PDU_Ptr pdu)
|
ExpDataSN = r2t_task->DataSN; |
ExpDataSN = r2t_task->DataSN; |
|
|
ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, |
ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, |
"StatSN=%u, ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%d\n", | "StatSN=%u, ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%zd\n", |
conn->StatSN, ExpStatSN, DataSN, buffer_offset, data_len); |
conn->StatSN, ExpStatSN, DataSN, buffer_offset, data_len); |
if (DataSN != ExpDataSN) { |
if (DataSN != ExpDataSN) { |
ISTGT_ERRLOG("DataSN(%u) error\n", DataSN); |
ISTGT_ERRLOG("DataSN(%u) error\n", DataSN); |
Line 4158 istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l
|
Line 4574 istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l
|
DSET32(&rsp[16], lu_cmd->task_tag); |
DSET32(&rsp[16], lu_cmd->task_tag); |
DSET32(&rsp[20], transfer_tag); |
DSET32(&rsp[20], transfer_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); | if (conn->use_sender == 0) { |
SESS_MTX_LOCK(conn); | SESS_MTX_LOCK(conn); |
DSET32(&rsp[28], conn->sess->ExpCmdSN); | DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); | DSET32(&rsp[28], conn->sess->ExpCmdSN); |
SESS_MTX_UNLOCK(conn); | DSET32(&rsp[32], conn->sess->MaxCmdSN); |
| SESS_MTX_UNLOCK(conn); |
| } else { |
| // update by sender |
| } |
|
|
DSET32(&rsp[36], *R2TSN); |
DSET32(&rsp[36], *R2TSN); |
*R2TSN += 1; |
*R2TSN += 1; |
DSET32(&rsp[40], (uint32_t) offset); |
DSET32(&rsp[40], (uint32_t) offset); |
DSET32(&rsp[44], (uint32_t) len); |
DSET32(&rsp[44], (uint32_t) len); |
|
|
rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); | rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, 0); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
return -1; |
return -1; |
Line 4179 istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l
|
Line 4599 istgt_iscsi_send_r2t(CONN_Ptr conn, ISTGT_LU_CMD_Ptr l
|
} |
} |
|
|
int |
int |
istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint8_t *data, int alloc_len, int transfer_len) | istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_Ptr lu_cmd, uint8_t *data, size_t alloc_len, size_t transfer_len) |
{ |
{ |
ISTGT_R2T_TASK_Ptr r2t_task; |
ISTGT_R2T_TASK_Ptr r2t_task; |
ISCSI_PDU data_pdu; |
ISCSI_PDU data_pdu; |
Line 4195 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4615 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
uint32_t DataSN; |
uint32_t DataSN; |
uint32_t buffer_offset; |
uint32_t buffer_offset; |
uint32_t R2TSN; |
uint32_t R2TSN; |
|
size_t data_len; |
|
size_t segment_len; |
|
size_t first_burst_len; |
|
size_t max_burst_len; |
|
size_t offset; |
int immediate, opcode; |
int immediate, opcode; |
int F_bit; |
int F_bit; |
int data_len; |
|
int segment_len; |
|
int first_burst_len; |
|
int max_burst_len; |
|
int offset; |
|
int len; |
int len; |
int r2t_flag; |
int r2t_flag; |
int r2t_offset; |
int r2t_offset; |
Line 4230 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4650 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
} |
} |
|
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"Transfer=%d, First=%d, Max=%d, Segment=%d\n", | "Transfer=%zd, First=%zd, Max=%zd, Segment=%zd\n", |
transfer_len, data_len, max_burst_len, segment_len); |
transfer_len, data_len, max_burst_len, segment_len); |
|
|
r2t_task = istgt_get_transfer_task(conn, current_transfer_tag); |
r2t_task = istgt_get_transfer_task(conn, current_transfer_tag); |
Line 4250 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4670 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
istgt_free_transfer_task(r2t_task); |
istgt_free_transfer_task(r2t_task); |
|
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"Using R2T(%d) offset=%d, DataSN=%d\n", | "Using R2T(%d) offset=%zd, DataSN=%d\n", |
conn->pending_r2t, offset, ExpDataSN); |
conn->pending_r2t, offset, ExpDataSN); |
|
|
rc = istgt_queue_count(&conn->pending_pdus); |
rc = istgt_queue_count(&conn->pending_pdus); |
Line 4302 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4722 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
data_pdu.copy_pdu = 0; |
data_pdu.copy_pdu = 0; |
do { |
do { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"Transfer=%d, Offset=%d, Len=%d\n", | "Transfer=%zd, Offset=%zd, Len=%d\n", |
transfer_len, offset, len); |
transfer_len, offset, len); |
/* send R2T if required */ |
/* send R2T if required */ |
if (r2t_flag == 0 |
if (r2t_flag == 0 |
Line 4330 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4750 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
r2t_sent = 1; |
r2t_sent = 1; |
ExpDataSN = 0; |
ExpDataSN = 0; |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"R2T, Transfer=%d, Offset=%d, Len=%d\n", | "R2T, Transfer=%zd, Offset=%zd, Len=%d\n", |
transfer_len, offset, len); |
transfer_len, offset, len); |
} else { |
} else { |
r2t_sent = 0; |
r2t_sent = 0; |
Line 4434 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4854 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
|
|
ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, |
ISTGT_TRACELOG(ISTGT_TRACE_ISCSI, |
"StatSN=%u, " |
"StatSN=%u, " |
"ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%d\n", | "ExpStatSN=%u, DataSN=%u, Offset=%u, Data=%zd\n", |
conn->StatSN, |
conn->StatSN, |
ExpStatSN, DataSN, buffer_offset, data_len); |
ExpStatSN, DataSN, buffer_offset, data_len); |
if (DataSN != ExpDataSN) { |
if (DataSN != ExpDataSN) { |
Line 4488 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4908 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
ExpDataSN++; |
ExpDataSN++; |
|
|
if (r2t_flag == 0 && (offset > first_burst_len)) { |
if (r2t_flag == 0 && (offset > first_burst_len)) { |
ISTGT_ERRLOG("data_len(%d) > first_burst_length(%d)", | ISTGT_ERRLOG("data_len(%zd) > first_burst_length(%zd)", |
offset, first_burst_len); |
offset, first_burst_len); |
goto error_return; |
goto error_return; |
} |
} |
Line 4534 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
Line 4954 istgt_iscsi_transfer_out(CONN_Ptr conn, ISTGT_LU_CMD_P
|
} |
} |
|
|
r2t_return: |
r2t_return: |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Transfered=%d, Offset=%d\n", | ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "Transfered=%zd, Offset=%zd\n", |
transfer_len, offset); |
transfer_len, offset); |
|
|
return 0; |
return 0; |
Line 4586 istgt_iscsi_send_nopin(CONN_Ptr conn)
|
Line 5006 istgt_iscsi_send_nopin(CONN_Ptr conn)
|
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[16], task_tag); |
DSET32(&rsp[20], transfer_tag); |
DSET32(&rsp[20], transfer_tag); |
|
|
DSET32(&rsp[24], conn->StatSN); | if (conn->use_sender == 0) { |
SESS_MTX_LOCK(conn); | SESS_MTX_LOCK(conn); |
DSET32(&rsp[28], conn->sess->ExpCmdSN); | DSET32(&rsp[24], conn->StatSN); |
DSET32(&rsp[32], conn->sess->MaxCmdSN); | DSET32(&rsp[28], conn->sess->ExpCmdSN); |
SESS_MTX_UNLOCK(conn); | DSET32(&rsp[32], conn->sess->MaxCmdSN); |
| SESS_MTX_UNLOCK(conn); |
| } else { |
| // update by sender |
| } |
|
|
rc = istgt_iscsi_write_pdu(conn, &rsp_pdu); | rc = istgt_iscsi_write_pdu_upd(conn, &rsp_pdu, 0); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
ISTGT_ERRLOG("iscsi_write_pdu() failed\n"); |
return -1; |
return -1; |
Line 4711 wait_all_task(CONN_Ptr conn)
|
Line 5135 wait_all_task(CONN_Ptr conn)
|
ISTGT_ERRLOG("kqueue() failed\n"); |
ISTGT_ERRLOG("kqueue() failed\n"); |
return; |
return; |
} |
} |
EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); | ISTGT_EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("kevent() failed\n"); |
ISTGT_ERRLOG("kevent() failed\n"); |
Line 4761 wait_all_task(CONN_Ptr conn)
|
Line 5185 wait_all_task(CONN_Ptr conn)
|
#endif /* ISTGT_USE_KQUEUE */ |
#endif /* ISTGT_USE_KQUEUE */ |
|
|
#ifdef ISTGT_USE_KQUEUE |
#ifdef ISTGT_USE_KQUEUE |
if (kev.ident == conn->task_pipe[0]) { | if (kev.ident == (uintptr_t)conn->task_pipe[0]) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
break; |
break; |
} |
} |
Line 4963 sender(void *arg)
|
Line 5387 sender(void *arg)
|
if (rc < 0) { |
if (rc < 0) { |
lu_task->error = 1; |
lu_task->error = 1; |
ISTGT_ERRLOG( |
ISTGT_ERRLOG( |
"iscsi_task_response() failed on %s(%s)\n", | "iscsi_task_response() CmdSN=%u failed" |
| " on %s(%s)\n", lu_task->lu_cmd.CmdSN, |
conn->target_port, conn->initiator_port); |
conn->target_port, conn->initiator_port); |
|
rc = write(conn->task_pipe[1], "E", 1); |
|
if(rc < 0 || rc != 1) { |
|
ISTGT_ERRLOG("write() failed\n"); |
|
} |
break; |
break; |
} |
} |
rc = istgt_lu_destroy_task(lu_task); |
rc = istgt_lu_destroy_task(lu_task); |
Line 4973 sender(void *arg)
|
Line 5402 sender(void *arg)
|
break; |
break; |
} |
} |
} else if (lu_task->type == ISTGT_LU_TASK_REQPDU) { |
} else if (lu_task->type == ISTGT_LU_TASK_REQPDU) { |
|
reqpdu: |
/* send PDU */ |
/* send PDU */ |
rc = istgt_iscsi_write_pdu_internal(lu_task->conn, |
rc = istgt_iscsi_write_pdu_internal(lu_task->conn, |
lu_task->lu_cmd.pdu); |
lu_task->lu_cmd.pdu); |
Line 4982 sender(void *arg)
|
Line 5412 sender(void *arg)
|
"iscsi_write_pdu() failed on %s(%s)\n", |
"iscsi_write_pdu() failed on %s(%s)\n", |
lu_task->conn->target_port, |
lu_task->conn->target_port, |
lu_task->conn->initiator_port); |
lu_task->conn->initiator_port); |
|
rc = write(conn->task_pipe[1], "E", 1); |
|
if(rc < 0 || rc != 1) { |
|
ISTGT_ERRLOG("write() failed\n"); |
|
} |
break; |
break; |
} |
} |
/* free allocated memory by caller */ |
/* free allocated memory by caller */ |
xfree(lu_task); |
xfree(lu_task); |
|
} else if (lu_task->type == ISTGT_LU_TASK_REQUPDPDU) { |
|
rc = istgt_update_pdu(lu_task->conn, &lu_task->lu_cmd); |
|
if (rc < 0) { |
|
lu_task->error = 1; |
|
ISTGT_ERRLOG( |
|
"update_pdu() failed on %s(%s)\n", |
|
lu_task->conn->target_port, |
|
lu_task->conn->initiator_port); |
|
rc = write(conn->task_pipe[1], "E", 1); |
|
if(rc < 0 || rc != 1) { |
|
ISTGT_ERRLOG("write() failed\n"); |
|
} |
|
break; |
|
} |
|
goto reqpdu; |
} else { |
} else { |
ISTGT_ERRLOG("Unknown task type %x\n", lu_task->type); |
ISTGT_ERRLOG("Unknown task type %x\n", lu_task->type); |
rc = -1; |
rc = -1; |
Line 5035 worker(void *arg)
|
Line 5484 worker(void *arg)
|
return NULL; |
return NULL; |
} |
} |
conn->kq = kq; |
conn->kq = kq; |
EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); | #if defined (ISTGT_USE_IOVEC) && defined (NOTE_LOWAT) |
| ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, NOTE_LOWAT, ISCSI_BHS_LEN, NULL); |
| #else |
| ISTGT_EV_SET(&kev, conn->sock, EVFILT_READ, EV_ADD, 0, 0, NULL); |
| #endif |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("kevent() failed\n"); |
ISTGT_ERRLOG("kevent() failed\n"); |
close(kq); |
close(kq); |
return NULL; |
return NULL; |
} |
} |
EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); | ISTGT_EV_SET(&kev, conn->task_pipe[0], EVFILT_READ, EV_ADD, 0, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
if (rc == -1) { |
if (rc == -1) { |
ISTGT_ERRLOG("kevent() failed\n"); |
ISTGT_ERRLOG("kevent() failed\n"); |
Line 5050 worker(void *arg)
|
Line 5503 worker(void *arg)
|
return NULL; |
return NULL; |
} |
} |
|
|
EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); | if (!conn->istgt->daemon) { |
rc = kevent(kq, &kev, 1, NULL, 0, NULL); | ISTGT_EV_SET(&kev, SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); |
if (rc == -1) { | rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
ISTGT_ERRLOG("kevent() failed\n"); | if (rc == -1) { |
close(kq); | ISTGT_ERRLOG("kevent() failed\n"); |
return NULL; | close(kq); |
| return NULL; |
| } |
| ISTGT_EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); |
| rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
| if (rc == -1) { |
| ISTGT_ERRLOG("kevent() failed\n"); |
| close(kq); |
| return NULL; |
| } |
} |
} |
EV_SET(&kev, SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); |
|
rc = kevent(kq, &kev, 1, NULL, 0, NULL); |
|
if (rc == -1) { |
|
ISTGT_ERRLOG("kevent() failed\n"); |
|
close(kq); |
|
return NULL; |
|
} |
|
#else |
#else |
memset(&fds, 0, sizeof fds); |
memset(&fds, 0, sizeof fds); |
fds[0].fd = conn->sock; |
fds[0].fd = conn->sock; |
fds[0].events = POLLIN; |
fds[0].events = POLLIN; |
fds[1].fd = conn->task_pipe[0]; |
fds[1].fd = conn->task_pipe[0]; |
fds[1].events = POLLIN; |
fds[1].events = POLLIN; |
|
|
nopin_timer = conn->nopininterval; |
|
#endif /* ISTGT_USE_KQUEUE */ |
#endif /* ISTGT_USE_KQUEUE */ |
|
|
conn->pdu.ahs = NULL; |
conn->pdu.ahs = NULL; |
Line 5108 worker(void *arg)
|
Line 5561 worker(void *arg)
|
pthread_sigmask(SIG_UNBLOCK, &signew, &sigold); |
pthread_sigmask(SIG_UNBLOCK, &signew, &sigold); |
|
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start (%d)\n", conn->id); |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "loop start (%d)\n", conn->id); |
|
#ifndef ISTGT_USE_KQUEUE |
|
nopin_timer = conn->nopininterval; |
|
#endif /* !ISTGT_USE_KQUEUE */ |
while (1) { |
while (1) { |
/* check exit request */ |
/* check exit request */ |
if (conn->sess != NULL) { |
if (conn->sess != NULL) { |
Line 5187 worker(void *arg)
|
Line 5643 worker(void *arg)
|
} |
} |
if (rc == 0) { |
if (rc == 0) { |
/* no fds */ |
/* no fds */ |
|
//ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "poll TIMEOUT\n"); |
if (nopin_timer > 0) { |
if (nopin_timer > 0) { |
nopin_timer -= POLLWAIT; |
nopin_timer -= POLLWAIT; |
if (nopin_timer <= 0) { |
if (nopin_timer <= 0) { |
Line 5205 worker(void *arg)
|
Line 5662 worker(void *arg)
|
|
|
/* on socket */ |
/* on socket */ |
#ifdef ISTGT_USE_KQUEUE |
#ifdef ISTGT_USE_KQUEUE |
if (kev.ident == conn->sock) { | if (kev.ident == (uintptr_t)conn->sock) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"kevent EOF/ERROR\n"); |
"kevent EOF/ERROR\n"); |
Line 5220 worker(void *arg)
|
Line 5677 worker(void *arg)
|
conn->pdu.copy_pdu = 0; |
conn->pdu.copy_pdu = 0; |
rc = istgt_iscsi_read_pdu(conn, &conn->pdu); |
rc = istgt_iscsi_read_pdu(conn, &conn->pdu); |
if (rc < 0) { |
if (rc < 0) { |
ISTGT_ERRLOG("conn->state = %d\n", conn->state); | if (conn->state != CONN_STATE_EXITING) { |
| ISTGT_ERRLOG("conn->state = %d\n", conn->state); |
| } |
if (conn->state != CONN_STATE_RUNNING) { |
if (conn->state != CONN_STATE_RUNNING) { |
if (errno == EINPROGRESS) { |
if (errno == EINPROGRESS) { |
sleep(1); |
sleep(1); |
Line 5317 worker(void *arg)
|
Line 5776 worker(void *arg)
|
|
|
/* execute on task queue */ |
/* execute on task queue */ |
#ifdef ISTGT_USE_KQUEUE |
#ifdef ISTGT_USE_KQUEUE |
if (kev.ident == conn->task_pipe[0]) { | if (kev.ident == (uintptr_t)conn->task_pipe[0]) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
if (kev.flags & (EV_EOF|EV_ERROR)) { |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
"kevent EOF/ERROR\n"); |
"kevent EOF/ERROR\n"); |
Line 5338 worker(void *arg)
|
Line 5797 worker(void *arg)
|
ISTGT_ERRLOG("read() failed\n"); |
ISTGT_ERRLOG("read() failed\n"); |
break; |
break; |
} |
} |
|
if (tmp[0] == 'E') { |
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "exit request (%d)\n", |
|
conn->id); |
|
break; |
|
} |
|
|
/* DATA-IN/OUT */ |
/* DATA-IN/OUT */ |
MTX_LOCK(&conn->task_queue_mutex); |
MTX_LOCK(&conn->task_queue_mutex); |
Line 5378 worker(void *arg)
|
Line 5842 worker(void *arg)
|
lu_task = NULL; |
lu_task = NULL; |
conn->exec_lu_task = NULL; |
conn->exec_lu_task = NULL; |
} else { |
} else { |
MTX_LOCK(&lu_task->trans_mutex); |
|
//ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
//ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
// "Task Write Trans START\n"); |
// "Task Write Trans START\n"); |
rc = istgt_iscsi_task_transfer_out(conn, lu_task); |
rc = istgt_iscsi_task_transfer_out(conn, lu_task); |
if (rc < 0) { |
if (rc < 0) { |
lu_task->error = 1; |
lu_task->error = 1; |
MTX_UNLOCK(&lu_task->trans_mutex); |
|
ISTGT_ERRLOG("iscsi_task_transfer_out() failed on %s(%s)\n", |
ISTGT_ERRLOG("iscsi_task_transfer_out() failed on %s(%s)\n", |
conn->target_port, |
conn->target_port, |
conn->initiator_port); |
conn->initiator_port); |
Line 5393 worker(void *arg)
|
Line 5855 worker(void *arg)
|
//ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
//ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, |
// "Task Write Trans END\n"); |
// "Task Write Trans END\n"); |
|
|
|
MTX_LOCK(&lu_task->trans_mutex); |
lu_task->req_transfer_out = 0; |
lu_task->req_transfer_out = 0; |
|
|
/* need response after execution */ |
/* need response after execution */ |
Line 5400 worker(void *arg)
|
Line 5863 worker(void *arg)
|
if (conn->use_sender == 0) { |
if (conn->use_sender == 0) { |
conn->running_tasks++; |
conn->running_tasks++; |
} |
} |
MTX_UNLOCK(&lu_task->trans_mutex); |
|
|
|
rc = pthread_cond_broadcast(&lu_task->trans_cond); |
rc = pthread_cond_broadcast(&lu_task->trans_cond); |
|
MTX_UNLOCK(&lu_task->trans_mutex); |
if (rc != 0) { |
if (rc != 0) { |
//MTX_UNLOCK(&lu_task->trans_mutex); |
|
ISTGT_ERRLOG("cond_broadcast() failed\n"); |
ISTGT_ERRLOG("cond_broadcast() failed\n"); |
break; |
break; |
} |
} |
Line 5476 worker(void *arg)
|
Line 5938 worker(void *arg)
|
wait_all_task(conn); |
wait_all_task(conn); |
|
|
if (conn->use_sender) { |
if (conn->use_sender) { |
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "stop sender thread (%d)\n", conn->id); |
/* stop sender thread */ |
/* stop sender thread */ |
|
MTX_LOCK(&conn->result_queue_mutex); |
rc = pthread_cond_broadcast(&conn->result_queue_cond); |
rc = pthread_cond_broadcast(&conn->result_queue_cond); |
|
MTX_UNLOCK(&conn->result_queue_mutex); |
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("cond_broadcast() failed\n"); |
ISTGT_ERRLOG("cond_broadcast() failed\n"); |
/* ignore errors */ |
/* ignore errors */ |
Line 5509 worker(void *arg)
|
Line 5974 worker(void *arg)
|
} |
} |
|
|
int |
int |
istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen) | istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal, int sock, struct sockaddr *sa, socklen_t salen __attribute__((__unused__))) |
{ |
{ |
char buf[MAX_TMPBUF]; |
char buf[MAX_TMPBUF]; |
CONN_Ptr conn; |
CONN_Ptr conn; |
Line 5651 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
Line 6116 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
ISTGT_ERRLOG("istgt_set_sendtimeo() failed\n"); |
ISTGT_ERRLOG("istgt_set_sendtimeo() failed\n"); |
goto error_return; |
goto error_return; |
} |
} |
|
#if defined (ISTGT_USE_IOVEC) |
|
/* set low water mark */ |
|
rc = istgt_set_recvlowat(conn->sock, ISCSI_BHS_LEN); |
|
if (rc != 0) { |
|
ISTGT_ERRLOG("istgt_set_recvlowat() failed\n"); |
|
goto error_return; |
|
} |
|
#endif |
|
|
rc = pipe(conn->task_pipe); |
rc = pipe(conn->task_pipe); |
if (rc != 0) { |
if (rc != 0) { |
Line 5659 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
Line 6132 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
conn->task_pipe[1] = -1; |
conn->task_pipe[1] = -1; |
goto error_return; |
goto error_return; |
} |
} |
rc = pthread_mutex_init(&conn->task_queue_mutex, NULL); | rc = pthread_mutex_init(&conn->task_queue_mutex, &istgt->mutex_attr); |
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("mutex_init() failed\n"); |
ISTGT_ERRLOG("mutex_init() failed\n"); |
goto error_return; |
goto error_return; |
} |
} |
rc = pthread_mutex_init(&conn->result_queue_mutex, NULL); | rc = pthread_mutex_init(&conn->result_queue_mutex, &istgt->mutex_attr); |
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("mutex_init() failed\n"); |
ISTGT_ERRLOG("mutex_init() failed\n"); |
goto error_return; |
goto error_return; |
Line 5684 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
Line 6157 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
ISTGT_ERRLOG("cond_init() failed\n"); |
ISTGT_ERRLOG("cond_init() failed\n"); |
goto error_return; |
goto error_return; |
} |
} |
rc = pthread_mutex_init(&conn->r2t_mutex, NULL); | rc = pthread_mutex_init(&conn->r2t_mutex, &istgt->mutex_attr); |
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("mutex_init() failed\n"); |
ISTGT_ERRLOG("mutex_init() failed\n"); |
goto error_return; |
goto error_return; |
Line 5761 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
Line 6234 istgt_create_conn(ISTGT_Ptr istgt, PORTAL_Ptr portal,
|
istgt_iscsi_param_free(conn->params); |
istgt_iscsi_param_free(conn->params); |
istgt_queue_destroy(&conn->pending_pdus); |
istgt_queue_destroy(&conn->pending_pdus); |
istgt_queue_destroy(&conn->task_queue); |
istgt_queue_destroy(&conn->task_queue); |
|
istgt_queue_destroy(&conn->result_queue); |
xfree(conn->portal.label); |
xfree(conn->portal.label); |
xfree(conn->portal.host); |
xfree(conn->portal.host); |
xfree(conn->portal.port); |
xfree(conn->portal.port); |
Line 6388 istgt_get_active_conns(void)
|
Line 6862 istgt_get_active_conns(void)
|
return num; |
return num; |
} |
} |
|
|
|
int |
|
istgt_stop_conns(void) |
|
{ |
|
CONN_Ptr conn; |
|
char tmp[1]; |
|
int rc; |
|
int i; |
|
|
|
ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "istgt_stop_conns\n"); |
|
tmp[0] = 'E'; |
|
MTX_LOCK(&g_conns_mutex); |
|
for (i = 0; i < g_nconns; i++) { |
|
conn = g_conns[i]; |
|
if (conn == NULL) |
|
continue; |
|
rc = write(conn->task_pipe[1], tmp, 1); |
|
if(rc < 0 || rc != 1) { |
|
ISTGT_ERRLOG("write() failed\n"); |
|
/* ignore error */ |
|
} |
|
} |
|
MTX_UNLOCK(&g_conns_mutex); |
|
return 0; |
|
} |
|
|
CONN_Ptr |
CONN_Ptr |
istgt_find_conn(const char *initiator_port, const char *target_name, uint16_t tsih) |
istgt_find_conn(const char *initiator_port, const char *target_name, uint16_t tsih) |
{ |
{ |
Line 6463 istgt_iscsi_init(ISTGT_Ptr istgt)
|
Line 6962 istgt_iscsi_init(ISTGT_Ptr istgt)
|
} |
} |
|
|
int |
int |
istgt_iscsi_shutdown(ISTGT_Ptr istgt) | istgt_iscsi_shutdown(ISTGT_Ptr istgt __attribute__((__unused__))) |
{ |
{ |
CONN_Ptr conn; |
CONN_Ptr conn; |
int retry = 10; |
int retry = 10; |
Line 6515 istgt_iscsi_shutdown(ISTGT_Ptr istgt)
|
Line 7014 istgt_iscsi_shutdown(ISTGT_Ptr istgt)
|
if (rc != 0) { |
if (rc != 0) { |
ISTGT_ERRLOG("mutex_destroy() failed\n"); |
ISTGT_ERRLOG("mutex_destroy() failed\n"); |
return -1; |
return -1; |
|
} |
|
|
|
if (num == 0) { |
|
xfree(g_conns); |
|
g_conns = NULL; |
} |
} |
|
|
return 0; |
return 0; |