📄 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(¤t->sigmask_lock, flags); oldset = current->blocked; sigfillset(¤t->blocked); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); length_sent = sock_sendmsg(sock,&msg,total_length); spin_lock_irqsave(¤t->sigmask_lock, flags); current->blocked = oldset; recalc_sigpending(current); spin_unlock_irqrestore(¤t->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(¤t->sigmask_lock, flags); oldset = current->blocked; sigfillset(¤t->blocked); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); length_recv = sock_recvmsg(sock, &msg, ISCSI_HDR_SIZE, /*MSG_DONTWAIT*/ 0); spin_lock_irqsave(¤t->sigmask_lock, flags); current->blocked = oldset; recalc_sigpending(current); spin_unlock_irqrestore(¤t->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(¤t->sigmask_lock, flags); oldset = current->blocked; sigfillset(¤t->blocked); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); length_recv = sock_recvmsg(sock, &msg, len, /*MSG_DONTWAIT*/ 0); spin_lock_irqsave(¤t->sigmask_lock, flags); current->blocked = oldset; recalc_sigpending(current); spin_unlock_irqrestore(¤t->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 + -