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

📄 iscsi_client.c

📁 一个iSCSI协议实现源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                header.login_cmd.isid = s->isid;                header.login_cmd.tsid = s->tsid;                header.login_cmd.init_cmd_rn = s->cmd_rn++;                header.login_cmd.itt = s->itt;        }                iov.iov_base = &header;        iov.iov_len = sizeof(header);                /* ship the message */        // printk ("iscsi_client - iscsi_client_login() Sending login cmd\n");        if (iscsi_sendv (sock, &iov, 1) < 0) {                printk ("iscsi_client - iscsi_client_login() Failed to send login message\n");                return -1;        }                /* get a response */        // printk ("iscsi_client - iscsi_client_login() Reading login rsp\n");        if ((len = iscsi_read_header (sock, &header)) < 0) {                printk ("iscsi_client - iscsi_client_login() Failed to recieve login response\n");                return -1;        }        if (len > 0) {                printk ("iscsi_client - iscsi_client_login() Extra data during login\n");        }                if (header.login_rsp.op != ISCSI_OP_LOGIN_RSP) {                printk ("iscsi_client - iscsi_client_login() Bad response during login:\n");		printk ("iscsi_client - iscsi_client_login() rsp op: %d\n",header.login_rsp.op);                iscsi_print_header (&header);                return -1;        }                /* verify the target accepted our login */        if (header.login_rsp.status != ISCSI_LOGIN_ACCEPT) {                printk ("iscsi_client - iscsi_client_login() Login not accepted reason: %d\n",                        header.login_rsp.status);                return -1;        }                /* verify that we're using version 1         * (was 0, since the UNH implementations use 1, we'll use it too)         */        if (header.login_rsp.version_active != 1) {                printk ("iscsi_client - iscsi_client_login() Unsupported version rquested\n");                return -1;        }                /* make sure final flag bit is set */        if (!(header.login_rsp.F_reserved1 & ISCSI_F_BIT)) {                printk ("iscsi_client - iscsi_client_login() Login Response Final Bit not set\n");                return -1;        }                if (s->cmd_rn != header.login_rsp.exp_cmd_rn) {                printk ("iscsi_client - iscsi_client_login() Command out of order.  Recieved %d expecting %d\n",                         header.login_rsp.exp_cmd_rn,                        s->cmd_rn);        }                // printk ("iscsi_client - iscsi_client_login() Login Accepted\n");        /* should be all set, finish initializing... */                if (s->tsid == 0) {                 s->tsid = header.login_rsp.tsid;        }        s->connection[c_idx].stat_rn = header.login_rsp.init_stat_rn;        s->max_cmd_rn = header.login_rsp.max_cmd_rn;        s->connection[c_idx].in_use = TRUE;        s->connection[c_idx].s = s;        /* we need an extra thread to handle reading */        // printk ("iscsi_client - iscsi_client_login() Creating reader thread for (%p)\n", &s->connection[c_idx]);        s->connection[c_idx].reader =                 kernel_thread(iscsi_client_reader, &s->connection[c_idx],                               CLONE_FS | CLONE_FILES | CLONE_SIGHAND);                if (s->connection[c_idx].reader <= 1) {                printk ("iscsi_client - iscsi_client_login() Error during thread creation\n");                return -1;        }        // printk ("iscsi_client - PID %d iscsi_client_login(%p,%d) EXIT\n", current->pid, s, c_idx);        return 0;}static int iscsi_client_reader(void *connection){        s32 len;        iscsi_header_t hdr;        iscsi_connection_t *c = connection;        struct sock *sk;        // printk ("iscsi_client - PID %d iscsi_client_reader(%p) ENTRY\n", current->pid, c);        sk = c->sock->sk;        while (1) {                if (!c->in_use) {                        printk ("iscsi_client - iscsi_client_reader() reader_thread on unused connection\n");                        return -1;                }                if (sk->state != TCP_ESTABLISHED &&                     sk->state != TCP_CLOSE_WAIT) {                        printk ("iscsi_client - iscsi_client_reader() abnormal connection teardown\n");                        iscsi_close_connection (c);                        return -1;                }                if ( skb_queue_empty(&(sk->receive_queue)) ) {                        /* nothing to do, wait on tcp.  This is mostly grabbed                         * from tcp_data_wait() which is not globally defined.                         * I'm paranoid about blocking on a read, so we'll                         * wait on tcp's sleep queue                          */                        DECLARE_WAITQUEUE(wait, current);                        // printk ("iscsi_client - iscsi_client_reader() no data, going to sleep\n");                        lock_sock(sk);                        add_wait_queue(sk->sleep, &wait);                        set_current_state(TASK_INTERRUPTIBLE);                        set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);                        release_sock(sk);                        schedule();                        lock_sock(sk);                        clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);                        remove_wait_queue(sk->sleep, &wait);                        set_current_state(TASK_RUNNING);                        release_sock(sk);                        // printk ("iscsi_client - iscsi_client_reader() WOKEN UP!\n");                } else {                                                /* if we manage to get here, that means                         * the connection has some data                         * waiting to be read from                         * its socket.  We'll read a header                         * and then call the dispatcher                         */                                        if ((len=iscsi_read_header(c->sock, &hdr)) >= 0) {                                iscsi_client_dispatch (c, hdr, len);                        }                }        }}static int iscsi_client_dispatch (iscsi_connection_t *c, iscsi_header_t hdr, s32 bytes_to_read){        s32 bytes_read = 0;        unsigned long int flags;        s32 current_write;        s32 total_written = 0;        struct scatterlist *sg_lst;        int sg_off;        int write_off;        int sg_cnt;        iscsi_header_t rsp;        struct iovec iov[ISCSI_CLIENT_SG_TABLE_SIZE + 4];        u16 num_iov;        s32 bytes_to_write;        iscsi_session_t *s = c->s;        // printk ("iscsi_client - PID %d iscsi_client_dispatch(%p,_,%d) ENTRY\n", current->pid, c, bytes_to_read);        /* ok let's parse the header and figure out what to do */        switch (hdr.scsi_cmd.op) {                case ISCSI_OP_NOP_IN:                        printk ("iscsi_client - I don't know how to handle"                                " NOP_IN yet\n");                        if (bytes_to_read != 0) {                                printk ("iscsi_client - Leftover bytes in"                                        " NOP_IN %d\n", bytes_to_read);                                while (bytes_to_read) {                                        if ((bytes_read = iscsi_read (c->sock, scratch_pad, bytes_to_read)) == -1) {                                                break;                                        }                                        bytes_to_read -= bytes_read;                                }                                return -1;                        }                        return 0;                        break;                                        case ISCSI_OP_SCSI_RSP:                         // printk ("iscsi_client - iscsi_client_dispatch() - RX SCSI_RSP\n");                        s->current_command->result = hdr.scsi_rsp.status;                        s->current_command->resid = hdr.scsi_rsp.resid_cnt;                        // printk ("iscsi_client - iscsi_client_dispatch() - Processing rsp buf %p\n", s->current_command->request_buffer);                                                /* DUMP_DATA (s->current_command->request_buffer, s->current_command->request_bufflen); */                        if ((hdr.scsi_rsp.status & STATUS_MASK) != GOOD) {                                printk ("iscsi_client - iscsi_client_dispatch() - BAD STATUS on RX\n");                                if (bytes_to_read != hdr.scsi_rsp.sense_len) {                                        printk ("iscsi_client - sense_length != length in SCSI_RSP\n");                                }                                if (bytes_to_read > SCSI_SENSE_BUFFERSIZE) {                                        printk ("iscsi_client - sense_length > SCSI_SENSE_BUFFERSIZE\n");                                        iscsi_read (c->sock,                                                     s->current_command->sense_buffer,                                                     SCSI_SENSE_BUFFERSIZE);                                        iscsi_read (c->sock, scratch_pad,                                                     bytes_to_read - SCSI_SENSE_BUFFERSIZE);                                } else {                                        iscsi_read (c->sock,                                                     s->current_command->sense_buffer,                                                     bytes_to_read);                                }                        }                        // printk ("iscsi_client - iscsi_client_dispatch() - calling done()\n");                        spin_lock_irqsave(&io_request_lock, flags);                        s->current_command->scsi_done(s->current_command);                        spin_unlock_irqrestore(&io_request_lock, flags);                        // printk ("iscsi_client - iscsi_client_dispatch() - done() returned\n");                        return 0;                        break;                case ISCSI_OP_TASK_RSP:                        printk ("iscsi_client - I don't know how to handle"                                " TASK_RSP yet\n");                        if (bytes_to_read != 0) {                                printk ("iscsi_client - Leftover bytes in"                                        " TASK_RSP %d\n", bytes_to_read);                                while (bytes_to_read) {                                        if ((bytes_read = iscsi_read (c->sock, scratch_pad, bytes_to_read)) == -1) {                                                break;                                        }                                        bytes_to_read -= bytes_read;                                }                                return -1;                        }                        return 0;                        break;                case ISCSI_OP_LOGIN_RSP:                        printk ("iscsi_client - Recieved LOGIN_RSP during"                                "full feature phase\n");                        if (bytes_to_read != 0) {                                printk ("iscsi_client - Leftover bytes in"                                        " LOGIN_RSP %d\n", bytes_to_read);                                while (bytes_to_read) {                                        if ((bytes_read = iscsi_read (c->sock, scratch_pad, bytes_to_read)) == -1) {                                                break;                                        }                                        bytes_to_read -= bytes_read;                                }                        }                        return -1;                        break;                case ISCSI_OP_TEXT_RSP:                        printk ("iscsi_client - I don't know how to handle"                                " TEXT_RSP yet\n");                        if (bytes_to_read != 0) {                                printk ("iscsi_client - Leftover bytes in"                                        " TEXT_RSP %d\n", bytes_to_read);                                while (bytes_to_read) {                                        if ((bytes_read = iscsi_read (c->sock, scratch_pad, bytes_to_read)) == -1) {                                                break;                                        }                                        bytes_to_read -= bytes_read;                                }                                return -1;                        }                        return 0;                        break;                case ISCSI_OP_READ_DATA:                        /* we're not setting the P-bit in the flags field so we don't need to bother with                         * ttt.  The spec doesnt say if this should be all zeros or all ones like it should                          * be if its not used when recieving an R2T message.  We'll assume all 1's for now.                         * Data numbering is optional, and since we don't support NOP messages yet                         * we won't support Data numbering                         */                        /* for now we'll ignore just about everything except what we really need */

⌨️ 快捷键说明

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