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

📄 iscsi.c

📁 一个iSCSI协议实现源代码
💻 C
字号:
/*  *  $Id: iscsi.c,v 1.11 2001/04/24 05:49:09 mbrown Exp $ * *  iscsi.c implements a few utility functions used by both iscsi_client *  and si. *  Copyright (C) 2001 Michael F. Brown (mbrown@cs.uml.edu) *  *  Changes : * *  $Log: iscsi.c,v $ *  Revision 1.11  2001/04/24 05:49:09  mbrown *  verbose error messages commented for now * *  Revision 1.10  2001/04/23 23:41:39  mbrown *  fixed bugs * *  Revision 1.9  2001/04/21 04:07:01  mbrown *  more bug fixing, mount readonly works, use the new DISK file, it *  contains a valid ext2 partition * *  Revision 1.8  2001/04/20 03:35:01  mbrown *  lun bug fixed, debug prints in big endian order * *  Revision 1.7  2001/04/19 15:16:50  mbrown *  devices now show up, fdisk still causes a kernel panic, *  checkin per jhawkins' request * *  Revision 1.6  2001/04/18 07:52:43  mbrown *  minor cleanup * *  Revision 1.4  2001/04/06 04:07:37  mbrown *  bug fix having to do with byte ordering fixed.  Added lots of debug *  prints in iscsi_client.c now that I can start testing * *  Revision 1.3  2001/04/03 09:44:58  mbrown *  iscsi.o and iscsi_client.o now successfully compile. * *  Revision 1.2  2001/03/02 22:58:56  mbrown *  name of iscsi_send changed to iscsi_sendv to look more like unix *  functions readv() and writev(). * *  Revision 1.1  2001/03/02 08:39:13  mbrown *  initial revision * * * *  This program is free software; you can redistribute it and/or modify it *  under the terms of the GNU General Public License as published by the *  Free Software Foundation; either version 2, or (at your option) any *  later version. * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/types.h>#include <linux/net.h>#include <linux/uio.h>#include <linux/socket.h>#include <linux/signal.h>#include <linux/spinlock.h>#include <linux/sched.h>#include <linux/blkdev.h>#include <asm/processor.h>#include <asm/uaccess.h>#include <linux/byteorder/generic.h>#include "iscsi.h"#define ASSERT(cond) { if (!(cond)) { printk ("iscsi_client - ASSERT FAILED " \                       "%s:%d\n", __FILE__, __LINE__); } }static __inline__ iscsi_header_t cpu_to_be_iscsi (iscsi_header_t hdr); static __inline__ iscsi_header_t be_to_cpu_iscsi (iscsi_header_t hdr); void iscsi_print_header (void *hdr){        register int i;        unsigned char *buf=hdr;        // printk ("iscsi - PID %d iscsi_print_header(%p) ENTRY\n", current->pid, hdr);        for (i=0; i<ISCSI_HDR_SIZE; i++) {                if (i % 4 == 0) {                        printk ("\n\t- 0x");                }                printk ("%02x", buf[i]);        }        printk ("\n");        // printk ("iscsi - PID %d iscsi_print_header(%p) EXIT\n", current->pid, hdr);}s32 iscsi_sendv (struct socket *sock, struct iovec *iov, u32 num_iov) {        struct msghdr msg;        mm_segment_t oldfs;        sigset_t oldset;        iscsi_header_t hdr;        s32 length_sent;        u32 total_length = 0;        u32 flags;        u32 i;	// printk ("iscsi - PID %d iscsi_sendv(%p,%p,%d) ENTRY\n", current->pid, sock, iov, num_iov);        hdr = cpu_to_be_iscsi ( *((iscsi_header_t *)(iov[0].iov_base)) );        iov[0].iov_base = &hdr;        //printk ("iscsi_sendv() TX header:\n");        //iscsi_print_header(&hdr);        msg.msg_name = NULL;        msg.msg_namelen = 0;        msg.msg_iov = iov;        msg.msg_iovlen = num_iov;        msg.msg_control = NULL;        msg.msg_controllen = 0;        msg.msg_flags = 0;            for (i=0; i<num_iov; i++) {                total_length += iov[i].iov_len;        }                oldfs = get_fs(); set_fs(KERNEL_DS);        spin_lock_irqsave(&current->sigmask_lock, flags);        oldset = current->blocked;        sigfillset(&current->blocked);        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);              length_sent = sock_sendmsg(sock,&msg,total_length);                 spin_lock_irqsave(&current->sigmask_lock, flags);        current->blocked = oldset;        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);          set_fs(oldfs);        if (length_sent < 0) {                printk ("iscsi - iscsi_sendv() Failed to write message: %d\n", length_sent);        }        if (length_sent != total_length) {                // printk ("iscsi - iscsi_sendv() SHORT WRITE!!\n");        }	// printk ("iscsi - PID %d iscsi_sendv(%p,%p,%d) EXIT\n", current->pid, sock, iov, num_iov);        return length_sent;}s32 iscsi_read_header (struct socket *sock, iscsi_header_t *hdr) {        struct msghdr msg;	struct iovec iov;        mm_segment_t oldfs;        sigset_t oldset;        s32 length_recv;        u32 flags;	// printk ("iscsi - PID %d iscsi_read_header(%p,%p) ENTRY\n", current->pid, sock, hdr);        iov.iov_base = hdr;        iov.iov_len = ISCSI_HDR_SIZE;        msg.msg_name = NULL;        msg.msg_namelen = 0;        msg.msg_iov = &iov;        msg.msg_iovlen = 1;        msg.msg_control = NULL;        msg.msg_controllen = 0;        msg.msg_flags = 0;        oldfs = get_fs(); set_fs(KERNEL_DS);        spin_lock_irqsave(&current->sigmask_lock, flags);        oldset = current->blocked;        sigfillset(&current->blocked);        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);              length_recv = sock_recvmsg(sock, &msg, ISCSI_HDR_SIZE, /*MSG_DONTWAIT*/ 0);                 spin_lock_irqsave(&current->sigmask_lock, flags);        current->blocked = oldset;        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);          set_fs(oldfs);        if (length_recv < 0) {                printk ("iscsi - iscsi_read_header() Failed to read message %d\n", length_recv);        }        if (length_recv != ISCSI_HDR_SIZE) {                printk ("iscsi - iscsi_read_header() PARTIAL HEADER READ!!!\n");                return -1;        }        //printk ("iscsi_read_hdr() RX header:\n");        //iscsi_print_header(hdr);        *hdr = be_to_cpu_iscsi (*hdr);	// printk ("iscsi - PID %d iscsi_read_header(%p,%p) EXIT\n", current->pid, sock, hdr);        return hdr->scsi_cmd.len; /* len is always in the same place */}s32 iscsi_read (struct socket *sock, void *buf, u32 len){        struct msghdr msg;	struct iovec iov;        mm_segment_t oldfs;        sigset_t oldset;        s32 length_recv;        u32 flags;        // printk ("iscsi - PID %d iscsi_read(%p,%p,%d) ENTRY\n", current->pid, sock, buf, len);        iov.iov_base = buf;        iov.iov_len = len;        msg.msg_name = NULL;        msg.msg_namelen = 0;        msg.msg_iov = &iov;        msg.msg_iovlen = 1;        msg.msg_control = NULL;        msg.msg_controllen = 0;        msg.msg_flags = 0;        oldfs = get_fs(); set_fs(KERNEL_DS);        spin_lock_irqsave(&current->sigmask_lock, flags);        oldset = current->blocked;        sigfillset(&current->blocked);        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);              length_recv = sock_recvmsg(sock, &msg, len, /*MSG_DONTWAIT*/ 0);                 spin_lock_irqsave(&current->sigmask_lock, flags);        current->blocked = oldset;        recalc_sigpending(current);        spin_unlock_irqrestore(&current->sigmask_lock, flags);          set_fs(oldfs);        if (length_recv < 0) {                printk ("iscsi - iscsi_read() Failed to read message %d\n", length_recv);        }        if (length_recv != len) {                // printk ("iscsi - iscsi_read() SHORT READ!!!!!\n");        }        // printk ("iscsi - PID %d iscsi_read(%p,%p,%d) EXIT\n", current->pid, sock, buf, len);        return length_recv;}static __inline__ iscsi_header_t cpu_to_be_iscsi (iscsi_header_t hdr){        switch (hdr.op) {                /*case ISCSI_OP_NOP_OUT:                hdr.nop_out.len = cpu_to_be32(hdr.nop_out.len);                hdr.nop_out.lun = cpu_to_be64(hdr.nop_out.lun);                hdr.nop_out.itt = cpu_to_be32(hdr.nop_out.itt);                hdr.nop_out.ttt = cpu_to_be32(hdr.nop_out.ttt);                hdr.nop_out.cmd_rn = cpu_to_be32(hdr.nop_out.cmd_rn);                hdr.nop_out.exp_stat_rn = cpu_to_be32(hdr.nop_out.exp_stat_rn);                hdr.nop_out.exp_data_rn = cpu_to_be32(hdr.nop_out.exp_data_rn);                return hdr;*/            case ISCSI_OP_SCSI_CMD:                hdr.scsi_cmd.len = cpu_to_be32(hdr.scsi_cmd.len);                hdr.scsi_cmd.lun = cpu_to_be64(hdr.scsi_cmd.lun);                hdr.scsi_cmd.itt = cpu_to_be32(hdr.scsi_cmd.itt);                hdr.scsi_cmd.exp_data_len = cpu_to_be32(hdr.scsi_cmd.exp_data_len);                hdr.scsi_cmd.cmd_rn = cpu_to_be32(hdr.scsi_cmd.cmd_rn);                hdr.scsi_cmd.exp_stat_rn = cpu_to_be32(hdr.scsi_cmd.exp_stat_rn);                return hdr;            case ISCSI_OP_LOGIN_CMD:                hdr.login_cmd.len = cpu_to_be32 (hdr.login_cmd.len);                hdr.login_cmd.cid = cpu_to_be16 (hdr.login_cmd.cid);                hdr.login_cmd.isid = cpu_to_be16 (hdr.login_cmd.isid);                hdr.login_cmd.tsid = cpu_to_be16 (hdr.login_cmd.tsid);                hdr.login_cmd.itt = cpu_to_be32 (hdr.login_cmd.itt);                hdr.login_cmd.init_cmd_rn = cpu_to_be32 (hdr.login_cmd.init_cmd_rn);                return hdr;            case ISCSI_OP_WRITE_DATA:                hdr.scsi_write.len = cpu_to_be32 (hdr.scsi_write.len);                hdr.scsi_write.lun = cpu_to_be64 (hdr.scsi_write.lun);                hdr.scsi_write.itt = cpu_to_be32 (hdr.scsi_write.itt);                hdr.scsi_write.ttt = cpu_to_be32 (hdr.scsi_write.ttt);                hdr.scsi_write.exp_stat_rn = cpu_to_be32 (hdr.scsi_write.exp_stat_rn);                hdr.scsi_write.buf_offset = cpu_to_be32 (hdr.scsi_write.buf_offset);                return hdr;            case ISCSI_OP_TASK_CMD:            case ISCSI_OP_TEXT_CMD:            case ISCSI_OP_LOGOUT_CMD:            case ISCSI_OP_SACK_REQ:            default:                    printk ("iscsi - hton - Unimplemented Byte Conversion\n");        }        return hdr;}static __inline__ iscsi_header_t be_to_cpu_iscsi (iscsi_header_t hdr){        switch (hdr.op) {            case ISCSI_OP_SCSI_RSP:                hdr.scsi_rsp.len = be32_to_cpu(hdr.scsi_rsp.len);                hdr.scsi_rsp.itt = be32_to_cpu(hdr.scsi_rsp.itt);                hdr.scsi_rsp.resid_cnt = be32_to_cpu(hdr.scsi_rsp.resid_cnt);                hdr.scsi_rsp.stat_rn = be32_to_cpu(hdr.scsi_rsp.stat_rn);                hdr.scsi_rsp.exp_cmd_rn = be32_to_cpu(hdr.scsi_rsp.exp_cmd_rn);                hdr.scsi_rsp.max_cmd_rn = be32_to_cpu(hdr.scsi_rsp.max_cmd_rn);                hdr.scsi_rsp.sense_len = be16_to_cpu(hdr.scsi_rsp.sense_len);                hdr.scsi_rsp.bidi_resid_cnt = be32_to_cpu(hdr.scsi_rsp.bidi_resid_cnt);                return hdr;            case ISCSI_OP_LOGIN_RSP:                hdr.login_rsp.len = be32_to_cpu (hdr.login_rsp.len);                hdr.login_rsp.isid = be16_to_cpu (hdr.login_rsp.isid);                hdr.login_rsp.tsid = be16_to_cpu (hdr.login_rsp.tsid);                hdr.login_rsp.itt = be32_to_cpu (hdr.login_rsp.itt);                hdr.login_rsp.init_stat_rn = be32_to_cpu (hdr.login_rsp.init_stat_rn);                hdr.login_rsp.exp_cmd_rn = be32_to_cpu (hdr.login_rsp.exp_cmd_rn);                hdr.login_rsp.max_cmd_rn = be32_to_cpu (hdr.login_rsp.max_cmd_rn);                return hdr;            case ISCSI_OP_READ_DATA:                hdr.scsi_read.len = be32_to_cpu (hdr.scsi_read.len);                hdr.scsi_read.itt = be32_to_cpu (hdr.scsi_read.itt);                hdr.scsi_read.ttt = be32_to_cpu (hdr.scsi_read.ttt);                hdr.scsi_read.data_rn_stat_rn = be32_to_cpu (hdr.scsi_read.data_rn_stat_rn);                hdr.scsi_read.exp_cmd_rn = be32_to_cpu (hdr.scsi_read.exp_cmd_rn);                hdr.scsi_read.max_cmd_rn = be32_to_cpu (hdr.scsi_read.max_cmd_rn);                hdr.scsi_read.buf_offset = be32_to_cpu (hdr.scsi_read.buf_offset);                hdr.scsi_read.resid_cnt = be32_to_cpu (hdr.scsi_read.resid_cnt);                return hdr;            case ISCSI_OP_R2T:                hdr.r2t.len = be32_to_cpu (hdr.r2t.len);                hdr.r2t.itt = be32_to_cpu (hdr.r2t.itt);                hdr.r2t.ttt = be32_to_cpu (hdr.r2t.ttt);                hdr.r2t.exp_cmd_rn = be32_to_cpu (hdr.r2t.exp_cmd_rn);                hdr.r2t.max_cmd_rn = be32_to_cpu (hdr.r2t.max_cmd_rn);                hdr.r2t.desired_data_len = be32_to_cpu (hdr.r2t.desired_data_len);                hdr.r2t.buf_offset = be32_to_cpu (hdr.r2t.buf_offset);                return hdr;            case ISCSI_OP_NOP_IN:            case ISCSI_OP_TASK_RSP:            case ISCSI_OP_TEXT_RSP:            case ISCSI_OP_LOGOUT_RSP:            case ISCSI_OP_ASYNC_EVENT:            case ISCSI_OP_REJECT:            default:                printk ("iscsi - ntoh - Unimplemented Byte Conversion\n");        }        return hdr;}/* Module linkage */MODULE_AUTHOR("mbrown");MODULE_DESCRIPTION("iSCSI core");/* We probably won't have any parameters to a modprobe, at least not now *//*MODULE_PARM(def_reserved_size, "n/a");  MODULE_PARM_DESC(def_reserved_size, "n/a");*//* Here are the init functions that get called */static int __init iscsi_init(void) {    // printk("iscsi - PID %d iscsi_init() ENTRY\n", current->pid);    ASSERT (ISCSI_HDR_SIZE == 48);    return 0;}static void __exit iscsi_exit(void){    // printk("iscsi - PID %d iscsi_exit() ENTRY\n", current->pid);}module_init(iscsi_init);module_exit(iscsi_exit);

⌨️ 快捷键说明

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