⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iscsi_main.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
    msg.msg_iovlen = 1;    /* set a timer, though we shouldn't really need one */    session->login_phase_timer = jiffies + (session->login_timeout * HZ);    mb();    if (LOG_ENABLED(ISCSI_LOG_LOGIN)) {        char *text = (char *)(pdu + 1);        char *end = text + ntoh24(pdu->dlength);        /* show the phases and tbit */        printk("iSCSI: session %p sending login pdu with current phase %d, next %d, tbit %d, dlength %d at %lu, timeout at %lu (%d seconds)\n",               session, pdu->curr, pdu->next, pdu->tbit, ntoh24(pdu->dlength), jiffies, session->login_phase_timer, session->login_timeout);        /* show all the text that we're sending */        while (text < end) {            printk("iSCSI: session %p login text: %s\n", session, text);            text += strlen(text);            while ((text < end) && (*text == '\0'))                text++;        }    }    rc = iscsi_sendmsg(session, &msg, pdu_length);    /* clear the timer */    session->login_phase_timer = 0;    mb();    if (rc != pdu_length) {        char *error;        if ((rc < 0) && (error = iscsi_strerror(-rc)) && (error[0] != '\0'))            printk("iSCSI: session %p failed to send login PDU, rc %d, %s\n", session, rc, iscsi_strerror(-rc));        else            printk("iSCSI: session %p failed to send login PDU, rc %d\n", session, rc);        return 0;    }    DEBUG_INIT5("iSCSI: session %p sent login pdu %p at %lu, length %d, dlength %d\n",                 session, pdu, jiffies, pdu_length, ntoh24(pdu->dlength));    return 1;}/* try to read an entire login PDU into the buffer, timing out after timeout seconds */int iscsi_recv_login_pdu(iscsi_session_t *session, struct IscsiLoginRspHdr *pdu, int max_pdu_length, int timeout){    struct msghdr msg;    struct iovec iov;    int rc = 0;    int pdu_length;    int ret = 0;    if (max_pdu_length < sizeof(*pdu)) {        printk("iSCSI: session %p, pdu %p max_pdu_length %d is too small to recv a login header\n",                session, pdu, max_pdu_length);        return 0;    }    /* set the timer to implement the timeout requested */    if (timeout)        session->login_phase_timer = jiffies + (timeout * HZ);    else        session->login_phase_timer = 0;    mb();    if (LOG_ENABLED(ISCSI_LOG_LOGIN)) {        printk("iSCSI: session %p trying to recv login pdu at %lu, timeout at %lu (%d seconds)\n",                session, jiffies, session->login_phase_timer, timeout);    }    /* read the PDU header */    memset(&iov, 0, sizeof(iov));    iov.iov_base = (void *)pdu;    iov.iov_len = sizeof(*pdu);    memset( &msg, 0, sizeof(struct msghdr) );    msg.msg_iov = &iov;    msg.msg_iovlen = 1;        rc = iscsi_recvmsg(session, &msg, sizeof(*pdu));    if (signal_pending(current)) {        printk("iSCSI: session %p recv_login_pdu timed out at %lu\n", session, jiffies);        goto done;    }        if (rc != sizeof(*pdu)) {        if (rc < 0) {            char *error = iscsi_strerror(-rc);            if (error && error[0] != '\0') {                printk("iSCSI: session %p recv_login_pdu failed to recv %d login PDU bytes, rc %d, %s\n",                        session, iov.iov_len, rc, iscsi_strerror(-rc));            }            else {                printk("iSCSI: session %p recv_login_pdu failed to recv %d login PDU bytes, rc %d\n",                        session, iov.iov_len, rc);            }        }        else if (rc == 0) {            printk("iSCSI: session %p recv_login_pdu: connection closed\n", session);        }        else {            /* short reads should be impossible unless a signal occured,             * which we already checked for.             */            printk("iSCSI: bug - session %p recv_login_pdu, short read %d of %d\n", session, rc, sizeof(*pdu));        }        goto done;    }    pdu_length = ntoh24(pdu->dlength);    if (pdu_length) {        char *nul = (char *)(pdu + 1);        /* check for buffer overflow */        if (pdu_length > (max_pdu_length - sizeof(*pdu))) {            printk("iSCSI: session %p recv_login_pdu can't read %d bytes of login PDU data, only %d bytes of buffer available\n",                   session, pdu_length, (max_pdu_length - sizeof(*pdu)));            goto done;        }        /* handle PDU padding */        if (pdu_length % PAD_WORD_LEN) {            int pad = PAD_WORD_LEN - (pdu_length % PAD_WORD_LEN);            pdu_length += pad;        }        /* make sure data + pad + NUL fits in the buffer */        if (pdu_length + sizeof(*pdu) + 1 >= max_pdu_length) {            printk("iSCSI: session %p recv_login_pdu failing, PDU size %d would overflow buffer size %d\n",                    session, pdu_length + sizeof(*pdu) + 1, max_pdu_length);            goto done;        }        /* read the PDU's text data payload */        memset(&iov, 0, sizeof(iov));        iov.iov_base = (void *)(pdu + 1);        iov.iov_len = max_pdu_length - sizeof(*pdu);        memset( &msg, 0, sizeof(struct msghdr) );        msg.msg_iov = &iov;        msg.msg_iovlen = 1;                rc = iscsi_recvmsg(session, &msg, pdu_length);        /* ensure NUL termination of the text */        nul += pdu_length;        *nul = '\0';                if (signal_pending(current)) {            printk("iSCSI: session %p recv_login_pdu timed out at %lu\n", session, jiffies);            goto done;        }                if (rc != pdu_length) {            if (rc < 0) {                char *error = iscsi_strerror(-rc);                if (error && error[0] != '\0') {                    printk("iSCSI: session %p recv_login_pdu failed to recv %d login data PDU bytes, rc %d, %s\n",                            session, pdu_length, rc, iscsi_strerror(-rc));                }                else {                    printk("iSCSI: session %p recv_login_pdu failed to recv %d login data PDU bytes, rc %d\n",                            session, pdu_length, rc);                }            }            else if (rc == 0) {                printk("iSCSI: session %p recv_login_pdu: connection closed\n", session);            }            else {                /* short reads should be impossible unless a signal occured,                 * which we already checked for.                 */                printk("iSCSI: bug - session %p recv_login_pdu, short read %d of %d\n", session, rc, pdu_length);            }            goto done;        }    }    if (LOG_ENABLED(ISCSI_LOG_LOGIN)) {        char *text = (char *)(pdu + 1);        char *end = text + ntoh24(pdu->dlength);        /* show the phases and tbit */        printk("iSCSI: session %p received login pdu response at %lu with current phase %d, next %d, tbit %d, dlength %d\n",               session, jiffies, pdu->curr, pdu->next, pdu->tbit, ntoh24(pdu->dlength));        /* show all the text that we're sending */        while (text < end) {            printk("iSCSI: session %p login resp text: %s\n", session, text);            text += strlen(text);            while ((text < end) && (*text == '\0'))                text++;        }    }        ret = 1;     done:        /* clear the timer */    session->login_phase_timer = 0;    mb();    iscsi_handle_signals(session);    return ret;}#if DEBUG_TRACEstatic voidiscsi_fill_trace(unsigned char type, Scsi_Cmnd *sc, iscsi_task_t *task, unsigned long data1, unsigned long data2){    iscsi_trace_entry_t *te;    DECLARE_NOQUEUE_FLAGS;    SPIN_LOCK_NOQUEUE(&iscsi_trace_lock);    te = &trace_table[trace_index];    trace_index++;    if ( trace_index >= ISCSI_TRACE_COUNT ) {        trace_index = 0;    }    memset(te, 0x0, sizeof(*te));    te->type = type;    if (sc) {        te->cmd = sc->cmnd[0];        te->host = sc->host->host_no;        te->channel = sc->channel;        te->target = sc->target;        te->lun = sc->lun;    }    if (task) {        te->itt = task->itt;    }    te->data1 = data1;    te->data2 = data2;    te->jiffies = jiffies;    SPIN_UNLOCK_NOQUEUE(&iscsi_trace_lock);}#endif/* FIXME: update for 16 byte CDBs, such as:   lock unlock cache 16   pre-fetch 16   read 16   rebuild 16   regenerate 16   synchronize cache 16   verify 16   write 16   write and verify 16   write same 16   xdwrite extended 16   Then increase ISCSI_MAX_CMD_LEN to 16 in iscsi.h.*//* FIXME: for that matter, check the existing list for correctness */static intiscsi_set_direction(iscsi_task_t *task){    if (task && task->scsi_cmnd)        switch (task->scsi_cmnd->cmnd[0]) {            case TEST_UNIT_READY:            case START_STOP:            case REZERO_UNIT:            case WRITE_FILEMARKS:            case SPACE:            case ERASE:            case ALLOW_MEDIUM_REMOVAL:                /* just control commands */                set_bit(ISCSI_TASK_CONTROL, &task->flags);                return ISCSI_TASK_CONTROL;            case WRITE_6:           case WRITE_10:          case WRITE_12:             case 0x8a: /* WRITE_16 */        case 0x8e: /* write and verify 16 */            case 0x93: /* write same 16 */            case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:            case WRITE_VERIFY:      case WRITE_VERIFY_12:            case COMPARE:           case COPY:              case COPY_VERIFY:            case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:            case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:            case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:            case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:            case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:            case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:            case WRITE_LONG_2:                set_bit(ISCSI_TASK_WRITE, &task->flags);                return ISCSI_TASK_WRITE;        default:            set_bit(ISCSI_TASK_READ, &task->flags);            return ISCSI_TASK_READ;    }        return -1;}/* tagged queueing */static voidiscsi_set_tag( Scsi_Cmnd *cmd, struct IscsiScsiCmdHdr *hdr ){    if ( cmd->device->tagged_supported ) {        switch( cmd->tag ) {            case HEAD_OF_QUEUE_TAG:                hdr->flags.attr = ISCSI_ATTR_HEAD_OF_QUEUE;                break;            case ORDERED_QUEUE_TAG:                hdr->flags.attr = ISCSI_ATTR_ORDERED;                break;            default:                hdr->flags.attr = ISCSI_ATTR_SIMPLE;                break;        }    }    else        hdr->flags.attr = ISCSI_ATTR_UNTAGGED;}void print_cmnd(Scsi_Cmnd *sc){    printk("iSCSI: Scsi_Cmnd %p to (%u %u %u %u), Cmd 0x%x\n"           "       done %p, scsi_done %p, host_scribble %p\n"           "       reqbuf %p, req_len %u\n"           "       buffer %p, bufflen %u\n"           "       use_sg %u, old_use_sg %u, sglist_len %u\n"           "       owner 0x%x, state  0x%x, eh_state 0x%x\n"           "       cmd_len %u, old_cmd_len %u, abort_reason 0x%x\n",           sc, sc->host->host_no, sc->channel, sc->target, sc->lun, sc->cmnd[0],           sc->done, sc->scsi_done, sc->host_scribble,            sc->request_buffer, sc->request_bufflen, sc->buffer, sc->bufflen,           sc->use_sg, sc->old_use_sg, sc->sglist_len,           sc->owner, sc->state, sc->eh_state,            sc->cmd_len, sc->old_cmd_len, sc->abort_reason);    if (sc->cmd_len >= 12)        printk("iSCSI: cdb %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",               sc->cmnd[0], sc->cmnd[1], sc->cmnd[2], sc->cmnd[3],               sc->cmnd[4], sc->cmnd[5], sc->cmnd[6], sc->cmnd[7],               sc->cmnd[8], sc->cmnd[9], sc->cmnd[10], sc->cmnd[11]);    else if (sc->cmd_len >= 8)        printk("iSCSI: cdb %02x%02x%02x%02x %02x%02x%02x%02x\n",               sc->cmnd[0], sc->cmnd[1], sc->cmnd[2], sc->cmnd[3],               sc->cmnd[4], sc->cmnd[5], sc->cmnd[6], sc->cmnd[7]);    else if (sc->cmd_len >= 6)        printk("iSCSI: cdb %02x%02x%02x%02x %02x%02x\n",               sc->cmnd[0], sc->cmnd[1], sc->cmnd[2], sc->cmnd[3],               sc->cmnd[4], sc->cmnd[5]);    else if (sc->cmd_len >= 4)        printk("iSCSI: cdb %02x%02x%02x%02x\n",               sc->cmnd[0], sc->cmnd[1], sc->cmnd[2], sc->cmnd[3]);    else if (sc->cmd_len >= 2)        printk("iSCSI: cdb %02x%02x\n", sc->cmnd[0], sc->cmnd[1]);    if (sc->use_sg && sc->request_buffer) {        struct scatterlist *sglist = (struct scatterlist *)sc->request_buffer;        int i;                for (i = 0; i < sc->use_sg; i++) {            printk("iSCSI: sglist %p[%02d] = addr %p, len %u\n",                    (struct scatterlist *)sc->request_buffer, i, sglist->address, sglist->length);            sglist++;        }    }}#ifdef DEBUG/* caller must hold the session's scsi_cmnd_lock */static void print_session_cmnds(iscsi_session_t *session){    Scsi_Cmnd *search = session->scsi_cmnd_head;    printk("iSCSI: session %p to %s unsent cmnd queue: head %p, tail %p, num %u\n",            session, session->log_name, session->scsi_cmnd_head, session->scsi_cmnd_tail,           atomic_read(&session->num_cmnds));    while (search) {        printk("iSCSI: session %p u cmnd %p: state %4x, eh_state %4x, scribble %p, Cmd 0x%x to (%u %u %u %u)\n",               session, search, search->state, search->eh_state, search->host_scribble,               search->cmnd[0], search->host->host_no, search->channel, search->target, search->lun);        search = (Scsi_Cmnd *)search->host_scribble;    }    printk("iSCSI: session %p to %s ignored cmnd queue: head %p, tail %p, num %u\n",            session, session->log_name, session->ignored_cmnd_head, session->ignored_cmnd_tail,           atomic_read(&session->num_ignored_cmnds));    search = session->ignored_cmnd_head;    while (search) {        printk("iSCSI: session %p i cmnd %p: state %4x, e

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -