Diff for /embedaddon/istgt/src/istgt_iscsi.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/10/09 09:13:23 version 1.1.1.3, 2013/07/21 23:49:22
Line 117  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 376  istgt_iscsi_write(CONN_Ptr conn, const void *buf, size Line 384  istgt_iscsi_write(CONN_Ptr conn, const void *buf, size
 #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 417  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 447  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 471  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 497  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 540  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 577  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 611  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 619  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_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_Ptr pdu, int req_type, int I_bit);
   
Line 787  istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_P Line 985  istgt_iscsi_write_pdu_queue(CONN_Ptr conn, ISCSI_PDU_P
         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 843  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 860  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 875  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 909  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 926  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 949  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 962  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 3239  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 3269  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 5162  worker(void *arg) Line 5484  worker(void *arg)
                 return NULL;                  return NULL;
         }          }
         conn->kq = kq;          conn->kq = kq;
   #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);          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");
Line 5351  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 5788  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) {

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>