From 522a0eb1fcf3a6d47b86aa400494e488160cc5b1 Mon Sep 17 00:00:00 2001
From: Stefan Bader <stefan.bader@canonical.com>
Date: Wed, 22 Jun 2011 10:51:54 +0200
Subject: [PATCH] UBUNTU: SAUCE: iscsitarget: Remove driver from the kernel
This driver is not boot/install essential and is provided by the
iscsitarget-dkms package. Having it in the kernel itself only
duplicates code and adds a chance of getting out of sync.
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
---
debian.master/config/config.common.ubuntu | 1 -
ubuntu/Kconfig | 4 -
ubuntu/Makefile | 4 -
ubuntu/iscsitarget/BOM | 2 -
ubuntu/iscsitarget/Kconfig | 3 -
ubuntu/iscsitarget/Makefile | 17 -
ubuntu/iscsitarget/block-io.c | 327 -----
ubuntu/iscsitarget/compat.h | 30 -
ubuntu/iscsitarget/config.c | 362 ------
ubuntu/iscsitarget/conn.c | 262 ----
ubuntu/iscsitarget/digest.c | 279 ----
ubuntu/iscsitarget/digest.h | 20 -
ubuntu/iscsitarget/event.c | 96 --
ubuntu/iscsitarget/file-io.c | 261 ----
ubuntu/iscsitarget/include/iet_u.h | 151 ---
ubuntu/iscsitarget/iotype.c | 110 --
ubuntu/iscsitarget/iotype.h | 42 -
ubuntu/iscsitarget/iscsi.c | 1967 -----------------------------
ubuntu/iscsitarget/iscsi.h | 524 --------
ubuntu/iscsitarget/iscsi_dbg.h | 137 --
ubuntu/iscsitarget/iscsi_hdr.h | 509 --------
ubuntu/iscsitarget/nthread.c | 790 ------------
ubuntu/iscsitarget/null-io.c | 98 --
ubuntu/iscsitarget/param.c | 205 ---
ubuntu/iscsitarget/session.c | 180 ---
ubuntu/iscsitarget/target.c | 374 ------
ubuntu/iscsitarget/target_disk.c | 589 ---------
ubuntu/iscsitarget/tio.c | 121 --
ubuntu/iscsitarget/ua.c | 176 ---
ubuntu/iscsitarget/volume.c | 422 ------
ubuntu/iscsitarget/wthread.c | 258 ----
31 files changed, 0 insertions(+), 8321 deletions(-)
delete mode 100644 ubuntu/iscsitarget/BOM
delete mode 100644 ubuntu/iscsitarget/Kconfig
delete mode 100644 ubuntu/iscsitarget/Makefile
delete mode 100644 ubuntu/iscsitarget/block-io.c
delete mode 100644 ubuntu/iscsitarget/compat.h
delete mode 100644 ubuntu/iscsitarget/config.c
delete mode 100644 ubuntu/iscsitarget/conn.c
delete mode 100644 ubuntu/iscsitarget/digest.c
delete mode 100644 ubuntu/iscsitarget/digest.h
delete mode 100644 ubuntu/iscsitarget/event.c
delete mode 100644 ubuntu/iscsitarget/file-io.c
delete mode 100644 ubuntu/iscsitarget/include/iet_u.h
delete mode 100644 ubuntu/iscsitarget/iotype.c
delete mode 100644 ubuntu/iscsitarget/iotype.h
delete mode 100644 ubuntu/iscsitarget/iscsi.c
delete mode 100644 ubuntu/iscsitarget/iscsi.h
delete mode 100644 ubuntu/iscsitarget/iscsi_dbg.h
delete mode 100644 ubuntu/iscsitarget/iscsi_hdr.h
delete mode 100644 ubuntu/iscsitarget/nthread.c
delete mode 100644 ubuntu/iscsitarget/null-io.c
delete mode 100644 ubuntu/iscsitarget/param.c
delete mode 100644 ubuntu/iscsitarget/session.c
delete mode 100644 ubuntu/iscsitarget/target.c
delete mode 100644 ubuntu/iscsitarget/target_disk.c
delete mode 100644 ubuntu/iscsitarget/tio.c
delete mode 100644 ubuntu/iscsitarget/ua.c
delete mode 100644 ubuntu/iscsitarget/volume.c
delete mode 100644 ubuntu/iscsitarget/wthread.c
@@ -4156,7 +4156,6 @@ CONFIG_SCSI_IN2000=m
CONFIG_SCSI_INIA100=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_IPS=m
-# CONFIG_SCSI_ISCSITARGET is not set
CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_IZIP_EPP16 is not set
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
@@ -34,10 +34,6 @@ source "ubuntu/omnibook/Kconfig"
##
##
##
-source "ubuntu/iscsitarget/Kconfig"
-##
-##
-##
source "ubuntu/rtl8192se/Kconfig"
##
##
@@ -36,10 +36,6 @@ obj-$(CONFIG_NDISWRAPPER) += ndiswrapper/
##
##
##
-obj-$(CONFIG_SCSI_ISCSITARGET) += iscsitarget/
-##
-##
-##
obj-$(CONFIG_RTL8192SE) += rtl8192se/
##
##
deleted file mode 100644
@@ -1,2 +0,0 @@
-Downloaded from: http://sourceforge.net/projects/iscsitarget/files/
-Current Version: 1.4.20.2
deleted file mode 100644
@@ -1,3 +0,0 @@
-config SCSI_ISCSITARGET
- tristate "iSCSI Target Driver"
- depends on SCSI
deleted file mode 100644
@@ -1,17 +0,0 @@
-#
-# Makefile for the Linux kernel device drivers.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile.
-
-EXTRA_CFLAGS += -I$(src)/include
-
-obj-m += iscsi_trgt.o
-iscsi_trgt-objs := tio.o iscsi.o nthread.o wthread.o config.o digest.o \
- conn.o session.o target.o volume.o iotype.o \
- file-io.o null-io.o target_disk.o event.o param.o \
- block-io.o ua.o
-
deleted file mode 100644
@@ -1,327 +0,0 @@
-/*
- * Target device block I/O.
- *
- * Based on file I/O driver from FUJITA Tomonori
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * (C) 2006 Andre Brinkmann <brinkman at hni dot upb dot de>
- * (C) 2007 Ross Walker <rswwalker at hotmail dot com>
- * (C) 2007 Ming Zhang <blackmagic02881 at gmail dot com>
- * This code is licenced under the GPL.
- */
-
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/parser.h>
-#include <linux/buffer_head.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-struct blockio_data {
- char *path;
- struct block_device *bdev;
-};
-
-struct tio_work {
- atomic_t error;
- atomic_t bios_remaining;
- struct completion tio_complete;
-};
-
-static void blockio_bio_endio(struct bio *bio, int error)
-{
- struct tio_work *tio_work = bio->bi_private;
-
- error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
-
- if (error)
- atomic_set(&tio_work->error, error);
-
- /* If last bio signal completion */
- if (atomic_dec_and_test(&tio_work->bios_remaining))
- complete(&tio_work->tio_complete);
-
- bio_put(bio);
-}
-
-/*
- * Blockio_make_request(): The function translates an iscsi-request into
- * a number of requests to the corresponding block device.
- */
-static int
-blockio_make_request(struct iet_volume *volume, struct tio *tio, int rw)
-{
- struct blockio_data *bio_data = volume->private;
- struct request_queue *bdev_q = bdev_get_queue(bio_data->bdev);
- struct tio_work *tio_work;
- struct bio *tio_bio = NULL, *bio = NULL, *biotail = NULL;
-
- u32 offset = tio->offset;
- u32 size = tio->size;
- u32 tio_index = 0;
-
- int max_pages = 1;
- int err = 0;
-
- loff_t ppos = ((loff_t) tio->idx << PAGE_SHIFT) + offset;
-
- /* Calculate max_pages for bio_alloc (memory saver) */
- if (bdev_q)
- max_pages = bio_get_nr_vecs(bio_data->bdev);
-
- tio_work = kzalloc(sizeof (*tio_work), GFP_KERNEL);
- if (!tio_work)
- return -ENOMEM;
-
- atomic_set(&tio_work->error, 0);
- atomic_set(&tio_work->bios_remaining, 0);
- init_completion(&tio_work->tio_complete);
-
- /* Main processing loop, allocate and fill all bios */
- while (tio_index < tio->pg_cnt) {
- bio = bio_alloc(GFP_KERNEL, min(max_pages, BIO_MAX_PAGES));
- if (!bio) {
- err = -ENOMEM;
- goto out;
- }
-
- /* bi_sector is ALWAYS in units of 512 bytes */
- bio->bi_sector = ppos >> 9;
- bio->bi_bdev = bio_data->bdev;
- bio->bi_end_io = blockio_bio_endio;
- bio->bi_private = tio_work;
-
- if (tio_bio)
- biotail = biotail->bi_next = bio;
- else
- tio_bio = biotail = bio;
-
- atomic_inc(&tio_work->bios_remaining);
-
- /* Loop for filling bio */
- while (tio_index < tio->pg_cnt) {
- unsigned int bytes = PAGE_SIZE - offset;
-
- if (bytes > size)
- bytes = size;
-
- if (!bio_add_page(bio, tio->pvec[tio_index], bytes, offset))
- break;
-
- size -= bytes;
- ppos += bytes;
-
- offset = 0;
-
- tio_index++;
- }
- }
-
- /* Walk the list, submitting bios 1 by 1 */
- while (tio_bio) {
- bio = tio_bio;
- tio_bio = tio_bio->bi_next;
- bio->bi_next = NULL;
-
- submit_bio(rw, bio);
- }
-
- if (bdev_q && bdev_q->unplug_fn)
- bdev_q->unplug_fn(bdev_q);
-
- wait_for_completion(&tio_work->tio_complete);
-
- err = atomic_read(&tio_work->error);
-
- kfree(tio_work);
-
- return err;
-out:
- while (tio_bio) {
- bio = tio_bio;
- tio_bio = tio_bio->bi_next;
-
- bio_put(bio);
- }
-
- kfree(tio_work);
-
- return err;
-}
-
-static int
-blockio_open_path(struct iet_volume *volume, const char *path)
-{
- struct blockio_data *bio_data = volume->private;
- struct block_device *bdev;
- int flags = FMODE_READ | (LUReadonly(volume) ? 0 : FMODE_WRITE);
- int err = 0;
-
- bio_data->path = kstrdup(path, GFP_KERNEL);
- if (!bio_data->path)
- return -ENOMEM;
-
- bdev = blkdev_get_by_path(path, flags | FMODE_EXCL, THIS_MODULE);
- if (IS_ERR(bdev)) {
- err = PTR_ERR(bdev);
- eprintk("Can't open device %s, error %d\n", path, err);
- bio_data->bdev = NULL;
- } else {
- bio_data->bdev = bdev;
- fsync_bdev(bio_data->bdev);
- }
-
- return err;
-}
-
-/* Create an enumeration of our accepted actions */
-enum
-{
- opt_path, opt_ignore, opt_err,
-};
-
-/* Create a match table using our action enums and their matching options */
-static match_table_t tokens = {
- {opt_path, "path=%s"},
- {opt_ignore, "scsiid=%s"},
- {opt_ignore, "scsisn=%s"},
- {opt_ignore, "type=%s"},
- {opt_ignore, "iomode=%s"},
- {opt_ignore, "blocksize=%s"},
- {opt_err, NULL},
-};
-
-static int
-parse_blockio_params(struct iet_volume *volume, char *params)
-{
- struct blockio_data *info = volume->private;
- int err = 0;
- char *p, *q;
-
- /* Loop through parameters separated by commas, look up our
- * parameter in match table, return enumeration and arguments
- * select case based on the returned enum and run the action */
- while ((p = strsep(¶ms, ",")) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- int token;
- if (!*p)
- continue;
- iet_strtolower(p);
- token = match_token(p, tokens, args);
- switch (token) {
- case opt_path:
- if (info->path) {
- iprintk("Target %s, LUN %u: "
- "duplicate \"Path\" param\n",
- volume->target->name, volume->lun);
- err = -EINVAL;
- goto out;
- }
- if (!(q = match_strdup(&args[0]))) {
- err = -ENOMEM;
- goto out;
- }
- err = blockio_open_path(volume, q);
- kfree(q);
- if (err < 0)
- goto out;
- break;
- case opt_ignore:
- break;
- default:
- iprintk("Target %s, LUN %u: unknown param %s\n",
- volume->target->name, volume->lun, p);
- return -EINVAL;
- }
- }
-
- if (!info->path) {
- iprintk("Target %s, LUN %u: missing \"Path\" param\n",
- volume->target->name, volume->lun);
- err = -EINVAL;
- }
-
- out:
- return err;
-}
-
-static void
-blockio_detach(struct iet_volume *volume)
-{
- struct blockio_data *bio_data = volume->private;
- int flags = FMODE_READ | (LUReadonly(volume) ? 0 : FMODE_WRITE);
-
- if (bio_data->bdev)
- blkdev_put(bio_data->bdev, flags | FMODE_EXCL);
- kfree(bio_data->path);
-
- kfree(volume->private);
-}
-
-static int
-blockio_attach(struct iet_volume *volume, char *args)
-{
- struct blockio_data *bio_data;
- int err = 0;
-
- if (volume->private) {
- eprintk("Lun %u already attached on Target %s \n",
- volume->lun, volume->target->name);
- return -EBUSY;
- }
-
- bio_data = kzalloc(sizeof (*bio_data), GFP_KERNEL);
- if (!bio_data)
- return -ENOMEM;
-
- volume->private = bio_data;
-
- err = parse_blockio_params(volume, args);
- if (!err) {
- /* see Documentation/ABI/testing/sysfs-block */
- unsigned bsz = bdev_logical_block_size(bio_data->bdev);
- if (!volume->blk_shift)
- volume->blk_shift = blksize_bits(bsz);
- else if (volume->blk_shift < blksize_bits(bsz)) {
- eprintk("Specified block size (%u) smaller than "
- "device %s logical block size (%u)\n",
- (1 << volume->blk_shift), bio_data->path, bsz);
- err = -EINVAL;
- }
- }
- if (err < 0) {
- eprintk("Error attaching Lun %u to Target %s \n",
- volume->lun, volume->target->name);
- goto out;
- }
-
- volume->blk_cnt = bio_data->bdev->bd_inode->i_size >> volume->blk_shift;
-
- /* Offer neither write nor read caching */
- ClearLURCache(volume);
- ClearLUWCache(volume);
-
- out:
- if (err < 0)
- blockio_detach(volume);
-
- return err;
-}
-
-static void
-blockio_show(struct iet_volume *volume, struct seq_file *seq)
-{
- struct blockio_data *bio_data = volume->private;
-
- /* Used to display blockio volume info in /proc/net/iet/volumes */
- seq_printf(seq, " path:%s\n", bio_data->path);
-}
-
-struct iotype blockio = {
- .name = "blockio",
- .attach = blockio_attach,
- .make_request = blockio_make_request,
- .detach = blockio_detach,
- .show = blockio_show,
-};
deleted file mode 100644
@@ -1,30 +0,0 @@
-/*
- * Kernel compatibility routines
- *
- * Copyright (C) 2008 Ross Walker <rswwalker at gmail dot com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#ifndef __IET_COMPAT_H__
-#define __IET_COMPAT_H__
-
-#include <linux/version.h>
-
-#ifndef DECLARE_COMPLETION_ONSTACK
-#define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
-#endif
-
-#ifndef is_power_of_2
-#define is_power_of_2(n) (n != 0 && ((n & (n - 1)) == 0))
-#endif
-
-#ifndef log2
-#define log2(n) ((sizeof(n) <= 4) ? (fls(n) - 1) : (fls64(n) - 1))
-#endif
-
-#ifndef roundup_pow_of_two
-#define roundup_pow_of_two(n) (1UL << fls_long(n - 1))
-#endif
-
-#endif /* __IET_COMPAT_H__ */
deleted file mode 100644
@@ -1,362 +0,0 @@
-/*
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- *
- * This code is licenced under the GPL.
- */
-
-#include <linux/proc_fs.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-
-static DEFINE_SEMAPHORE(ioctl_sem);
-
-struct proc_entries {
- const char *name;
- struct file_operations *fops;
-};
-
-static struct proc_entries iet_proc_entries[] =
-{
- {"volume", &volume_seq_fops},
- {"session", &session_seq_fops},
-};
-
-static struct proc_dir_entry *proc_iet_dir;
-
-void iet_procfs_exit(void)
-{
- int i;
-
- if (!proc_iet_dir)
- return;
-
- for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++)
- remove_proc_entry(iet_proc_entries[i].name, proc_iet_dir);
-
- remove_proc_entry(proc_iet_dir->name, proc_iet_dir->parent);
-}
-
-int iet_procfs_init(void)
-{
- int i;
- struct proc_dir_entry *ent;
-
- if (!(proc_iet_dir = proc_mkdir("iet", init_net.proc_net)))
- goto err;
-
- for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++) {
- ent = create_proc_entry(iet_proc_entries[i].name, 0, proc_iet_dir);
- if (ent)
- ent->proc_fops = iet_proc_entries[i].fops;
- else
- goto err;
- }
-
- return 0;
-
-err:
- if (proc_iet_dir)
- iet_procfs_exit();
-
- return -ENOMEM;
-}
-
-static int get_module_info(unsigned long ptr)
-{
- struct module_info info;
- int err;
-
- snprintf(info.version, sizeof(info.version), "%s", IET_VERSION_STRING);
-
- err = copy_to_user((void *) ptr, &info, sizeof(info));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-static int get_conn_info(struct iscsi_target *target, unsigned long ptr)
-{
- struct iscsi_session *session;
- struct iscsi_conn *conn;
- struct conn_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- session = session_lookup(target, info.sid);
- if (!session)
- return -ENOENT;
-
- conn = conn_lookup(session, info.cid);
- if (!conn)
- return -ENOENT;
-
- info.cid = conn->cid;
- info.stat_sn = conn->stat_sn;
- info.exp_stat_sn = conn->exp_stat_sn;
-
- err = copy_to_user((void *) ptr, &info, sizeof(info));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-static int add_conn(struct iscsi_target *target, unsigned long ptr)
-{
- struct iscsi_session *session;
- struct conn_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- session = session_lookup(target, info.sid);
- if (!session)
- return -ENOENT;
-
- return conn_add(session, &info);
-}
-
-static int del_conn(struct iscsi_target *target, unsigned long ptr)
-{
- struct iscsi_session *session;
- struct conn_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- session = session_lookup(target, info.sid);
- if (!session)
- return -ENOENT;
-
- return conn_del(session, &info);
-}
-
-static int get_session_info(struct iscsi_target *target, unsigned long ptr)
-{
- struct iscsi_session *session;
- struct session_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- session = session_lookup(target, info.sid);
- if (!session)
- return -ENOENT;
-
- info.exp_cmd_sn = session->exp_cmd_sn;
- info.max_cmd_sn = session->max_cmd_sn;
-
- err = copy_to_user((void *) ptr, &info, sizeof(info));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-static int add_session(struct iscsi_target *target, unsigned long ptr)
-{
- struct session_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- return session_add(target, &info);
-}
-
-static int del_session(struct iscsi_target *target, unsigned long ptr)
-{
- struct session_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- return session_del(target, info.sid);
-}
-
-static int add_volume(struct iscsi_target *target, unsigned long ptr)
-{
- struct volume_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- return volume_add(target, &info);
-}
-
-static int del_volume(struct iscsi_target *target, unsigned long ptr)
-{
- struct volume_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- return iscsi_volume_del(target, &info);
-}
-
-static int iscsi_param_config(struct iscsi_target *target, unsigned long ptr, int set)
-{
- struct iscsi_param_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- err = iscsi_param_set(target, &info, set);
- if (err < 0 || set)
- return err;
-
- err = copy_to_user((void *) ptr, &info, sizeof(info));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-static int add_target(unsigned long ptr)
-{
- struct target_info info;
- int err;
-
- err = copy_from_user(&info, (void *) ptr, sizeof(info));
- if (err)
- return -EFAULT;
-
- err = target_add(&info);
- if (err < 0)
- return err;
-
- err = copy_to_user((void *) ptr, &info, sizeof(info));
- if (err)
- return -EFAULT;
-
- return 0;
-}
-
-static long ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- struct iscsi_target *target = NULL;
- long err;
- u32 id;
-
- err = down_interruptible(&ioctl_sem);
- if (err < 0)
- return err;
-
- if (cmd == GET_MODULE_INFO) {
- err = get_module_info(arg);
- goto done;
- }
-
- if (cmd == ADD_TARGET) {
- err = add_target(arg);
- goto done;
- }
-
- err = get_user(id, (u32 *) arg);
- if (err < 0)
- goto done;
-
- /* locking handled in target_del */
- if (cmd == DEL_TARGET) {
- err = target_del(id);
- goto done;
- }
-
- target = target_lookup_by_id(id);
- if (!target) {
- err = -ENOENT;
- goto done;
- }
-
- err = target_lock(target, 1);
- if (err < 0)
- goto done;
-
- switch (cmd) {
- case ADD_VOLUME:
- err = add_volume(target, arg);
- break;
-
- case DEL_VOLUME:
- err = del_volume(target, arg);
- break;
-
- case ADD_SESSION:
- err = add_session(target, arg);
- break;
-
- case DEL_SESSION:
- err = del_session(target, arg);
- break;
-
- case GET_SESSION_INFO:
- err = get_session_info(target, arg);
- break;
-
- case ISCSI_PARAM_SET:
- err = iscsi_param_config(target, arg, 1);
- break;
-
- case ISCSI_PARAM_GET:
- err = iscsi_param_config(target, arg, 0);
- break;
-
- case ADD_CONN:
- err = add_conn(target, arg);
- break;
-
- case DEL_CONN:
- err = del_conn(target, arg);
- break;
-
- case GET_CONN_INFO:
- err = get_conn_info(target, arg);
- break;
- default:
- eprintk("invalid ioctl cmd %x\n", cmd);
- err = -EINVAL;
- }
-
- target_unlock(target);
-done:
- up(&ioctl_sem);
-
- return err;
-}
-
-static int release(struct inode *i __attribute__((unused)),
- struct file *f __attribute__((unused)))
-{
- down(&ioctl_sem);
- target_del_all();
- up(&ioctl_sem);
-
- return 0;
-}
-
-struct file_operations ctr_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = ioctl,
- .compat_ioctl = ioctl,
- .release = release
-};
deleted file mode 100644
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <linux/file.h>
-#include <linux/ip.h>
-#include <net/tcp.h>
-#include <scsi/scsi.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "digest.h"
-
-static void print_conn_state(char *p, size_t size, unsigned long state)
-{
- if (test_bit(CONN_ACTIVE, &state))
- snprintf(p, size, "%s", "active");
- else if (test_bit(CONN_CLOSING, &state))
- snprintf(p, size, "%s", "closing");
- else
- snprintf(p, size, "%s", "unknown");
-}
-
-static void print_digest_state(char *p, size_t size, unsigned long flags)
-{
- if (DIGEST_NONE & flags)
- snprintf(p, size, "%s", "none");
- else if (DIGEST_CRC32C & flags)
- snprintf(p, size, "%s", "crc32c");
- else
- snprintf(p, size, "%s", "unknown");
-}
-
-void conn_info_show(struct seq_file *seq, struct iscsi_session *session)
-{
- struct iscsi_conn *conn;
- struct sock *sk;
- char buf[64];
-
- list_for_each_entry(conn, &session->conn_list, list) {
- sk = conn->sock->sk;
- switch (sk->sk_family) {
- case AF_INET:
- snprintf(buf, sizeof(buf),
- "%pI4", &inet_sk(sk)->inet_daddr);
- break;
- case AF_INET6:
- snprintf(buf, sizeof(buf), "[%pI6]",
- &inet6_sk(sk)->daddr);
- break;
- default:
- break;
- }
- seq_printf(seq, "\t\tcid:%u ip:%s ", conn->cid, buf);
- print_conn_state(buf, sizeof(buf), conn->state);
- seq_printf(seq, "state:%s ", buf);
- print_digest_state(buf, sizeof(buf), conn->hdigest_type);
- seq_printf(seq, "hd:%s ", buf);
- print_digest_state(buf, sizeof(buf), conn->ddigest_type);
- seq_printf(seq, "dd:%s\n", buf);
- }
-}
-
-struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid)
-{
- struct iscsi_conn *conn;
-
- list_for_each_entry(conn, &session->conn_list, list) {
- if (conn->cid == cid)
- return conn;
- }
- return NULL;
-}
-
-static void iet_state_change(struct sock *sk)
-{
- struct iscsi_conn *conn = sk->sk_user_data;
- struct iscsi_target *target = conn->session->target;
-
- if (sk->sk_state != TCP_ESTABLISHED)
- conn_close(conn);
- else
- nthread_wakeup(target);
-
- target->nthread_info.old_state_change(sk);
-}
-
-static void iet_data_ready(struct sock *sk, int len)
-{
- struct iscsi_conn *conn = sk->sk_user_data;
- struct iscsi_target *target = conn->session->target;
-
- nthread_wakeup(target);
- target->nthread_info.old_data_ready(sk, len);
-}
-
-/*
- * @locking: grabs the target's nthread_lock to protect it from races with
- * set_conn_wspace_wait()
- */
-static void iet_write_space(struct sock *sk)
-{
- struct iscsi_conn *conn = sk->sk_user_data;
- struct network_thread_info *info = &conn->session->target->nthread_info;
-
- spin_lock_bh(&info->nthread_lock);
-
- if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) &&
- test_bit(CONN_WSPACE_WAIT, &conn->state)) {
- clear_bit(CONN_WSPACE_WAIT, &conn->state);
- __nthread_wakeup(info);
- }
-
- spin_unlock_bh(&info->nthread_lock);
-
- info->old_write_space(sk);
-}
-
-static void iet_socket_bind(struct iscsi_conn *conn)
-{
- int opt = 1;
- mm_segment_t oldfs;
- struct iscsi_session *session = conn->session;
- struct iscsi_target *target = session->target;
-
- dprintk(D_GENERIC, "%llu\n", (unsigned long long) session->sid);
-
- conn->sock = SOCKET_I(conn->file->f_dentry->d_inode);
- conn->sock->sk->sk_user_data = conn;
-
- write_lock_bh(&conn->sock->sk->sk_callback_lock);
- target->nthread_info.old_state_change = conn->sock->sk->sk_state_change;
- conn->sock->sk->sk_state_change = iet_state_change;
-
- target->nthread_info.old_data_ready = conn->sock->sk->sk_data_ready;
- conn->sock->sk->sk_data_ready = iet_data_ready;
-
- target->nthread_info.old_write_space = conn->sock->sk->sk_write_space;
- conn->sock->sk->sk_write_space = iet_write_space;
- write_unlock_bh(&conn->sock->sk->sk_callback_lock);
-
- oldfs = get_fs();
- set_fs(get_ds());
- conn->sock->ops->setsockopt(conn->sock, SOL_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt));
- set_fs(oldfs);
-}
-
-int conn_free(struct iscsi_conn *conn)
-{
- dprintk(D_GENERIC, "%p %#Lx %u\n", conn->session,
- (unsigned long long) conn->session->sid, conn->cid);
-
- assert(atomic_read(&conn->nr_cmnds) == 0);
- assert(list_empty(&conn->pdu_list));
- assert(list_empty(&conn->write_list));
-
- list_del(&conn->list);
- list_del(&conn->poll_list);
-
- del_timer_sync(&conn->nop_timer);
- digest_cleanup(conn);
- kfree(conn);
-
- return 0;
-}
-
-static int iet_conn_alloc(struct iscsi_session *session, struct conn_info *info)
-{
- struct iscsi_conn *conn;
-
- dprintk(D_SETUP, "%#Lx:%u\n", (unsigned long long) session->sid, info->cid);
-
- conn = kzalloc(sizeof(*conn), GFP_KERNEL);
- if (!conn)
- return -ENOMEM;
-
- conn->session = session;
- conn->cid = info->cid;
- conn->stat_sn = info->stat_sn;
- conn->exp_stat_sn = info->exp_stat_sn;
-
- conn->hdigest_type = info->header_digest;
- conn->ddigest_type = info->data_digest;
- if (digest_init(conn) < 0) {
- kfree(conn);
- return -ENOMEM;
- }
-
- spin_lock_init(&conn->list_lock);
- atomic_set(&conn->nr_cmnds, 0);
- atomic_set(&conn->nr_busy_cmnds, 0);
- INIT_LIST_HEAD(&conn->pdu_list);
- INIT_LIST_HEAD(&conn->write_list);
- INIT_LIST_HEAD(&conn->poll_list);
- init_timer(&conn->nop_timer);
-
- list_add(&conn->list, &session->conn_list);
-
- set_bit(CONN_ACTIVE, &conn->state);
-
- conn->file = fget(info->fd);
- iet_socket_bind(conn);
-
- list_add(&conn->poll_list, &session->target->nthread_info.active_conns);
-
- nthread_wakeup(conn->session->target);
-
- return 0;
-}
-
-void conn_close(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *cmnd;
- struct iscsi_session *session = conn->session;
-
- if (test_and_clear_bit(CONN_ACTIVE, &conn->state))
- set_bit(CONN_CLOSING, &conn->state);
-
- spin_lock(&conn->list_lock);
- list_for_each_entry(cmnd, &conn->pdu_list, conn_list) {
- set_cmnd_tmfabort(cmnd);
- if (cmnd->lun) {
- ua_establish_for_session(session, cmnd->lun->lun, 0x47, 0x7f);
- iscsi_cmnd_set_sense(cmnd, UNIT_ATTENTION, 0x6e, 0x0);
- }
- }
- spin_unlock(&conn->list_lock);
-
- nthread_wakeup(conn->session->target);
-}
-
-int conn_add(struct iscsi_session *session, struct conn_info *info)
-{
- struct iscsi_conn *conn;
- int err;
-
- conn = conn_lookup(session, info->cid);
- if (conn)
- conn_close(conn);
-
- err = iet_conn_alloc(session, info);
- if (!err && conn)
- err = -EEXIST;
-
- return err;
-}
-
-int conn_del(struct iscsi_session *session, struct conn_info *info)
-{
- struct iscsi_conn *conn;
- int err = -EEXIST;
-
- conn = conn_lookup(session, info->cid);
- if (!conn)
- return err;
-
- conn_close(conn);
-
- return 0;
-}
deleted file mode 100644
@@ -1,279 +0,0 @@
-/*
- * iSCSI digest handling.
- * (C) 2004 - 2006 Xiranet Communications GmbH <arne.redlich@xiranet.com>
- * This code is licensed under the GPL.
- */
-
-#include <linux/types.h>
-
-#include "iscsi.h"
-#include "digest.h"
-#include "iscsi_dbg.h"
-
-void digest_alg_available(unsigned int *val)
-{
- if (*val & DIGEST_CRC32C &&
- !crypto_has_alg("crc32c", 0, CRYPTO_ALG_ASYNC)) {
- printk("CRC32C digest algorithm not available in kernel\n");
- *val |= ~DIGEST_CRC32C;
- }
-}
-
-/**
- * initialize support for digest calculation.
- *
- * digest_init -
- * @conn: ptr to connection to make use of digests
- *
- * @return: 0 on success, < 0 on error
- */
-int digest_init(struct iscsi_conn *conn)
-{
- int err = 0;
-
- if (!(conn->hdigest_type & DIGEST_ALL))
- conn->hdigest_type = DIGEST_NONE;
-
- if (!(conn->ddigest_type & DIGEST_ALL))
- conn->ddigest_type = DIGEST_NONE;
-
- if (conn->hdigest_type & DIGEST_CRC32C ||
- conn->ddigest_type & DIGEST_CRC32C) {
- conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
- CRYPTO_ALG_ASYNC);
- conn->rx_hash.flags = 0;
- if (IS_ERR(conn->rx_hash.tfm)) {
- conn->rx_hash.tfm = NULL;
- err = -ENOMEM;
- goto out;
- }
-
- conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
- CRYPTO_ALG_ASYNC);
- conn->tx_hash.flags = 0;
- if (IS_ERR(conn->tx_hash.tfm)) {
- conn->tx_hash.tfm = NULL;
- err = -ENOMEM;
- goto out;
- }
- }
-
-out:
- if (err)
- digest_cleanup(conn);
-
- return err;
-}
-
-/**
- * free resources used for digest calculation.
- *
- * digest_cleanup -
- * @conn: ptr to connection that made use of digests
- */
-void digest_cleanup(struct iscsi_conn *conn)
-{
- if (conn->tx_hash.tfm)
- crypto_free_hash(conn->tx_hash.tfm);
- if (conn->rx_hash.tfm)
- crypto_free_hash(conn->rx_hash.tfm);
-}
-
-/**
- * debug handling of header digest errors:
- * simulates a digest error after n PDUs / every n-th PDU of type
- * HDIGEST_ERR_CORRUPT_PDU_TYPE.
- */
-static inline void __dbg_simulate_header_digest_error(struct iscsi_cmnd *cmnd)
-{
-#define HDIGEST_ERR_AFTER_N_CMNDS 1000
-#define HDIGEST_ERR_ONLY_ONCE 1
-#define HDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_CMD
-#define HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY 0
-
- static int num_cmnds = 0;
- static int num_errs = 0;
-
- if (cmnd_opcode(cmnd) == HDIGEST_ERR_CORRUPT_PDU_TYPE) {
- if (HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY) {
- if (cmnd->pdu.datasize)
- num_cmnds++;
- } else
- num_cmnds++;
- }
-
- if ((num_cmnds == HDIGEST_ERR_AFTER_N_CMNDS)
- && (!(HDIGEST_ERR_ONLY_ONCE && num_errs))) {
- printk("*** Faking header digest error ***\n");
- printk("\tcmnd: 0x%x, itt 0x%x, sn 0x%x\n",
- cmnd_opcode(cmnd),
- be32_to_cpu(cmnd->pdu.bhs.itt),
- be32_to_cpu(cmnd->pdu.bhs.sn));
- cmnd->hdigest = ~cmnd->hdigest;
- /* make things even worse by manipulating header fields */
- cmnd->pdu.datasize += 8;
- num_errs++;
- num_cmnds = 0;
- }
- return;
-}
-
-/**
- * debug handling of data digest errors:
- * simulates a digest error after n PDUs / every n-th PDU of type
- * DDIGEST_ERR_CORRUPT_PDU_TYPE.
- */
-static inline void __dbg_simulate_data_digest_error(struct iscsi_cmnd *cmnd)
-{
-#define DDIGEST_ERR_AFTER_N_CMNDS 50
-#define DDIGEST_ERR_ONLY_ONCE 1
-#define DDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_DATA_OUT
-#define DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY 0
-
- static int num_cmnds = 0;
- static int num_errs = 0;
-
- if ((cmnd->pdu.datasize)
- && (cmnd_opcode(cmnd) == DDIGEST_ERR_CORRUPT_PDU_TYPE)) {
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_SCSI_DATA_OUT:
- if ((DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY)
- && (cmnd->pdu.bhs.ttt != ISCSI_RESERVED_TAG))
- break;
- default:
- num_cmnds++;
- }
- }
-
- if ((num_cmnds == DDIGEST_ERR_AFTER_N_CMNDS)
- && (!(DDIGEST_ERR_ONLY_ONCE && num_errs))
- && (cmnd->pdu.datasize)
- && (!cmnd->conn->read_overflow)) {
- printk("*** Faking data digest error: ***");
- printk("\tcmnd 0x%x, itt 0x%x, sn 0x%x\n",
- cmnd_opcode(cmnd),
- be32_to_cpu(cmnd->pdu.bhs.itt),
- be32_to_cpu(cmnd->pdu.bhs.sn));
- cmnd->ddigest = ~cmnd->ddigest;
- num_errs++;
- num_cmnds = 0;
- }
-}
-
-static void digest_header(struct hash_desc *hash, struct iscsi_pdu *pdu,
- u8 *crc)
-{
- struct scatterlist sg[2];
- unsigned int nbytes = sizeof(struct iscsi_hdr);
-
- sg_init_table(sg, pdu->ahssize ? 2 : 1);
-
- sg_set_buf(&sg[0], &pdu->bhs, nbytes);
- if (pdu->ahssize) {
- sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize);
- nbytes += pdu->ahssize;
- }
-
- crypto_hash_init(hash);
- crypto_hash_update(hash, sg, nbytes);
- crypto_hash_final(hash, crc);
-}
-
-int digest_rx_header(struct iscsi_cmnd *cmnd)
-{
- u32 crc;
-
- digest_header(&cmnd->conn->rx_hash, &cmnd->pdu, (u8 *) &crc);
- if (crc != cmnd->hdigest)
- return -EIO;
-
- return 0;
-}
-
-void digest_tx_header(struct iscsi_cmnd *cmnd)
-{
- digest_header(&cmnd->conn->tx_hash, &cmnd->pdu, (u8 *) &cmnd->hdigest);
-}
-
-static void digest_data(struct hash_desc *hash, struct iscsi_cmnd *cmnd,
- struct tio *tio, u32 offset, u8 *crc)
-{
- struct scatterlist *sg = cmnd->conn->hash_sg;
- u32 size, length;
- int i, idx, count;
- unsigned int nbytes;
-
- size = cmnd->pdu.datasize;
- nbytes = size = (size + 3) & ~3;
-
- offset += tio->offset;
- idx = offset >> PAGE_CACHE_SHIFT;
- offset &= ~PAGE_CACHE_MASK;
- count = get_pgcnt(size, offset);
- assert(idx + count <= tio->pg_cnt);
-
- assert(count <= ISCSI_CONN_IOV_MAX);
-
- sg_init_table(sg, ARRAY_SIZE(cmnd->conn->hash_sg));
- crypto_hash_init(hash);
-
- for (i = 0; size; i++) {
- if (offset + size > PAGE_CACHE_SIZE)
- length = PAGE_CACHE_SIZE - offset;
- else
- length = size;
-
- sg_set_page(&sg[i], tio->pvec[idx + i], length, offset);
- size -= length;
- offset = 0;
- }
-
- sg_mark_end(&sg[i - 1]);
-
- crypto_hash_update(hash, sg, nbytes);
- crypto_hash_final(hash, crc);
-}
-
-int digest_rx_data(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio;
- struct iscsi_cmnd *scsi_cmnd;
- struct iscsi_data_out_hdr *req;
- u32 offset, crc;
-
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_SCSI_REJECT:
- case ISCSI_OP_PDU_REJECT:
- case ISCSI_OP_DATA_REJECT:
- return 0;
- case ISCSI_OP_SCSI_DATA_OUT:
- scsi_cmnd = cmnd->req;
- req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs;
- tio = scsi_cmnd->tio;
- offset = be32_to_cpu(req->buffer_offset);
- break;
- default:
- tio = cmnd->tio;
- offset = 0;
- }
-
- digest_data(&cmnd->conn->rx_hash, cmnd, tio, offset, (u8 *) &crc);
-
- if (!cmnd->conn->read_overflow &&
- (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) {
- if (crc != cmnd->ddigest)
- return -EIO;
- }
-
- return 0;
-}
-
-void digest_tx_data(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio = cmnd->tio;
- struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs;
-
- assert(tio);
- digest_data(&cmnd->conn->tx_hash, cmnd, tio,
- be32_to_cpu(req->buffer_offset), (u8 *) &cmnd->ddigest);
-}
deleted file mode 100644
@@ -1,20 +0,0 @@
-/*
- * iSCSI digest handling.
- * (C) 2004 Xiranet Communications GmbH <arne.redlich@xiranet.com>
- * This code is licensed under the GPL.
- */
-
-#ifndef __IET_DIGEST_H__
-#define __IET_DIGEST_H__
-
-extern void digest_alg_available(unsigned int *val);
-extern int digest_init(struct iscsi_conn *conn);
-extern void digest_cleanup(struct iscsi_conn *conn);
-
-extern int digest_rx_header(struct iscsi_cmnd *cmnd);
-extern int digest_rx_data(struct iscsi_cmnd *cmnd);
-
-extern void digest_tx_header(struct iscsi_cmnd *cmnd);
-extern void digest_tx_data(struct iscsi_cmnd *cmnd);
-
-#endif /* __IET_DIGEST_H__ */
deleted file mode 100644
@@ -1,96 +0,0 @@
-/*
- * Event notification code.
- * (C) 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- *
- * Some functions are based on audit code.
- */
-
-#include <net/tcp.h>
-#include "iet_u.h"
-#include "iscsi_dbg.h"
-
-static struct sock *nl;
-static u32 ietd_pid;
-
-static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
-{
- u32 uid, pid, seq;
- char *data;
-
- pid = NETLINK_CREDS(skb)->pid;
- uid = NETLINK_CREDS(skb)->uid;
- seq = nlh->nlmsg_seq;
- data = NLMSG_DATA(nlh);
-
- ietd_pid = pid;
-
- return 0;
-}
-
-static void event_recv_skb(struct sk_buff *skb)
-{
- int err;
- struct nlmsghdr *nlh;
- u32 rlen;
-
- while (skb->len >= NLMSG_SPACE(0)) {
- nlh = (struct nlmsghdr *)skb->data;
- if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
- break;
- rlen = NLMSG_ALIGN(nlh->nlmsg_len);
- if (rlen > skb->len)
- rlen = skb->len;
- if ((err = event_recv_msg(skb, nlh))) {
- netlink_ack(skb, nlh, -err);
- } else if (nlh->nlmsg_flags & NLM_F_ACK)
- netlink_ack(skb, nlh, 0);
- skb_pull(skb, rlen);
- }
-}
-
-static int notify(void *data, int len, int gfp_mask)
-{
- struct sk_buff *skb;
- struct nlmsghdr *nlh;
- static u32 seq = 0;
-
- if (!(skb = alloc_skb(NLMSG_SPACE(len), gfp_mask)))
- return -ENOMEM;
-
- nlh = __nlmsg_put(skb, ietd_pid, seq++, NLMSG_DONE, len - sizeof(*nlh), 0);
-
- memcpy(NLMSG_DATA(nlh), data, len);
-
- return netlink_unicast(nl, skb, ietd_pid, 0);
-}
-
-int event_send(u32 tid, u64 sid, u32 cid, u32 state, int atomic)
-{
- int err;
- struct iet_event event;
-
- event.tid = tid;
- event.sid = sid;
- event.cid = cid;
- event.state = state;
-
- err = notify(&event, NLMSG_SPACE(sizeof(struct iet_event)), 0);
-
- return err;
-}
-
-int event_init(void)
-{
- nl = netlink_kernel_create(&init_net, NETLINK_IET, 1, event_recv_skb,
- NULL, THIS_MODULE);
- if (!nl)
- return -ENOMEM;
- else
- return 0;
-}
-
-void event_exit(void)
-{
- netlink_kernel_release(nl);
-}
deleted file mode 100644
@@ -1,261 +0,0 @@
-/*
- * Target device file I/O.
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/parser.h>
-#include <linux/writeback.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-struct fileio_data {
- char *path;
- struct file *filp;
-};
-
-static int fileio_make_request(struct iet_volume *lu, struct tio *tio, int rw)
-{
- struct fileio_data *p = lu->private;
- struct file *filp;
- mm_segment_t oldfs;
- struct page *page;
- u32 offset, size;
- loff_t ppos, count;
- char *buf;
- int i, err = 0;
- ssize_t ret;
-
- assert(p);
- filp = p->filp;
- size = tio->size;
- offset= tio->offset;
-
- ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT;
- ppos += offset;
-
- for (i = 0; i < tio->pg_cnt; i++) {
- page = tio->pvec[i];
- assert(page);
- buf = page_address(page);
- buf += offset;
-
- if (offset + size > PAGE_CACHE_SIZE)
- count = PAGE_CACHE_SIZE - offset;
- else
- count = size;
-
- oldfs = get_fs();
- set_fs(get_ds());
-
- if (rw == READ)
- ret = vfs_read(filp, buf, count, &ppos);
- else
- ret = vfs_write(filp, buf, count, &ppos);
-
- set_fs(oldfs);
-
- if (ret != count) {
- eprintk("I/O error %lld, %ld\n", count, (long) ret);
- err = -EIO;
- }
-
- size -= count;
- offset = 0;
- }
- assert(!size);
-
- return err;
-}
-
-static int fileio_sync(struct iet_volume *lu, struct tio *tio)
-{
- struct fileio_data *p = lu->private;
- struct inode *inode = p->filp->f_dentry->d_inode;
- struct address_space *mapping = inode->i_mapping;
- loff_t ppos, count;
- int res;
-
- if (tio) {
- ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT;
- ppos += tio->offset;
- count = tio->size;
- } else {
- ppos = 0;
- count = lu->blk_cnt << lu->blk_shift;
- }
-
- res = filemap_write_and_wait_range(mapping, ppos, ppos + count - 1);
- if (res) {
- eprintk("I/O error: syncing pages failed: %d\n", res);
- return -EIO;
- } else
- return 0;
-}
-
-static int open_path(struct iet_volume *volume, const char *path)
-{
- int err = 0;
- struct fileio_data *info = volume->private;
- struct file *filp;
- mm_segment_t oldfs;
- int flags;
-
- info->path = kstrdup(path, GFP_KERNEL);
- if (!info->path)
- return -ENOMEM;
-
- oldfs = get_fs();
- set_fs(get_ds());
- flags = (LUReadonly(volume) ? O_RDONLY : O_RDWR) | O_LARGEFILE;
- filp = filp_open(path, flags, 0);
- set_fs(oldfs);
-
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
- eprintk("Can't open %s %d\n", path, err);
- info->filp = NULL;
- } else
- info->filp = filp;
-
- return err;
-}
-
-enum {
- opt_path, opt_ignore, opt_err,
-};
-
-static match_table_t tokens = {
- {opt_path, "path=%s"},
- {opt_ignore, "scsiid=%s"},
- {opt_ignore, "scsisn=%s"},
- {opt_ignore, "type=%s"},
- {opt_ignore, "iomode=%s"},
- {opt_ignore, "blocksize=%s"},
- {opt_err, NULL},
-};
-
-static int parse_fileio_params(struct iet_volume *volume, char *params)
-{
- struct fileio_data *info = volume->private;
- int err = 0;
- char *p, *q;
-
- while ((p = strsep(¶ms, ",")) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- int token;
- if (!*p)
- continue;
- iet_strtolower(p);
- token = match_token(p, tokens, args);
- switch (token) {
- case opt_path:
- if (info->path) {
- iprintk("Target %s, LUN %u: "
- "duplicate \"Path\" param\n",
- volume->target->name, volume->lun);
- err = -EINVAL;
- goto out;
- }
- if (!(q = match_strdup(&args[0]))) {
- err = -ENOMEM;
- goto out;
- }
- err = open_path(volume, q);
- kfree(q);
- if (err < 0)
- goto out;
- break;
- case opt_ignore:
- break;
- default:
- iprintk("Target %s, LUN %u: unknown param %s\n",
- volume->target->name, volume->lun, p);
- return -EINVAL;
- }
- }
-
- if (!info->path) {
- iprintk("Target %s, LUN %u: missing \"Path\" param\n",
- volume->target->name, volume->lun);
- err = -EINVAL;
- }
-out:
- return err;
-}
-
-static void fileio_detach(struct iet_volume *lu)
-{
- struct fileio_data *p = lu->private;
-
- kfree(p->path);
- if (p->filp)
- filp_close(p->filp, NULL);
- kfree(p);
- lu->private = NULL;
-}
-
-static int fileio_attach(struct iet_volume *lu, char *args)
-{
- int err = 0;
- struct fileio_data *p;
- struct inode *inode;
-
- if (lu->private) {
- printk("already attached ? %d\n", lu->lun);
- return -EBUSY;
- }
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- lu->private = p;
-
- if ((err = parse_fileio_params(lu, args)) < 0) {
- eprintk("%d\n", err);
- goto out;
- }
- inode = p->filp->f_dentry->d_inode;
-
- if (S_ISREG(inode->i_mode))
- ;
- else if (S_ISBLK(inode->i_mode))
- inode = inode->i_bdev->bd_inode;
- else {
- err = -EINVAL;
- goto out;
- }
-
- if (!lu->blk_shift)
- lu->blk_shift = blksize_bits(IET_DEF_BLOCK_SIZE);
-
- lu->blk_cnt = inode->i_size >> lu->blk_shift;
-
- /* we're using the page cache */
- SetLURCache(lu);
-out:
- if (err < 0)
- fileio_detach(lu);
- return err;
-}
-
-static void fileio_show(struct iet_volume *lu, struct seq_file *seq)
-{
- struct fileio_data *p = lu->private;
- seq_printf(seq, " path:%s\n", p->path);
-}
-
-struct iotype fileio =
-{
- .name = "fileio",
- .attach = fileio_attach,
- .make_request = fileio_make_request,
- .sync = fileio_sync,
- .detach = fileio_detach,
- .show = fileio_show,
-};
deleted file mode 100644
@@ -1,151 +0,0 @@
-#ifndef _IET_U_H
-#define _IET_U_H
-
-#define IET_VERSION_STRING "1.4.20.2"
-
-/* The maximum length of 223 bytes in the RFC. */
-#define ISCSI_NAME_LEN 256
-#define ISCSI_ARGS_LEN 2048
-
-#define ISCSI_LISTEN_PORT 3260
-
-#define SCSI_ID_LEN 16
-#define SCSI_SN_LEN (SCSI_ID_LEN * 2)
-
-#ifndef aligned_u64
-#define aligned_u64 unsigned long long __attribute__((aligned(8)))
-#endif
-
-struct module_info {
- char version[128];
-};
-
-struct target_info {
- u32 tid;
- char name[ISCSI_NAME_LEN];
-};
-
-struct volume_info {
- u32 tid;
- u32 lun;
- aligned_u64 args_ptr;
- u32 args_len;
-};
-
-struct session_info {
- u32 tid;
-
- aligned_u64 sid;
- char initiator_name[ISCSI_NAME_LEN];
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
-};
-
-#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C)
-#define DIGEST_NONE (1 << 0)
-#define DIGEST_CRC32C (1 << 1)
-
-struct conn_info {
- u32 tid;
- aligned_u64 sid;
-
- u32 cid;
- u32 stat_sn;
- u32 exp_stat_sn;
- int header_digest;
- int data_digest;
- int fd;
-};
-
-enum {
- key_initial_r2t,
- key_immediate_data,
- key_max_connections,
- key_max_recv_data_length,
- key_max_xmit_data_length,
- key_max_burst_length,
- key_first_burst_length,
- key_default_wait_time,
- key_default_retain_time,
- key_max_outstanding_r2t,
- key_data_pdu_inorder,
- key_data_sequence_inorder,
- key_error_recovery_level,
- key_header_digest,
- key_data_digest,
- key_ofmarker,
- key_ifmarker,
- key_ofmarkint,
- key_ifmarkint,
- session_key_last,
-};
-
-enum {
- key_wthreads,
- key_target_type,
- key_queued_cmnds,
- key_nop_interval,
- key_nop_timeout,
- target_key_last,
-};
-
-enum {
- key_session,
- key_target,
-};
-
-struct iscsi_param_info {
- u32 tid;
- aligned_u64 sid;
-
- u32 param_type;
- u32 partial;
-
- u32 session_param[session_key_last];
- u32 target_param[target_key_last];
-};
-
-enum iet_event_state {
- E_CONN_CLOSE,
-};
-
-struct iet_event {
- u32 tid;
- aligned_u64 sid;
- u32 cid;
- u32 state;
-};
-
-#define DEFAULT_NR_WTHREADS 8
-#define MIN_NR_WTHREADS 1
-#define MAX_NR_WTHREADS 128
-
-#define DEFAULT_NR_QUEUED_CMNDS 32
-#define MIN_NR_QUEUED_CMNDS 1
-#define MAX_NR_QUEUED_CMNDS 256
-
-#define DEFAULT_NOP_INTERVAL 0
-#define MIN_NOP_INTERVAL 0
-#define MAX_NOP_INTERVAL 90
-
-#define DEFAULT_NOP_TIMEOUT 0
-#define MIN_NOP_TIMEOUT 0
-#define MAX_NOP_TIMEOUT 90
-
-#define NETLINK_IET 21
-
-#define GET_MODULE_INFO _IOW('i', 20, struct module_info)
-#define ADD_TARGET _IOWR('i', 21, struct target_info)
-#define DEL_TARGET _IOW('i', 22, struct target_info)
-#define ADD_VOLUME _IOW('i', 24, struct volume_info)
-#define DEL_VOLUME _IOW('i', 25, struct volume_info)
-#define ADD_SESSION _IOW('i', 26, struct session_info)
-#define DEL_SESSION _IOW('i', 27, struct session_info)
-#define GET_SESSION_INFO _IOWR('i', 28, struct session_info)
-#define ADD_CONN _IOW('i', 29, struct conn_info)
-#define DEL_CONN _IOW('i', 30, struct conn_info)
-#define GET_CONN_INFO _IOWR('i', 31, struct conn_info)
-#define ISCSI_PARAM_SET _IOW('i', 32, struct iscsi_param_info)
-#define ISCSI_PARAM_GET _IOWR('i', 33, struct iscsi_param_info)
-
-#endif
deleted file mode 100644
@@ -1,110 +0,0 @@
-/*
- * Manager for various I/O types.
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include "iscsi.h"
-#include "iotype.h"
-#include "iscsi_dbg.h"
-
-static LIST_HEAD(iotypes);
-static rwlock_t iotypes_lock = __RW_LOCK_UNLOCKED(iotypes_lock);
-
-static struct iotype *find_iotype(const char *name)
-{
- struct iotype *iot = NULL;
-
- list_for_each_entry(iot, &iotypes, iot_list) {
- if (strcmp(iot->name, name) == 0)
- return iot;
- }
- return NULL;
-}
-
-struct iotype *get_iotype(const char *name)
-{
- struct iotype *iot;
-
- read_lock(&iotypes_lock);
- iot = find_iotype(name);
- read_unlock(&iotypes_lock);
-
- return iot;
-}
-
-void put_iotype(struct iotype *iot)
-{
- if (!iot)
- return;
- return;
-}
-
-static int register_iotype(struct iotype *iot)
-{
- int err = 0;
- struct iotype *p;
-
- write_lock(&iotypes_lock);
-
- p = find_iotype(iot->name);
- if (p)
- err = -EBUSY;
- else
- list_add_tail(&iot->iot_list, &iotypes);
-
- write_unlock(&iotypes_lock);
-
- return err;
-}
-
-static int unregister_iotype(struct iotype *iot)
-{
- int err = 0;
- struct iotype *p;
-
- write_lock(&iotypes_lock);
-
- p = find_iotype(iot->name);
- if (p && p == iot)
- list_del_init(&iot->iot_list);
- else
- err = -EINVAL;
-
- write_unlock(&iotypes_lock);
-
-
- return err;
-}
-
-struct iotype *iotype_array[] = {
- &fileio,
- &blockio,
- &nullio,
-};
-
-int iotype_init(void)
-{
- int i, err;
-
- for (i = 0; i < ARRAY_SIZE(iotype_array); i++) {
- if (!(err = register_iotype(iotype_array[i])))
- iprintk("Registered io type %s\n",
- iotype_array[i]->name);
- else {
- eprintk("Failed to register io type %s\n",
- iotype_array[i]->name);
- break;
- }
- }
-
- return err;
-}
-
-void iotype_exit(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(iotype_array); i++)
- unregister_iotype(iotype_array[i]);
-}
deleted file mode 100644
@@ -1,42 +0,0 @@
-/*
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include <linux/ctype.h>
-#include "iscsi.h"
-
-#ifndef __IOTYPE_H__
-#define __IOTYPE_H__
-
-struct iotype {
- const char *name;
- struct list_head iot_list;
-
- int (*attach)(struct iet_volume *dev, char *args);
- int (*make_request)(struct iet_volume *dev, struct tio *tio, int rw);
- int (*sync)(struct iet_volume *dev, struct tio *tio);
- void (*detach)(struct iet_volume *dev);
- void (*show)(struct iet_volume *dev, struct seq_file *seq);
-};
-
-extern struct iotype fileio;
-extern struct iotype nullio;
-extern struct iotype blockio;
-
-extern int iotype_init(void);
-extern void iotype_exit(void);
-
-/* For option parameter parsing.
- * This is slightly iet specific: we only tolower() up to the first '='.
- * Note that this changes *c _in place_, but our parsing
- * routines copy the input to a scratch page before parsing anyways. */
-static inline void iet_strtolower(char *c)
-{
- if (!c)
- return;
- for (; *c && *c != '='; c++)
- *c = tolower(*c);
-}
-
-#endif
deleted file mode 100644
@@ -1,1967 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- * Copyright (C) 2008 Arne Redlich <agr@powerkom-dd.de>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <linux/module.h>
-#include <linux/hash.h>
-#include <net/tcp.h>
-#include <scsi/scsi.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-unsigned long debug_enable_flags;
-unsigned long worker_thread_pool_size;
-
-static struct kmem_cache *iscsi_cmnd_cache;
-static u8 dummy_data[PAGE_SIZE];
-
-static int ctr_major;
-static char ctr_name[] = "ietctl";
-extern struct file_operations ctr_fops;
-
-static u32 cmnd_write_size(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd);
-
- if (hdr->flags & ISCSI_CMD_WRITE)
- return be32_to_cpu(hdr->data_length);
- return 0;
-}
-
-static u32 cmnd_read_size(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd);
-
- if (hdr->flags & ISCSI_CMD_READ) {
- struct iscsi_rlength_ahdr *ahdr =
- (struct iscsi_rlength_ahdr *)cmnd->pdu.ahs;
-
- if (!(hdr->flags & ISCSI_CMD_WRITE))
- return be32_to_cpu(hdr->data_length);
- if (ahdr && ahdr->ahstype == ISCSI_AHSTYPE_RLENGTH)
- return be32_to_cpu(ahdr->read_length);
- }
- return 0;
-}
-
-static void iscsi_device_queue_cmnd(struct iscsi_cmnd *cmnd)
-{
- set_cmnd_waitio(cmnd);
- wthread_queue(cmnd);
-}
-
-static void iscsi_scsi_queuecmnd(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_queue *queue = &cmnd->lun->queue;
-
- dprintk(D_GENERIC, "%p\n", cmnd);
-
- if ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_UNTAGGED &&
- (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_SIMPLE) {
- cmnd->pdu.bhs.flags &= ~ISCSI_CMD_ATTR_MASK;
- cmnd->pdu.bhs.flags |= ISCSI_CMD_UNTAGGED;
- }
-
- spin_lock(&queue->queue_lock);
-
- set_cmnd_queued(cmnd);
-
- switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) {
- case ISCSI_CMD_UNTAGGED:
- case ISCSI_CMD_SIMPLE:
- if (!list_empty(&queue->wait_list) || queue->ordered_cmnd)
- goto pending;
- queue->active_cnt++;
- break;
-
- default:
- BUG();
- }
- spin_unlock(&queue->queue_lock);
-
- iscsi_device_queue_cmnd(cmnd);
- return;
- pending:
- assert(list_empty(&cmnd->list));
-
- list_add_tail(&cmnd->list, &queue->wait_list);
- spin_unlock(&queue->queue_lock);
- return;
-}
-
-static void iscsi_scsi_dequeuecmnd(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_queue *queue;
-
- if (!cmnd->lun)
- return;
- queue = &cmnd->lun->queue;
- spin_lock(&queue->queue_lock);
- switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) {
- case ISCSI_CMD_UNTAGGED:
- case ISCSI_CMD_SIMPLE:
- --queue->active_cnt;
- break;
- case ISCSI_CMD_ORDERED:
- case ISCSI_CMD_HEAD_OF_QUEUE:
- case ISCSI_CMD_ACA:
- BUG();
- default:
- /* Should the iscsi_scsi_queuecmnd func reject this ? */
- break;
- }
-
- while (!list_empty(&queue->wait_list)) {
- cmnd = list_entry(queue->wait_list.next, struct iscsi_cmnd, list);
- switch ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK)) {
- case ISCSI_CMD_UNTAGGED:
- case ISCSI_CMD_SIMPLE:
- list_del_init(&cmnd->list);
- queue->active_cnt++;
- iscsi_device_queue_cmnd(cmnd);
- break;
- case ISCSI_CMD_ORDERED:
- case ISCSI_CMD_HEAD_OF_QUEUE:
- case ISCSI_CMD_ACA:
- BUG();
- }
- }
-
- spin_unlock(&queue->queue_lock);
-
- return;
-}
-
-/**
- * create a new command.
- *
- * iscsi_cmnd_create -
- * @conn: ptr to connection (for i/o)
- *
- * @return ptr to command or NULL
- */
-
-struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *conn, int req)
-{
- struct iscsi_cmnd *cmnd;
-
- /* TODO: async interface is necessary ? */
- cmnd = kmem_cache_alloc(iscsi_cmnd_cache, GFP_KERNEL|__GFP_NOFAIL);
-
- memset(cmnd, 0, sizeof(*cmnd));
- INIT_LIST_HEAD(&cmnd->list);
- INIT_LIST_HEAD(&cmnd->pdu_list);
- INIT_LIST_HEAD(&cmnd->conn_list);
- INIT_LIST_HEAD(&cmnd->hash_list);
- cmnd->conn = conn;
- spin_lock(&conn->list_lock);
- atomic_inc(&conn->nr_cmnds);
- if (req)
- list_add_tail(&cmnd->conn_list, &conn->pdu_list);
- spin_unlock(&conn->list_lock);
- cmnd->tio = NULL;
-
- dprintk(D_GENERIC, "%p:%p\n", conn, cmnd);
-
- return cmnd;
-}
-
-/**
- * create a new command used as response.
- *
- * iscsi_cmnd_create_rsp_cmnd -
- * @cmnd: ptr to request command
- *
- * @return ptr to response command or NULL
- */
-
-static struct iscsi_cmnd *iscsi_cmnd_create_rsp_cmnd(struct iscsi_cmnd *cmnd, int final)
-{
- struct iscsi_cmnd *rsp = cmnd_alloc(cmnd->conn, 0);
-
- if (final)
- set_cmnd_final(rsp);
- list_add_tail(&rsp->pdu_list, &cmnd->pdu_list);
- rsp->req = cmnd;
- return rsp;
-}
-
-static struct iscsi_cmnd *get_rsp_cmnd(struct iscsi_cmnd *req)
-{
- return list_entry(req->pdu_list.prev, struct iscsi_cmnd, pdu_list);
-}
-
-static void iscsi_cmnds_init_write(struct list_head *send)
-{
- struct iscsi_cmnd *cmnd = list_entry(send->next, struct iscsi_cmnd, list);
- struct iscsi_conn *conn = cmnd->conn;
- struct list_head *pos, *next;
-
- spin_lock(&conn->list_lock);
-
- list_for_each_safe(pos, next, send) {
- cmnd = list_entry(pos, struct iscsi_cmnd, list);
-
- dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd));
-
- list_del_init(&cmnd->list);
- assert(conn == cmnd->conn);
- list_add_tail(&cmnd->list, &conn->write_list);
- }
-
- spin_unlock(&conn->list_lock);
-
- nthread_wakeup(conn->session->target);
-}
-
-static void iscsi_cmnd_init_write(struct iscsi_cmnd *cmnd)
-{
- LIST_HEAD(head);
-
- if (!list_empty(&cmnd->list)) {
- eprintk("%x %x %x %x %lx %u %u %u %u %u %u %u %d %d\n",
- cmnd_itt(cmnd), cmnd_ttt(cmnd), cmnd_opcode(cmnd),
- cmnd_scsicode(cmnd), cmnd->flags, cmnd->r2t_sn,
- cmnd->r2t_length, cmnd->is_unsolicited_data,
- cmnd->target_task_tag, cmnd->outstanding_r2t,
- cmnd->hdigest, cmnd->ddigest,
- list_empty(&cmnd->pdu_list), list_empty(&cmnd->hash_list));
-
- assert(list_empty(&cmnd->list));
- }
- list_add(&cmnd->list, &head);
- iscsi_cmnds_init_write(&head);
-}
-
-static void do_send_data_rsp(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct iscsi_cmnd *data_cmnd;
- struct tio *tio = cmnd->tio;
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- struct iscsi_data_in_hdr *rsp;
- u32 pdusize, expsize, scsisize, size, offset, sn;
- LIST_HEAD(send);
-
- dprintk(D_GENERIC, "%p\n", cmnd);
- pdusize = conn->session->param.max_xmit_data_length;
- expsize = cmnd_read_size(cmnd);
- size = min(expsize, tio->size);
- offset = 0;
- sn = 0;
-
- while (1) {
- data_cmnd = iscsi_cmnd_create_rsp_cmnd(cmnd, size <= pdusize);
- tio_get(tio);
- data_cmnd->tio = tio;
- rsp = (struct iscsi_data_in_hdr *)&data_cmnd->pdu.bhs;
-
- rsp->opcode = ISCSI_OP_SCSI_DATA_IN;
- rsp->itt = req->itt;
- rsp->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
- rsp->buffer_offset = offset;
- rsp->data_sn = cpu_to_be32(sn);
-
- if (size <= pdusize) {
- data_cmnd->pdu.datasize = size;
- rsp->flags = ISCSI_FLG_FINAL | ISCSI_FLG_STATUS;
-
- scsisize = tio->size;
- if (scsisize < expsize) {
- rsp->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
- size = expsize - scsisize;
- } else if (scsisize > expsize) {
- rsp->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW;
- size = scsisize - expsize;
- } else
- size = 0;
- rsp->residual_count = cpu_to_be32(size);
- list_add_tail(&data_cmnd->list, &send);
-
- break;
- }
-
- data_cmnd->pdu.datasize = pdusize;
-
- size -= pdusize;
- offset += pdusize;
- sn++;
-
- list_add_tail(&data_cmnd->list, &send);
- }
-
- iscsi_cmnds_init_write(&send);
-}
-
-static struct iscsi_cmnd *create_scsi_rsp(struct iscsi_cmnd *req)
-{
- struct iscsi_cmnd *rsp;
- struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req);
- struct iscsi_scsi_rsp_hdr *rsp_hdr;
- struct iscsi_sense_data *sense;
-
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 1);
-
- rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
- rsp_hdr->opcode = ISCSI_OP_SCSI_RSP;
- rsp_hdr->flags = ISCSI_FLG_FINAL;
- rsp_hdr->response = ISCSI_RESPONSE_COMMAND_COMPLETED;
- rsp_hdr->cmd_status = req->status;
- rsp_hdr->itt = req_hdr->itt;
-
- if (req->status == SAM_STAT_CHECK_CONDITION) {
- assert(!rsp->tio);
- rsp->tio = tio_alloc(1);
- sense = (struct iscsi_sense_data *)
- page_address(rsp->tio->pvec[0]);
-
- assert(sense);
- clear_page(sense);
- sense->length = cpu_to_be16(IET_SENSE_BUF_SIZE);
-
- memcpy(sense->data, req->sense_buf, IET_SENSE_BUF_SIZE);
- rsp->pdu.datasize = sizeof(struct iscsi_sense_data) +
- IET_SENSE_BUF_SIZE;
-
- rsp->tio->size = (rsp->pdu.datasize + 3) & -4;
- rsp->tio->offset = 0;
- }
-
- return rsp;
-}
-
-void iscsi_cmnd_set_sense(struct iscsi_cmnd *cmnd, u8 sense_key, u8 asc,
- u8 ascq)
-{
- cmnd->status = SAM_STAT_CHECK_CONDITION;
-
- cmnd->sense_buf[0] = 0xf0;
- cmnd->sense_buf[2] = sense_key;
- cmnd->sense_buf[7] = 6; // Additional sense length
- cmnd->sense_buf[12] = asc;
- cmnd->sense_buf[13] = ascq;
-
- /* Call to ACA/UAI handler */
-}
-
-static struct iscsi_cmnd *create_sense_rsp(struct iscsi_cmnd *req,
- u8 sense_key, u8 asc, u8 ascq)
-{
- iscsi_cmnd_set_sense(req, sense_key, asc, ascq);
- return create_scsi_rsp(req);
-}
-
-void send_scsi_rsp(struct iscsi_cmnd *req, void (*func)(struct iscsi_cmnd *))
-{
- struct iscsi_cmnd *rsp;
- struct iscsi_scsi_rsp_hdr *rsp_hdr;
- u32 size;
-
- func(req);
- rsp = create_scsi_rsp(req);
-
- switch (req->status) {
- case SAM_STAT_GOOD:
- case SAM_STAT_RESERVATION_CONFLICT:
- rsp_hdr = (struct iscsi_scsi_rsp_hdr *) &rsp->pdu.bhs;
- if ((size = cmnd_read_size(req)) != 0) {
- rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
- rsp_hdr->residual_count = cpu_to_be32(size);
- }
- break;
- default:
- break;
- }
-
- iscsi_cmnd_init_write(rsp);
-}
-
-void send_data_rsp(struct iscsi_cmnd *req, void (*func)(struct iscsi_cmnd *))
-{
- struct iscsi_cmnd *rsp;
-
- func(req);
-
- if (req->status == SAM_STAT_GOOD)
- do_send_data_rsp(req);
- else {
- rsp = create_scsi_rsp(req);
- iscsi_cmnd_init_write(rsp);
- }
-}
-
-/**
- * Free a command.
- * Also frees the additional header.
- *
- * iscsi_cmnd_remove -
- * @cmnd: ptr to command
- */
-
-static void iscsi_cmnd_remove(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn;
-
- if (!cmnd)
- return;
-
- if (cmnd_timer_active(cmnd)) {
- clear_cmnd_timer_active(cmnd);
- del_timer_sync(&cmnd->timer);
- }
-
- dprintk(D_GENERIC, "%p\n", cmnd);
- conn = cmnd->conn;
- kfree(cmnd->pdu.ahs);
-
- if (!list_empty(&cmnd->list)) {
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
-
- eprintk("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x %lx\n",
- cmnd, req->opcode, req->scb[0], req->flags, req->itt,
- be32_to_cpu(req->data_length),
- req->cmd_sn, be32_to_cpu(cmnd->pdu.datasize),
- conn->state);
-
- if (cmnd->req) {
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->req);
- eprintk("%p %x %u\n", req, req->opcode, req->scb[0]);
- }
- dump_stack();
- BUG();
- }
- list_del(&cmnd->list);
- spin_lock(&conn->list_lock);
- atomic_dec(&conn->nr_cmnds);
- list_del(&cmnd->conn_list);
- spin_unlock(&conn->list_lock);
-
- if (cmnd->tio)
- tio_put(cmnd->tio);
-
- kmem_cache_free(iscsi_cmnd_cache, cmnd);
-}
-
-static void cmnd_skip_pdu(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct tio *tio = cmnd->tio;
- char *addr;
- u32 size;
- int i;
-
- eprintk("%x %x %x %u\n", cmnd_itt(cmnd), cmnd_opcode(cmnd),
- cmnd_hdr(cmnd)->scb[0], cmnd->pdu.datasize);
-
- if (!(size = cmnd->pdu.datasize))
- return;
-
- if (tio)
- assert(tio->pg_cnt > 0);
- else
- tio = cmnd->tio = tio_alloc(1);
-
- addr = page_address(tio->pvec[0]);
- assert(addr);
- size = (size + 3) & -4;
- conn->read_size = size;
- for (i = 0; size > PAGE_CACHE_SIZE; i++, size -= PAGE_CACHE_SIZE) {
- assert(i < ISCSI_CONN_IOV_MAX);
- conn->read_iov[i].iov_base = addr;
- conn->read_iov[i].iov_len = PAGE_CACHE_SIZE;
- }
- conn->read_iov[i].iov_base = addr;
- conn->read_iov[i].iov_len = size;
- conn->read_msg.msg_iov = conn->read_iov;
- conn->read_msg.msg_iovlen = ++i;
-}
-
-static void iscsi_cmnd_reject(struct iscsi_cmnd *req, int reason)
-{
- struct iscsi_cmnd *rsp;
- struct iscsi_reject_hdr *rsp_hdr;
- struct tio *tio;
- char *addr;
-
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 1);
- rsp_hdr = (struct iscsi_reject_hdr *)&rsp->pdu.bhs;
-
- rsp_hdr->opcode = ISCSI_OP_REJECT;
- rsp_hdr->ffffffff = ISCSI_RESERVED_TAG;
- rsp_hdr->reason = reason;
-
- rsp->tio = tio = tio_alloc(1);
- addr = page_address(tio->pvec[0]);
- clear_page(addr);
- memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr));
- tio->size = rsp->pdu.datasize = sizeof(struct iscsi_hdr);
- cmnd_skip_pdu(req);
-
- req->pdu.bhs.opcode = ISCSI_OP_PDU_REJECT;
-}
-
-static void cmnd_set_sn(struct iscsi_cmnd *cmnd, int set_stat_sn)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct iscsi_session *sess = conn->session;
-
- if (set_stat_sn)
- cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn++);
- cmnd->pdu.bhs.exp_sn = cpu_to_be32(sess->exp_cmd_sn);
- cmnd->pdu.bhs.max_sn = cpu_to_be32(sess->exp_cmd_sn + sess->max_queued_cmnds);
-}
-
-static void update_stat_sn(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- u32 exp_stat_sn;
-
- cmnd->pdu.bhs.exp_sn = exp_stat_sn = be32_to_cpu(cmnd->pdu.bhs.exp_sn);
- dprintk(D_GENERIC, "%x,%x\n", cmnd_opcode(cmnd), exp_stat_sn);
- if ((int)(exp_stat_sn - conn->exp_stat_sn) > 0 &&
- (int)(exp_stat_sn - conn->stat_sn) <= 0) {
- // free pdu resources
- cmnd->conn->exp_stat_sn = exp_stat_sn;
- }
-}
-
-static int check_cmd_sn(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_session *session = cmnd->conn->session;
- u32 cmd_sn;
-
- cmnd->pdu.bhs.sn = cmd_sn = be32_to_cpu(cmnd->pdu.bhs.sn);
-
- dprintk(D_GENERIC, "cmd_sn(%u) exp_cmd_sn(%u) max_cmd_sn(%u)\n",
- cmd_sn, session->exp_cmd_sn, session->max_cmd_sn);
-
- if (between(cmd_sn, session->exp_cmd_sn, session->max_cmd_sn))
- return 0;
- else if (cmnd_immediate(cmnd))
- return 0;
-
- eprintk("sequence error: cmd_sn(%u) exp_cmd_sn(%u) max_cmd_sn(%u)\n",
- cmd_sn, session->exp_cmd_sn, session->max_cmd_sn);
-
- set_cmnd_tmfabort(cmnd);
-
- return -ISCSI_REASON_PROTOCOL_ERROR;
-}
-
-static struct iscsi_cmnd *__cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt)
-{
- struct list_head *head;
- struct iscsi_cmnd *cmnd;
-
- head = &session->cmnd_hash[cmnd_hashfn(itt)];
-
- list_for_each_entry(cmnd, head, hash_list) {
- if (cmnd->pdu.bhs.itt == itt) {
- if ((ttt != ISCSI_RESERVED_TAG) && (ttt != cmnd->target_task_tag))
- continue;
- return cmnd;
- }
- }
-
- return NULL;
-}
-
-static struct iscsi_cmnd *cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt)
-{
- struct iscsi_cmnd *cmnd;
-
- spin_lock(&session->cmnd_hash_lock);
-
- cmnd = __cmnd_find_hash(session, itt, ttt);
-
- spin_unlock(&session->cmnd_hash_lock);
-
- return cmnd;
-}
-
-static int cmnd_insert_hash_ttt(struct iscsi_cmnd *cmnd, u32 ttt)
-{
- struct iscsi_session *session = cmnd->conn->session;
- struct iscsi_cmnd *tmp;
- struct list_head *head;
- int err = 0;
- u32 itt = cmnd->pdu.bhs.itt;
-
- head = &session->cmnd_hash[cmnd_hashfn(itt)];
-
- spin_lock(&session->cmnd_hash_lock);
-
- tmp = __cmnd_find_hash(session, itt, ttt);
- if (!tmp) {
- list_add_tail(&cmnd->hash_list, head);
- set_cmnd_hashed(cmnd);
- } else
- err = -ISCSI_REASON_TASK_IN_PROGRESS;
-
- spin_unlock(&session->cmnd_hash_lock);
-
- return err;
-}
-
-static int cmnd_insert_hash(struct iscsi_cmnd *cmnd)
-{
- int err;
-
- dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd->pdu.bhs.itt);
-
- if (cmnd->pdu.bhs.itt == ISCSI_RESERVED_TAG)
- return -ISCSI_REASON_PROTOCOL_ERROR;
-
- err = cmnd_insert_hash_ttt(cmnd, ISCSI_RESERVED_TAG);
- if (!err) {
- update_stat_sn(cmnd);
- err = check_cmd_sn(cmnd);
- } else if (!cmnd_immediate(cmnd))
- set_cmnd_tmfabort(cmnd);
-
- return err;
-}
-
-static void __cmnd_remove_hash(struct iscsi_cmnd *cmnd)
-{
- list_del(&cmnd->hash_list);
-}
-
-static void cmnd_remove_hash(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_session *session = cmnd->conn->session;
- struct iscsi_cmnd *tmp;
-
- spin_lock(&session->cmnd_hash_lock);
-
- tmp = __cmnd_find_hash(session, cmnd->pdu.bhs.itt,
- cmnd->target_task_tag);
- if (tmp && tmp == cmnd)
- __cmnd_remove_hash(tmp);
- else
- eprintk("%p:%x not found\n", cmnd, cmnd_itt(cmnd));
-
- spin_unlock(&session->cmnd_hash_lock);
-}
-
-static void cmnd_skip_data(struct iscsi_cmnd *req)
-{
- struct iscsi_cmnd *rsp;
- struct iscsi_scsi_rsp_hdr *rsp_hdr;
- u32 size;
-
- rsp = get_rsp_cmnd(req);
- rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
- if (cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP) {
- eprintk("unexpected response command %u\n", cmnd_opcode(rsp));
- return;
- }
-
- size = cmnd_write_size(req);
- if (size) {
- rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
- rsp_hdr->residual_count = cpu_to_be32(size);
- }
- size = cmnd_read_size(req);
- if (size) {
- if (cmnd_hdr(req)->flags & ISCSI_CMD_WRITE) {
- rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_UNDERFLOW;
- rsp_hdr->bi_residual_count = cpu_to_be32(size);
- } else {
- rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW;
- rsp_hdr->residual_count = cpu_to_be32(size);
- }
- }
- req->pdu.bhs.opcode =
- (req->pdu.bhs.opcode & ~ISCSI_OPCODE_MASK) | ISCSI_OP_SCSI_REJECT;
-
- cmnd_skip_pdu(req);
-}
-
-static int cmnd_recv_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size)
-{
- int idx, i;
- char *addr;
-
- dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size);
- offset += tio->offset;
-
- if (!(offset < tio->offset + tio->size) ||
- !(offset + size <= tio->offset + tio->size)) {
- eprintk("%u %u %u %u", offset, size, tio->offset, tio->size);
- return -EIO;
- }
- assert(offset < tio->offset + tio->size);
- assert(offset + size <= tio->offset + tio->size);
-
- idx = offset >> PAGE_CACHE_SHIFT;
- offset &= ~PAGE_CACHE_MASK;
-
- conn->read_msg.msg_iov = conn->read_iov;
- conn->read_size = size = (size + 3) & -4;
- conn->read_overflow = 0;
-
- i = 0;
- while (1) {
- assert(tio->pvec[idx]);
- addr = page_address(tio->pvec[idx]);
- assert(addr);
- conn->read_iov[i].iov_base = addr + offset;
- if (offset + size <= PAGE_CACHE_SIZE) {
- conn->read_iov[i].iov_len = size;
- conn->read_msg.msg_iovlen = ++i;
- break;
- }
- conn->read_iov[i].iov_len = PAGE_CACHE_SIZE - offset;
- size -= conn->read_iov[i].iov_len;
- offset = 0;
- if (++i >= ISCSI_CONN_IOV_MAX) {
- conn->read_msg.msg_iovlen = i;
- conn->read_overflow = size;
- conn->read_size -= size;
- break;
- }
-
- idx++;
- }
-
- return 0;
-}
-
-static void set_offset_and_length(struct iet_volume *lu, u8 *cmd, loff_t *off, u32 *len)
-{
- assert(lu);
-
- switch (cmd[0]) {
- case READ_6:
- case WRITE_6:
- *off = ((cmd[1] & 0x1f) << 16) + (cmd[2] << 8) + cmd[3];
- *len = cmd[4];
- if (!*len)
- *len = 256;
- break;
- case READ_10:
- case WRITE_10:
- case WRITE_VERIFY:
- *off = (u32)cmd[2] << 24 | (u32)cmd[3] << 16 |
- (u32)cmd[4] << 8 | (u32)cmd[5];
- *len = (cmd[7] << 8) + cmd[8];
- break;
- case READ_16:
- case WRITE_16:
- *off = (u64)cmd[2] << 56 | (u64)cmd[3] << 48 |
- (u64)cmd[4] << 40 | (u64)cmd[5] << 32 |
- (u64)cmd[6] << 24 | (u64)cmd[7] << 16 |
- (u64)cmd[8] << 8 | (u64)cmd[9];
- *len = (u32)cmd[10] << 24 | (u32)cmd[11] << 16 |
- (u32)cmd[12] << 8 | (u32)cmd[13];
- break;
- default:
- BUG();
- }
-
- *off <<= lu->blk_shift;
- *len <<= lu->blk_shift;
-}
-
-static u32 translate_lun(u16 * data)
-{
- u8 *p = (u8 *) data;
- u32 lun = ~0U;
-
- switch (*p >> 6) {
- case 0:
- lun = p[1];
- break;
- case 1:
- lun = (0x3f & p[0]) << 8 | p[1];
- break;
- case 2:
- case 3:
- default:
- eprintk("%u %u %u %u\n", data[0], data[1], data[2], data[3]);
- break;
- }
-
- return lun;
-}
-
-static void send_r2t(struct iscsi_cmnd *req)
-{
- struct iscsi_cmnd *rsp;
- struct iscsi_r2t_hdr *rsp_hdr;
- u32 length, offset, burst;
- LIST_HEAD(send);
-
- length = req->r2t_length;
- burst = req->conn->session->param.max_burst_length;
- offset = be32_to_cpu(cmnd_hdr(req)->data_length) - length;
-
- do {
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 0);
- rsp->pdu.bhs.ttt = req->target_task_tag;
-
- rsp_hdr = (struct iscsi_r2t_hdr *)&rsp->pdu.bhs;
- rsp_hdr->opcode = ISCSI_OP_R2T;
- rsp_hdr->flags = ISCSI_FLG_FINAL;
- memcpy(rsp_hdr->lun, cmnd_hdr(req)->lun, 8);
- rsp_hdr->itt = cmnd_hdr(req)->itt;
- rsp_hdr->r2t_sn = cpu_to_be32(req->r2t_sn++);
- rsp_hdr->buffer_offset = cpu_to_be32(offset);
- if (length > burst) {
- rsp_hdr->data_length = cpu_to_be32(burst);
- length -= burst;
- offset += burst;
- } else {
- rsp_hdr->data_length = cpu_to_be32(length);
- length = 0;
- }
-
- dprintk(D_WRITE, "%x %u %u %u %u\n", cmnd_itt(req),
- be32_to_cpu(rsp_hdr->data_length),
- be32_to_cpu(rsp_hdr->buffer_offset),
- be32_to_cpu(rsp_hdr->r2t_sn), req->outstanding_r2t);
-
- list_add_tail(&rsp->list, &send);
-
- if (++req->outstanding_r2t >= req->conn->session->param.max_outstanding_r2t)
- break;
-
- } while (length);
-
- iscsi_cmnds_init_write(&send);
-}
-
-static void scsi_cmnd_exec(struct iscsi_cmnd *cmnd)
-{
- assert(!cmnd->r2t_length);
-
- if (cmnd->lun) {
- iscsi_scsi_queuecmnd(cmnd);
- } else {
- iscsi_device_queue_cmnd(cmnd);
- }
-}
-
-static int nop_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
-{
- u32 size, tmp;
- int i, err = 0;
-
- if (cmnd_ttt(cmnd) != cpu_to_be32(ISCSI_RESERVED_TAG)) {
- cmnd->req = cmnd_find_hash(conn->session, cmnd->pdu.bhs.itt,
- cmnd->pdu.bhs.ttt);
- if (!cmnd->req) {
- /*
- * We didn't request this NOP-Out (by sending a
- * NOP-In, see 10.18.2 of the RFC) or our fake NOP-Out
- * timed out.
- */
- eprintk("initiator bug %x\n", cmnd_itt(cmnd));
- err = -ISCSI_REASON_PROTOCOL_ERROR;
- goto out;
- }
-
- del_timer_sync(&cmnd->req->timer);
- clear_cmnd_timer_active(cmnd->req);
- dprintk(D_GENERIC, "NOP-Out: %p, ttt %x, timer %p\n",
- cmnd->req, cmnd_ttt(cmnd->req), &cmnd->req->timer);
- }
-
- if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) {
- if (!cmnd_immediate(cmnd))
- eprintk("%s\n", "initiator bug!");
- update_stat_sn(cmnd);
- err = check_cmd_sn(cmnd);
- if (err)
- goto out;
- } else if ((err = cmnd_insert_hash(cmnd)) < 0) {
- eprintk("ignore this request %x\n", cmnd_itt(cmnd));
- goto out;
- }
-
- if ((size = cmnd->pdu.datasize)) {
- size = (size + 3) & -4;
- conn->read_msg.msg_iov = conn->read_iov;
- if (cmnd->pdu.bhs.itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
- struct tio *tio;
- int pg_cnt = get_pgcnt(size, 0);
-
- assert(pg_cnt < ISCSI_CONN_IOV_MAX);
- cmnd->tio = tio = tio_alloc(pg_cnt);
- tio_set(tio, size, 0);
-
- for (i = 0; i < pg_cnt; i++) {
- conn->read_iov[i].iov_base
- = page_address(tio->pvec[i]);
- tmp = min_t(u32, size, PAGE_CACHE_SIZE);
- conn->read_iov[i].iov_len = tmp;
- conn->read_size += tmp;
- size -= tmp;
- }
- } else {
- for (i = 0; i < ISCSI_CONN_IOV_MAX; i++) {
- conn->read_iov[i].iov_base = dummy_data;
- tmp = min_t(u32, size, sizeof(dummy_data));
- conn->read_iov[i].iov_len = tmp;
- conn->read_size += tmp;
- size -= tmp;
- }
- }
- assert(!size);
- conn->read_overflow = size;
- conn->read_msg.msg_iovlen = i;
- }
-
-out:
- return err;
-}
-
-static u32 get_next_ttt(struct iscsi_session *session)
-{
- u32 ttt;
-
- if (session->next_ttt == ISCSI_RESERVED_TAG)
- session->next_ttt++;
- ttt = session->next_ttt++;
-
- return cpu_to_be32(ttt);
-}
-
-static void scsi_cmnd_start(struct iscsi_conn *conn, struct iscsi_cmnd *req)
-{
- struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req);
-
- dprintk(D_GENERIC, "scsi command: %02x\n", req_hdr->scb[0]);
-
- req->lun = volume_get(conn->session->target, translate_lun(req_hdr->lun));
- if (!req->lun) {
- switch (req_hdr->scb[0]) {
- case INQUIRY:
- case REPORT_LUNS:
- break;
- default:
- eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]);
- create_sense_rsp(req, ILLEGAL_REQUEST, 0x25, 0x0);
- cmnd_skip_data(req);
- goto out;
- }
- } else
- set_cmnd_lunit(req);
-
- switch (req_hdr->scb[0]) {
- case SERVICE_ACTION_IN:
- if ((req_hdr->scb[1] & 0x1f) != 0x10)
- goto error;
- case INQUIRY:
- case REPORT_LUNS:
- case TEST_UNIT_READY:
- case SYNCHRONIZE_CACHE:
- case VERIFY:
- case VERIFY_16:
- case START_STOP:
- case READ_CAPACITY:
- case MODE_SENSE:
- case REQUEST_SENSE:
- case RESERVE:
- case RELEASE:
- {
- if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) {
- /* unexpected unsolicited data */
- eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]);
- create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc);
- cmnd_skip_data(req);
- }
- break;
- }
- case READ_6:
- case READ_10:
- case READ_16:
- {
- loff_t offset;
- u32 length;
-
- if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) {
- /* unexpected unsolicited data */
- eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]);
- create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc);
- cmnd_skip_data(req);
- break;
- }
-
- set_offset_and_length(req->lun, req_hdr->scb, &offset, &length);
- req->tio = tio_alloc(get_pgcnt(length, offset));
- tio_set(req->tio, length, offset);
- break;
- }
- case WRITE_6:
- case WRITE_10:
- case WRITE_16:
- case WRITE_VERIFY:
- {
- struct iscsi_sess_param *param = &conn->session->param;
- loff_t offset;
- u32 length;
-
- req->r2t_length = be32_to_cpu(req_hdr->data_length) - req->pdu.datasize;
- req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL);
- req->target_task_tag = get_next_ttt(conn->session);
-
- if (LUReadonly(req->lun)) {
- create_sense_rsp(req, DATA_PROTECT, 0x27, 0x0);
- cmnd_skip_data(req);
- break;
- }
-
- if (!param->immediate_data && req->pdu.datasize)
- eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]);
-
- if (param->initial_r2t && !(req_hdr->flags & ISCSI_CMD_FINAL))
- eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]);
-
- if (req_hdr->scb[0] == WRITE_VERIFY && req_hdr->scb[1] & 0x02)
- eprintk("Verification is ignored %x\n", cmnd_itt(req));
-
- set_offset_and_length(req->lun, req_hdr->scb, &offset, &length);
- if (cmnd_write_size(req) != length)
- eprintk("%x %u %u\n", cmnd_itt(req), cmnd_write_size(req), length);
-
- req->tio = tio_alloc(get_pgcnt(length, offset));
- tio_set(req->tio, length, offset);
-
- if (req->pdu.datasize) {
- if (cmnd_recv_pdu(conn, req->tio, 0, req->pdu.datasize) < 0)
- assert(0);
- }
- break;
- }
- error:
- default:
- eprintk("Unsupported %x\n", req_hdr->scb[0]);
- create_sense_rsp(req, ILLEGAL_REQUEST, 0x20, 0x0);
- cmnd_skip_data(req);
- break;
- }
-
-out:
- return;
-}
-
-static void data_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
-{
- struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs;
- struct iscsi_cmnd *scsi_cmnd = NULL;
- u32 offset = be32_to_cpu(req->buffer_offset);
-
- update_stat_sn(cmnd);
-
- cmnd->req = scsi_cmnd = cmnd_find_hash(conn->session, req->itt, req->ttt);
- if (!scsi_cmnd) {
- eprintk("unable to find scsi task %x %x\n",
- cmnd_itt(cmnd), cmnd_ttt(cmnd));
- goto skip_data;
- }
-
- if (scsi_cmnd->r2t_length < cmnd->pdu.datasize) {
- eprintk("invalid data len %x %u %u\n",
- cmnd_itt(scsi_cmnd), cmnd->pdu.datasize, scsi_cmnd->r2t_length);
- goto skip_data;
- }
-
- if (scsi_cmnd->r2t_length + offset != cmnd_write_size(scsi_cmnd)) {
- eprintk("%x %u %u %u\n", cmnd_itt(scsi_cmnd), scsi_cmnd->r2t_length,
- offset, cmnd_write_size(scsi_cmnd));
- goto skip_data;
- }
-
- scsi_cmnd->r2t_length -= cmnd->pdu.datasize;
-
- if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) {
- /* unsolicited burst data */
- if (scsi_cmnd->pdu.bhs.flags & ISCSI_FLG_FINAL) {
- eprintk("unexpected data from %x %x\n",
- cmnd_itt(cmnd), cmnd_ttt(cmnd));
- goto skip_data;
- }
- }
-
- dprintk(D_WRITE, "%u %p %p %p %u %u\n", req->ttt, cmnd, scsi_cmnd,
- scsi_cmnd->tio, offset, cmnd->pdu.datasize);
-
- if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, cmnd->pdu.datasize) < 0)
- goto skip_data;
- return;
-
-skip_data:
- cmnd->pdu.bhs.opcode = ISCSI_OP_DATA_REJECT;
- cmnd_skip_pdu(cmnd);
- return;
-}
-
-static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd);
-
-static void data_out_end(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
-{
- struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs;
- struct iscsi_cmnd *scsi_cmnd;
- u32 offset;
-
- assert(cmnd);
- scsi_cmnd = cmnd->req;
- assert(scsi_cmnd);
-
- if (conn->read_overflow) {
- eprintk("%x %u\n", cmnd_itt(cmnd), conn->read_overflow);
- assert(scsi_cmnd->tio);
- offset = be32_to_cpu(req->buffer_offset);
- offset += cmnd->pdu.datasize - conn->read_overflow;
- if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, conn->read_overflow) < 0)
- assert(0);
- return;
- }
-
- if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) {
- if (req->flags & ISCSI_FLG_FINAL) {
- scsi_cmnd->is_unsolicited_data = 0;
- iscsi_session_push_cmnd(scsi_cmnd);
- }
- } else {
- /* TODO : proper error handling */
- if (!(req->flags & ISCSI_FLG_FINAL) && scsi_cmnd->r2t_length == 0)
- eprintk("initiator error %x\n", cmnd_itt(scsi_cmnd));
-
- if (!(req->flags & ISCSI_FLG_FINAL))
- goto out;
-
- scsi_cmnd->outstanding_r2t--;
-
- if (scsi_cmnd->r2t_length == 0)
- assert(list_empty(&scsi_cmnd->pdu_list));
-
- iscsi_session_push_cmnd(scsi_cmnd);
- }
-
-out:
- iscsi_cmnd_remove(cmnd);
- return;
-}
-
-static void __cmnd_abort(struct iscsi_cmnd *cmnd)
-{
- if (cmnd_rxstart(cmnd))
- set_cmnd_tmfabort(cmnd);
-
- if (cmnd_waitio(cmnd))
- return;
-
- if (cmnd->conn->read_cmnd != cmnd)
- cmnd_release(cmnd, 1);
-}
-
-static int cmnd_abort(struct iscsi_session *session, struct iscsi_cmnd *req)
-{
- struct iscsi_task_mgt_hdr *req_hdr =
- (struct iscsi_task_mgt_hdr *)&req->pdu.bhs;
- struct iscsi_cmnd *cmnd;
-
- u32 min_cmd_sn = req_hdr->cmd_sn - session->max_queued_cmnds;
-
- req_hdr->ref_cmd_sn = be32_to_cpu(req_hdr->ref_cmd_sn);
-
- dprintk(D_GENERIC, "cmd_sn(%u) ref_cmd_sn(%u) min_cmd_sn(%u) rtt(%x)"
- " lun(%d) cid(%u)\n",
- req_hdr->cmd_sn, req_hdr->ref_cmd_sn, min_cmd_sn, req_hdr->rtt,
- translate_lun(req_hdr->lun), req->conn->cid);
-
- if (after(req_hdr->ref_cmd_sn, req_hdr->cmd_sn))
- return ISCSI_RESPONSE_FUNCTION_REJECTED;
-
- if (!(cmnd = cmnd_find_hash(session, req_hdr->rtt, ISCSI_RESERVED_TAG))) {
- if (between(req_hdr->ref_cmd_sn, min_cmd_sn, req_hdr->cmd_sn))
- return ISCSI_RESPONSE_FUNCTION_COMPLETE;
- else
- return ISCSI_RESPONSE_UNKNOWN_TASK;
- }
-
- dprintk(D_GENERIC, "itt(%x) opcode(%x) scsicode(%x) lun(%d) cid(%u)\n",
- cmnd_itt(cmnd), cmnd_opcode(cmnd), cmnd_scsicode(cmnd),
- translate_lun(cmnd_hdr(cmnd)->lun), cmnd->conn->cid);
-
- if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_TASK_MGT_MSG)
- return ISCSI_RESPONSE_FUNCTION_REJECTED;
-
- if (translate_lun(cmnd_hdr(cmnd)->lun) !=
- translate_lun(req_hdr->lun))
- return ISCSI_RESPONSE_FUNCTION_REJECTED;
-
- if (cmnd->conn && test_bit(CONN_ACTIVE, &cmnd->conn->state)) {
- if (cmnd->conn->cid != req->conn->cid)
- return ISCSI_RESPONSE_FUNCTION_REJECTED;
- } else {
- /* Switch cmnd connection allegiance */
- }
-
- __cmnd_abort(cmnd);
-
- return ISCSI_RESPONSE_FUNCTION_COMPLETE;
-}
-
-static int target_reset(struct iscsi_cmnd *req, u32 lun, int all)
-{
- struct iscsi_target *target = req->conn->session->target;
- struct iscsi_session *session;
- struct iscsi_conn *conn;
- struct iscsi_cmnd *cmnd, *tmp;
- struct iet_volume *volume;
-
- list_for_each_entry(session, &target->session_list, list) {
- list_for_each_entry(conn, &session->conn_list, list) {
- list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) {
- if (cmnd == req)
- continue;
-
- if (all)
- __cmnd_abort(cmnd);
- else if (translate_lun(cmnd_hdr(cmnd)->lun)
- == lun)
- __cmnd_abort(cmnd);
- }
- }
- }
-
- list_for_each_entry(volume, &target->volumes, list) {
- if (all || volume->lun == lun) {
- /* force release */
- volume_release(volume, 0, 1);
- /* power-on, reset, or bus device reset occurred */
- ua_establish_for_all_sessions(target, volume->lun,
- 0x29, 0x0);
- }
- }
-
- return 0;
-}
-
-static void task_set_abort(struct iscsi_cmnd *req)
-{
- struct iscsi_session *session = req->conn->session;
- struct iscsi_conn *conn;
- struct iscsi_cmnd *cmnd, *tmp;
-
- list_for_each_entry(conn, &session->conn_list, list) {
- list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) {
- if (translate_lun(cmnd_hdr(cmnd)->lun)
- != translate_lun(cmnd_hdr(req)->lun))
- continue;
-
- if (before(cmnd_hdr(cmnd)->cmd_sn,
- cmnd_hdr(req)->cmd_sn))
- __cmnd_abort(cmnd);
- }
- }
-}
-
-static inline char *tmf_desc(int fun)
-{
- static char *tmf_desc[] = {
- "Unknown Function",
- "Abort Task",
- "Abort Task Set",
- "Clear ACA",
- "Clear Task Set",
- "Logical Unit Reset",
- "Target Warm Reset",
- "Target Cold Reset",
- "Task Reassign",
- };
-
- if ((fun < ISCSI_FUNCTION_ABORT_TASK) ||
- (fun > ISCSI_FUNCTION_TASK_REASSIGN))
- fun = 0;
-
- return tmf_desc[fun];
-}
-
-static inline char *rsp_desc(int rsp)
-{
- static char *rsp_desc[] = {
- "Function Complete",
- "Unknown Task",
- "Unknown LUN",
- "Task Allegiant",
- "Failover Unsupported",
- "Function Unsupported",
- "No Authorization",
- "Function Rejected",
- "Unknown Response",
- };
-
- if (((rsp < ISCSI_RESPONSE_FUNCTION_COMPLETE) ||
- (rsp > ISCSI_RESPONSE_NO_AUTHORIZATION)) &&
- (rsp != ISCSI_RESPONSE_FUNCTION_REJECTED))
- rsp = 8;
- else if (rsp == ISCSI_RESPONSE_FUNCTION_REJECTED)
- rsp = 7;
-
- return rsp_desc[rsp];
-}
-
-static void execute_task_management(struct iscsi_cmnd *req)
-{
- struct iscsi_conn *conn = req->conn;
- struct iscsi_session *session = conn->session;
- struct iscsi_target *target = session->target;
- struct iscsi_cmnd *rsp;
- struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs;
- struct iscsi_task_rsp_hdr *rsp_hdr;
- u32 lun;
- int function = req_hdr->function & ISCSI_FUNCTION_MASK;
-
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 1);
- rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs;
-
- rsp_hdr->opcode = ISCSI_OP_SCSI_TASK_MGT_RSP;
- rsp_hdr->flags = ISCSI_FLG_FINAL;
- rsp_hdr->itt = req_hdr->itt;
- rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_COMPLETE;
-
- switch (function) {
- case ISCSI_FUNCTION_ABORT_TASK:
- case ISCSI_FUNCTION_ABORT_TASK_SET:
- case ISCSI_FUNCTION_CLEAR_ACA:
- case ISCSI_FUNCTION_CLEAR_TASK_SET:
- case ISCSI_FUNCTION_LOGICAL_UNIT_RESET:
- lun = translate_lun(req_hdr->lun);
- if (!volume_lookup(target, lun)) {
- rsp_hdr->response = ISCSI_RESPONSE_UNKNOWN_LUN;
- goto out;
- }
- }
-
- switch (function) {
- case ISCSI_FUNCTION_ABORT_TASK:
- rsp_hdr->response = cmnd_abort(conn->session, req);
- break;
- case ISCSI_FUNCTION_ABORT_TASK_SET:
- task_set_abort(req);
- break;
- case ISCSI_FUNCTION_CLEAR_ACA:
- rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED;
- break;
- case ISCSI_FUNCTION_CLEAR_TASK_SET:
- rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED;
- break;
- case ISCSI_FUNCTION_LOGICAL_UNIT_RESET:
- target_reset(req, translate_lun(req_hdr->lun), 0);
- break;
- case ISCSI_FUNCTION_TARGET_WARM_RESET:
- case ISCSI_FUNCTION_TARGET_COLD_RESET:
- target_reset(req, 0, 1);
- if (function == ISCSI_FUNCTION_TARGET_COLD_RESET)
- set_cmnd_close(rsp);
- break;
- case ISCSI_FUNCTION_TASK_REASSIGN:
- rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED;
- break;
- default:
- rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED;
- break;
- }
-out:
- iprintk("%s (%02x) issued on tid:%d lun:%d by sid:%llu (%s)\n",
- tmf_desc(function), function, target->tid,
- translate_lun(req_hdr->lun), session->sid,
- rsp_desc(rsp_hdr->response));
-
- iscsi_cmnd_init_write(rsp);
-}
-
-static void nop_hdr_setup(struct iscsi_hdr *hdr, u8 opcode, __be32 itt,
- __be32 ttt)
-{
- hdr->opcode = opcode;
- hdr->flags = ISCSI_FLG_FINAL;
- hdr->itt = itt;
- hdr->ttt = ttt;
-}
-
-static void nop_out_exec(struct iscsi_cmnd *req)
-{
- struct iscsi_cmnd *rsp;
-
- if (cmnd_itt(req) != cpu_to_be32(ISCSI_RESERVED_TAG)) {
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 1);
-
- nop_hdr_setup(&rsp->pdu.bhs, ISCSI_OP_NOP_IN, req->pdu.bhs.itt,
- cpu_to_be32(ISCSI_RESERVED_TAG));
-
- if (req->pdu.datasize)
- assert(req->tio);
- else
- assert(!req->tio);
-
- if (req->tio) {
- tio_get(req->tio);
- rsp->tio = req->tio;
- }
-
- assert(get_pgcnt(req->pdu.datasize, 0) < ISCSI_CONN_IOV_MAX);
- rsp->pdu.datasize = req->pdu.datasize;
- iscsi_cmnd_init_write(rsp);
- } else {
- if (req->req) {
- dprintk(D_GENERIC, "releasing NOP-Out %p, ttt %x; "
- "removing NOP-In %p, ttt %x\n", req->req,
- cmnd_ttt(req->req), req, cmnd_ttt(req));
- cmnd_release(req->req, 0);
- }
- iscsi_cmnd_remove(req);
- }
-}
-
-static void nop_in_timeout(unsigned long data)
-{
- struct iscsi_cmnd *req = (struct iscsi_cmnd *)data;
-
- printk(KERN_INFO "NOP-In ping timed out - closing sid:cid %llu:%u\n",
- req->conn->session->sid, req->conn->cid);
- clear_cmnd_timer_active(req);
- conn_close(req->conn);
-}
-
-/* create a fake NOP-Out req and treat the NOP-In as our rsp to it */
-void send_nop_in(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *req = cmnd_alloc(conn, 1);
- struct iscsi_cmnd *rsp = iscsi_cmnd_create_rsp_cmnd(req, 0);
-
- req->target_task_tag = get_next_ttt(conn->session);
-
-
- nop_hdr_setup(&req->pdu.bhs, ISCSI_OP_NOP_OUT,
- cpu_to_be32(ISCSI_RESERVED_TAG), req->target_task_tag);
- nop_hdr_setup(&rsp->pdu.bhs, ISCSI_OP_NOP_IN,
- cpu_to_be32(ISCSI_RESERVED_TAG), req->target_task_tag);
-
- dprintk(D_GENERIC, "NOP-Out: %p, ttt %x, timer %p; "
- "NOP-In: %p, ttt %x;\n", req, cmnd_ttt(req), &req->timer, rsp,
- cmnd_ttt(rsp));
-
- init_timer(&req->timer);
- req->timer.data = (unsigned long)req;
- req->timer.function = nop_in_timeout;
-
- if (cmnd_insert_hash_ttt(req, req->target_task_tag)) {
- eprintk("%s\n",
- "failed to insert fake NOP-Out into hash table");
- cmnd_release(rsp, 0);
- cmnd_release(req, 0);
- } else
- iscsi_cmnd_init_write(rsp);
-}
-
-static void nop_in_tx_end(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- u32 t;
-
- if (cmnd->pdu.bhs.ttt == cpu_to_be32(ISCSI_RESERVED_TAG))
- return;
-
- /*
- * NOP-In ping issued by the target.
- * FIXME: Sanitize the NOP timeout earlier, during configuration
- */
- t = conn->session->target->trgt_param.nop_timeout;
-
- if (!t || t > conn->session->target->trgt_param.nop_interval) {
- eprintk("Adjusting NOPTimeout of tid %u from %u to %u "
- "(== NOPInterval)\n", conn->session->target->tid,
- t,
- conn->session->target->trgt_param.nop_interval);
- t = conn->session->target->trgt_param.nop_interval;
- conn->session->target->trgt_param.nop_timeout = t;
- }
-
- dprintk(D_GENERIC, "NOP-In %p, %x: timer %p\n", cmnd, cmnd_ttt(cmnd),
- &cmnd->req->timer);
-
- set_cmnd_timer_active(cmnd->req);
- mod_timer(&cmnd->req->timer, jiffies + HZ * t);
-}
-
-static void logout_exec(struct iscsi_cmnd *req)
-{
- struct iscsi_logout_req_hdr *req_hdr;
- struct iscsi_cmnd *rsp;
- struct iscsi_logout_rsp_hdr *rsp_hdr;
-
- req_hdr = (struct iscsi_logout_req_hdr *)&req->pdu.bhs;
- rsp = iscsi_cmnd_create_rsp_cmnd(req, 1);
- rsp_hdr = (struct iscsi_logout_rsp_hdr *)&rsp->pdu.bhs;
- rsp_hdr->opcode = ISCSI_OP_LOGOUT_RSP;
- rsp_hdr->flags = ISCSI_FLG_FINAL;
- rsp_hdr->itt = req_hdr->itt;
- set_cmnd_close(rsp);
- iscsi_cmnd_init_write(rsp);
-}
-
-static void iscsi_cmnd_exec(struct iscsi_cmnd *cmnd)
-{
- dprintk(D_GENERIC, "%p,%x,%u\n", cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn);
-
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_NOP_OUT:
- nop_out_exec(cmnd);
- break;
- case ISCSI_OP_SCSI_CMD:
- scsi_cmnd_exec(cmnd);
- break;
- case ISCSI_OP_SCSI_TASK_MGT_MSG:
- execute_task_management(cmnd);
- break;
- case ISCSI_OP_LOGOUT_CMD:
- logout_exec(cmnd);
- break;
- case ISCSI_OP_SCSI_REJECT:
- iscsi_cmnd_init_write(get_rsp_cmnd(cmnd));
- break;
- case ISCSI_OP_TEXT_CMD:
- case ISCSI_OP_SNACK_CMD:
- break;
- default:
- eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd));
- break;
- }
-}
-
-static void __cmnd_send_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size)
-{
- dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size);
- offset += tio->offset;
-
- assert(offset <= tio->offset + tio->size);
- assert(offset + size <= tio->offset + tio->size);
-
- conn->write_tcmnd = tio;
- conn->write_offset = offset;
- conn->write_size += size;
-}
-
-static void cmnd_send_pdu(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
-{
- u32 size;
- struct tio *tio;
-
- if (!cmnd->pdu.datasize)
- return;
-
- size = (cmnd->pdu.datasize + 3) & -4;
- tio = cmnd->tio;
- assert(tio);
- assert(tio->size == size);
- __cmnd_send_pdu(conn, tio, 0, size);
-}
-
-static void set_cork(struct socket *sock, int on)
-{
- int opt = on;
- mm_segment_t oldfs;
-
- oldfs = get_fs();
- set_fs(get_ds());
- sock->ops->setsockopt(sock, SOL_TCP, TCP_CORK, (void *)&opt, sizeof(opt));
- set_fs(oldfs);
-}
-
-void cmnd_release(struct iscsi_cmnd *cmnd, int force)
-{
- struct iscsi_cmnd *req, *rsp;
- int is_last = 0;
-
- if (!cmnd)
- return;
-
-/* eprintk("%x %lx %d\n", cmnd_opcode(cmnd), cmnd->flags, force); */
-
- req = cmnd->req;
- is_last = cmnd_final(cmnd);
-
- if (force) {
- while (!list_empty(&cmnd->pdu_list)) {
- rsp = list_entry(cmnd->pdu_list.next, struct iscsi_cmnd, pdu_list);
- list_del_init(&rsp->list);
- list_del(&rsp->pdu_list);
- iscsi_cmnd_remove(rsp);
- }
- list_del_init(&cmnd->list);
- } else
- if (cmnd_queued(cmnd))
- iscsi_scsi_dequeuecmnd(cmnd);
-
- if (cmnd_hashed(cmnd))
- cmnd_remove_hash(cmnd);
-
- if (cmnd_lunit(cmnd)) {
- assert(cmnd->lun);
- volume_put(cmnd->lun);
- }
-
- list_del_init(&cmnd->pdu_list);
- iscsi_cmnd_remove(cmnd);
-
- if (is_last) {
- assert(!force);
- assert(req);
- cmnd_release(req, 0);
- }
-
- return;
-}
-
-void cmnd_tx_start(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct iovec *iop;
-
- dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd));
- assert(cmnd);
- iscsi_cmnd_set_length(&cmnd->pdu);
-
- set_cork(conn->sock, 1);
-
- conn->write_iop = iop = conn->write_iov;
- iop->iov_base = &cmnd->pdu.bhs;
- iop->iov_len = sizeof(cmnd->pdu.bhs);
- iop++;
- conn->write_size = sizeof(cmnd->pdu.bhs);
-
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_NOP_IN:
- if (cmnd->pdu.bhs.itt == ISCSI_RESERVED_TAG) {
- /* NOP-In ping generated by us. Don't advance StatSN. */
- cmnd_set_sn(cmnd, 0);
- cmnd_set_sn(cmnd->req, 0);
- cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn);
- cmnd->req->pdu.bhs.sn = cpu_to_be32(conn->stat_sn);
- } else
- cmnd_set_sn(cmnd, 1);
- cmnd_send_pdu(conn, cmnd);
- break;
- case ISCSI_OP_SCSI_RSP:
- cmnd_set_sn(cmnd, 1);
- cmnd_send_pdu(conn, cmnd);
- break;
- case ISCSI_OP_SCSI_TASK_MGT_RSP:
- cmnd_set_sn(cmnd, 1);
- break;
- case ISCSI_OP_TEXT_RSP:
- cmnd_set_sn(cmnd, 1);
- break;
- case ISCSI_OP_SCSI_DATA_IN:
- {
- struct iscsi_data_in_hdr *rsp = (struct iscsi_data_in_hdr *)&cmnd->pdu.bhs;
- u32 offset;
-
- cmnd_set_sn(cmnd, (rsp->flags & ISCSI_FLG_FINAL) ? 1 : 0);
- offset = rsp->buffer_offset;
- rsp->buffer_offset = cpu_to_be32(offset);
- __cmnd_send_pdu(conn, cmnd->tio, offset, cmnd->pdu.datasize);
- break;
- }
- case ISCSI_OP_LOGOUT_RSP:
- cmnd_set_sn(cmnd, 1);
- break;
- case ISCSI_OP_R2T:
- cmnd_set_sn(cmnd, 0);
- cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn);
- break;
- case ISCSI_OP_ASYNC_MSG:
- cmnd_set_sn(cmnd, 1);
- break;
- case ISCSI_OP_REJECT:
- cmnd_set_sn(cmnd, 1);
- cmnd_send_pdu(conn, cmnd);
- break;
- default:
- eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd));
- break;
- }
-
- iop->iov_len = 0;
- // move this?
- conn->write_size = (conn->write_size + 3) & -4;
- iscsi_dump_pdu(&cmnd->pdu);
-}
-
-void cmnd_tx_end(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
-
- dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd));
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_NOP_IN:
- nop_in_tx_end(cmnd);
- break;
- case ISCSI_OP_SCSI_RSP:
- case ISCSI_OP_SCSI_TASK_MGT_RSP:
- case ISCSI_OP_TEXT_RSP:
- case ISCSI_OP_R2T:
- case ISCSI_OP_ASYNC_MSG:
- case ISCSI_OP_REJECT:
- case ISCSI_OP_SCSI_DATA_IN:
- case ISCSI_OP_LOGOUT_RSP:
- break;
- default:
- eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd));
- assert(0);
- break;
- }
-
- if (cmnd_close(cmnd))
- conn_close(conn);
-
- list_del_init(&cmnd->list);
- set_cork(cmnd->conn->sock, 0);
-}
-
-/**
- * Push the command for execution.
- * This functions reorders the commands.
- * Called from the read thread.
- *
- * iscsi_session_push_cmnd -
- * @cmnd: ptr to command
- */
-
-static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_session *session = cmnd->conn->session;
- struct list_head *entry;
- u32 cmd_sn;
-
- if (cmnd->r2t_length) {
- if (!cmnd->is_unsolicited_data)
- send_r2t(cmnd);
- return;
- }
-
- dprintk(D_GENERIC, "%p:%x %u,%u\n",
- cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn, session->exp_cmd_sn);
-
- if (cmnd_immediate(cmnd)) {
- iscsi_cmnd_exec(cmnd);
- return;
- }
-
- cmd_sn = cmnd->pdu.bhs.sn;
- if (cmd_sn == session->exp_cmd_sn) {
- while (1) {
- session->exp_cmd_sn = ++cmd_sn;
- iscsi_cmnd_exec(cmnd);
-
- if (list_empty(&session->pending_list))
- break;
-
- cmnd = list_entry(session->pending_list.next, struct iscsi_cmnd, list);
- if (cmnd->pdu.bhs.sn != cmd_sn)
- break;
-
- list_del_init(&cmnd->list);
- clear_cmnd_pending(cmnd);
- }
- } else {
- set_cmnd_pending(cmnd);
-
- list_for_each(entry, &session->pending_list) {
- struct iscsi_cmnd *tmp = list_entry(entry, struct iscsi_cmnd, list);
- if (before(cmd_sn, tmp->pdu.bhs.sn))
- break;
- }
-
- assert(list_empty(&cmnd->list));
-
- list_add_tail(&cmnd->list, entry);
- }
-}
-
-static int check_segment_length(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct iscsi_sess_param *param = &conn->session->param;
-
- if (cmnd->pdu.datasize > param->max_recv_data_length) {
- eprintk("data too long %x %u %u\n", cmnd_itt(cmnd),
- cmnd->pdu.datasize, param->max_recv_data_length);
-
- if (get_pgcnt(cmnd->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX) {
- conn_close(conn);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-void cmnd_rx_start(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- int err = 0;
-
- iscsi_dump_pdu(&cmnd->pdu);
-
- set_cmnd_rxstart(cmnd);
- if (check_segment_length(cmnd) < 0)
- return;
-
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_NOP_OUT:
- err = nop_out_start(conn, cmnd);
- break;
- case ISCSI_OP_SCSI_CMD:
- if (!(err = cmnd_insert_hash(cmnd)))
- scsi_cmnd_start(conn, cmnd);
- break;
- case ISCSI_OP_SCSI_TASK_MGT_MSG:
- err = cmnd_insert_hash(cmnd);
- break;
- case ISCSI_OP_SCSI_DATA_OUT:
- data_out_start(conn, cmnd);
- break;
- case ISCSI_OP_LOGOUT_CMD:
- err = cmnd_insert_hash(cmnd);
- break;
- case ISCSI_OP_TEXT_CMD:
- case ISCSI_OP_SNACK_CMD:
- err = -ISCSI_REASON_UNSUPPORTED_COMMAND;
- break;
- default:
- err = -ISCSI_REASON_UNSUPPORTED_COMMAND;
- break;
- }
-
- if (err < 0) {
- eprintk("%x %x %d\n", cmnd_opcode(cmnd), cmnd_itt(cmnd), err);
- iscsi_cmnd_reject(cmnd, -err);
- }
-}
-
-void cmnd_rx_end(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
-
- if (cmnd_tmfabort(cmnd)) {
- cmnd_release(cmnd, 1);
- return;
- }
-
- dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd));
- switch (cmnd_opcode(cmnd)) {
- case ISCSI_OP_SCSI_REJECT:
- case ISCSI_OP_NOP_OUT:
- case ISCSI_OP_SCSI_CMD:
- case ISCSI_OP_SCSI_TASK_MGT_MSG:
- case ISCSI_OP_TEXT_CMD:
- case ISCSI_OP_LOGOUT_CMD:
- iscsi_session_push_cmnd(cmnd);
- break;
- case ISCSI_OP_SCSI_DATA_OUT:
- data_out_end(conn, cmnd);
- break;
- case ISCSI_OP_SNACK_CMD:
- break;
- case ISCSI_OP_PDU_REJECT:
- iscsi_cmnd_init_write(get_rsp_cmnd(cmnd));
- break;
- case ISCSI_OP_DATA_REJECT:
- cmnd_release(cmnd, 0);
- break;
- default:
- eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd));
- BUG();
- break;
- }
-}
-
-static void iscsi_exit(void)
-{
- wthread_module_exit();
-
- unregister_chrdev(ctr_major, ctr_name);
-
- iet_procfs_exit();
-
- event_exit();
-
- tio_exit();
-
- iotype_exit();
-
- ua_exit();
-
- if (iscsi_cmnd_cache)
- kmem_cache_destroy(iscsi_cmnd_cache);
-}
-
-static int iscsi_init(void)
-{
- int err = -ENOMEM;
-
- printk("iSCSI Enterprise Target Software - version %s\n", IET_VERSION_STRING);
-
- if ((ctr_major = register_chrdev(0, ctr_name, &ctr_fops)) < 0) {
- eprintk("failed to register the control device %d\n", ctr_major);
- return ctr_major;
- }
-
- if ((err = iet_procfs_init()) < 0)
- goto err;
-
- if ((err = event_init()) < 0)
- goto err;
-
- iscsi_cmnd_cache = KMEM_CACHE(iscsi_cmnd, 0);
- if (!iscsi_cmnd_cache)
- goto err;
-
- err = ua_init();
- if (err < 0)
- goto err;
-
- if ((err = tio_init()) < 0)
- goto err;
-
- if ((err = iotype_init()) < 0)
- goto err;
-
- if ((err = wthread_module_init()) < 0)
- goto err;
-
- return 0;
-
-err:
- iscsi_exit();
- return err;
-}
-
-module_param(worker_thread_pool_size, ulong, S_IRUGO);
-MODULE_PARM_DESC(worker_thread_pool_size,
- "Size of the worker thread pool "
- "(0 = dedicated threads per target (default))");
-
-module_param(debug_enable_flags, ulong, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug_enable_flags,
- "debug bitmask, low bits (0 ... 8) used, see iscsi_dbg.h");
-
-module_init(iscsi_init);
-module_exit(iscsi_exit);
-
-MODULE_VERSION(IET_VERSION_STRING);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("iSCSI Enterprise Target");
-MODULE_AUTHOR("IET development team <iscsitarget-devel@lists.sourceforge.net>");
deleted file mode 100644
@@ -1,524 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- * Copyright (C) 2008 Arne Redlich <agr@powerkom-dd.de>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#ifndef __ISCSI_H__
-#define __ISCSI_H__
-
-#include <linux/blkdev.h>
-#include <linux/completion.h>
-#include <linux/pagemap.h>
-#include <linux/seq_file.h>
-#include <linux/mm.h>
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <net/sock.h>
-
-#include "iscsi_hdr.h"
-#include "iet_u.h"
-#include "compat.h"
-
-#define IET_SENSE_BUF_SIZE 18
-
-struct iscsi_sess_param {
- int initial_r2t;
- int immediate_data;
- int max_connections;
- int max_recv_data_length;
- int max_xmit_data_length;
- int max_burst_length;
- int first_burst_length;
- int default_wait_time;
- int default_retain_time;
- int max_outstanding_r2t;
- int data_pdu_inorder;
- int data_sequence_inorder;
- int error_recovery_level;
- int header_digest;
- int data_digest;
- int ofmarker;
- int ifmarker;
- int ofmarkint;
- int ifmarkint;
-};
-
-struct iscsi_trgt_param {
- int wthreads;
- int target_type;
- int queued_cmnds;
- int nop_interval;
- int nop_timeout;
-};
-
-struct tio {
- u32 pg_cnt;
-
- pgoff_t idx;
- u32 offset;
- u32 size;
-
- struct page **pvec;
-
- atomic_t count;
-};
-
-struct network_thread_info {
- struct task_struct *task;
- unsigned long flags;
- struct list_head active_conns;
-
- spinlock_t nthread_lock;
-
- void (*old_state_change)(struct sock *);
- void (*old_data_ready)(struct sock *, int);
- void (*old_write_space)(struct sock *);
-};
-
-struct worker_thread_info;
-
-struct worker_thread {
- struct task_struct *w_task;
- struct list_head w_list;
- struct worker_thread_info *w_info;
-};
-
-struct worker_thread_info {
- spinlock_t wthread_lock;
-
- u32 nr_running_wthreads;
-
- struct list_head wthread_list;
- struct list_head work_queue;
-
- wait_queue_head_t wthread_sleep;
-
- struct io_context *wthread_ioc;
-};
-
-struct iscsi_cmnd;
-
-struct target_type {
- int id;
- int (*execute_cmnd) (struct iscsi_cmnd *);
-};
-
-enum iscsi_device_state {
- IDEV_RUNNING,
- IDEV_DEL,
-};
-
-struct iscsi_target {
- struct list_head t_list;
- u32 tid;
-
- char name[ISCSI_NAME_LEN];
-
- struct iscsi_sess_param sess_param;
- struct iscsi_trgt_param trgt_param;
-
- atomic_t nr_volumes;
- struct list_head volumes;
- struct list_head session_list;
-
- /* Prevents races between add/del session and adding UAs */
- spinlock_t session_list_lock;
-
- struct network_thread_info nthread_info;
- /* Points either to own list or global pool */
- struct worker_thread_info * wthread_info;
-
- struct semaphore target_sem;
-};
-
-struct iscsi_queue {
- spinlock_t queue_lock;
- struct iscsi_cmnd *ordered_cmnd;
- struct list_head wait_list;
- int active_cnt;
-};
-
-struct iet_volume {
- u32 lun;
-
- enum iscsi_device_state l_state;
- atomic_t l_count;
-
- struct iscsi_target *target;
- struct list_head list;
-
- struct iscsi_queue queue;
-
- u8 scsi_id[SCSI_ID_LEN];
- u8 scsi_sn[SCSI_SN_LEN + 1];
-
- u32 blk_shift;
- u64 blk_cnt;
-
- u64 reserve_sid;
- spinlock_t reserve_lock;
-
- unsigned long flags;
-
- struct iotype *iotype;
- void *private;
-};
-
-enum lu_flags {
- LU_READONLY,
- LU_WCACHE,
- LU_RCACHE,
-};
-
-#define LUReadonly(lu) test_bit(LU_READONLY, &(lu)->flags)
-#define SetLUReadonly(lu) set_bit(LU_READONLY, &(lu)->flags)
-
-#define LUWCache(lu) test_bit(LU_WCACHE, &(lu)->flags)
-#define SetLUWCache(lu) set_bit(LU_WCACHE, &(lu)->flags)
-#define ClearLUWCache(lu) clear_bit(LU_WCACHE, &(lu)->flags)
-
-#define LURCache(lu) test_bit(LU_RCACHE, &(lu)->flags)
-#define SetLURCache(lu) set_bit(LU_RCACHE, &(lu)->flags)
-#define ClearLURCache(lu) clear_bit(LU_RCACHE, &(lu)->flags)
-
-#define IET_HASH_ORDER 8
-#define cmnd_hashfn(itt) hash_long((itt), IET_HASH_ORDER)
-
-#define UA_HASH_LEN 8
-
-struct iscsi_session {
- struct list_head list;
- struct iscsi_target *target;
- struct completion *done;
- char *initiator;
- u64 sid;
-
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
-
- struct iscsi_sess_param param;
- u32 max_queued_cmnds;
-
- struct list_head conn_list;
-
- struct list_head pending_list;
-
- spinlock_t cmnd_hash_lock;
- struct list_head cmnd_hash[1 << IET_HASH_ORDER];
-
- spinlock_t ua_hash_lock;
- struct list_head ua_hash[UA_HASH_LEN];
-
- u32 next_ttt;
-};
-
-enum connection_state_bit {
- CONN_ACTIVE,
- CONN_CLOSING,
- CONN_WSPACE_WAIT,
- CONN_NEED_NOP_IN,
-};
-
-#define ISCSI_CONN_IOV_MAX (((256 << 10) >> PAGE_SHIFT) + 1)
-
-struct iscsi_conn {
- struct list_head list; /* list entry in session list */
- struct iscsi_session *session; /* owning session */
-
- u16 cid;
- unsigned long state;
-
- u32 stat_sn;
- u32 exp_stat_sn;
-
- int hdigest_type;
- int ddigest_type;
-
- struct list_head poll_list;
-
- struct file *file;
- struct socket *sock;
- spinlock_t list_lock;
- atomic_t nr_cmnds;
- atomic_t nr_busy_cmnds;
- struct list_head pdu_list; /* in/outcoming pdus */
- struct list_head write_list; /* list of data pdus to be sent */
- struct timer_list nop_timer;
-
- struct iscsi_cmnd *read_cmnd;
- struct msghdr read_msg;
- struct iovec read_iov[ISCSI_CONN_IOV_MAX];
- u32 read_size;
- u32 read_overflow;
- int read_state;
-
- struct iscsi_cmnd *write_cmnd;
- struct iovec write_iov[ISCSI_CONN_IOV_MAX];
- struct iovec *write_iop;
- struct tio *write_tcmnd;
- u32 write_size;
- u32 write_offset;
- int write_state;
-
- struct hash_desc rx_hash;
- struct hash_desc tx_hash;
- struct scatterlist hash_sg[ISCSI_CONN_IOV_MAX];
-};
-
-struct iscsi_pdu {
- struct iscsi_hdr bhs;
- void *ahs;
- unsigned int ahssize;
- unsigned int datasize;
-};
-
-typedef void (iet_show_info_t)(struct seq_file *seq, struct iscsi_target *target);
-
-struct iscsi_cmnd {
- struct list_head list;
- struct list_head conn_list;
- unsigned long flags;
- struct iscsi_conn *conn;
- struct iet_volume *lun;
-
- struct iscsi_pdu pdu;
- struct list_head pdu_list;
-
- struct list_head hash_list;
-
- struct tio *tio;
-
- u8 status;
-
- struct timer_list timer;
-
- u32 r2t_sn;
- u32 r2t_length;
- u32 is_unsolicited_data;
- u32 target_task_tag;
- u32 outstanding_r2t;
-
- u32 hdigest;
- u32 ddigest;
-
- struct iscsi_cmnd *req;
-
- unsigned char sense_buf[IET_SENSE_BUF_SIZE];
-};
-
-struct ua_entry {
- struct list_head entry;
- struct iscsi_session *session; /* only used for debugging ATM */
- u32 lun;
- u8 asc;
- u8 ascq;
-};
-
-#define ISCSI_OP_SCSI_REJECT ISCSI_OP_VENDOR1_CMD
-#define ISCSI_OP_PDU_REJECT ISCSI_OP_VENDOR2_CMD
-#define ISCSI_OP_DATA_REJECT ISCSI_OP_VENDOR3_CMD
-#define ISCSI_OP_SCSI_ABORT ISCSI_OP_VENDOR4_CMD
-
-/* iscsi.c */
-extern unsigned long worker_thread_pool_size;
-extern struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *, int);
-extern void cmnd_rx_start(struct iscsi_cmnd *);
-extern void cmnd_rx_end(struct iscsi_cmnd *);
-extern void cmnd_tx_start(struct iscsi_cmnd *);
-extern void cmnd_tx_end(struct iscsi_cmnd *);
-extern void cmnd_release(struct iscsi_cmnd *, int);
-extern void send_data_rsp(struct iscsi_cmnd *, void (*)(struct iscsi_cmnd *));
-extern void send_scsi_rsp(struct iscsi_cmnd *, void (*)(struct iscsi_cmnd *));
-extern void iscsi_cmnd_set_sense(struct iscsi_cmnd *, u8 sense_key, u8 asc,
- u8 ascq);
-extern void send_nop_in(struct iscsi_conn *);
-
-/* conn.c */
-extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16);
-extern int conn_add(struct iscsi_session *, struct conn_info *);
-extern int conn_del(struct iscsi_session *, struct conn_info *);
-extern int conn_free(struct iscsi_conn *);
-extern void conn_close(struct iscsi_conn *);
-extern void conn_info_show(struct seq_file *, struct iscsi_session *);
-
-/* nthread.c */
-extern int nthread_init(struct iscsi_target *);
-extern int nthread_start(struct iscsi_target *);
-extern int nthread_stop(struct iscsi_target *);
-extern void __nthread_wakeup(struct network_thread_info *);
-extern void nthread_wakeup(struct iscsi_target *);
-
-/* wthread.c */
-extern int wthread_init(struct worker_thread_info *info);
-extern int wthread_start(struct worker_thread_info *info, int wthreads, u32 tid);
-extern int wthread_stop(struct worker_thread_info *info);
-extern void wthread_queue(struct iscsi_cmnd *);
-extern struct target_type *target_type_array[];
-extern int wthread_module_init(void);
-extern void wthread_module_exit(void);
-extern struct worker_thread_info *worker_thread_pool;
-
-/* target.c */
-extern int target_lock(struct iscsi_target *, int);
-extern void target_unlock(struct iscsi_target *);
-struct iscsi_target *target_lookup_by_id(u32);
-extern int target_add(struct target_info *);
-extern int target_del(u32 id);
-extern void target_del_all(void);
-extern struct seq_operations iet_seq_op;
-
-/* config.c */
-extern int iet_procfs_init(void);
-extern void iet_procfs_exit(void);
-extern int iet_info_show(struct seq_file *, iet_show_info_t *);
-
-/* session.c */
-extern struct file_operations session_seq_fops;
-extern struct iscsi_session *session_lookup(struct iscsi_target *, u64);
-extern int session_add(struct iscsi_target *, struct session_info *);
-extern int session_del(struct iscsi_target *, u64);
-
-/* volume.c */
-extern struct file_operations volume_seq_fops;
-extern int volume_add(struct iscsi_target *, struct volume_info *);
-extern int iscsi_volume_del(struct iscsi_target *, struct volume_info *);
-extern void iscsi_volume_destroy(struct iet_volume *);
-extern struct iet_volume *volume_lookup(struct iscsi_target *, u32);
-extern struct iet_volume *volume_get(struct iscsi_target *, u32);
-extern void volume_put(struct iet_volume *);
-extern int volume_reserve(struct iet_volume *volume, u64 sid);
-extern int volume_release(struct iet_volume *volume, u64 sid, int force);
-extern int is_volume_reserved(struct iet_volume *volume, u64 sid);
-
-/* tio.c */
-extern int tio_init(void);
-extern void tio_exit(void);
-extern struct tio *tio_alloc(int);
-extern void tio_get(struct tio *);
-extern void tio_put(struct tio *);
-extern void tio_set(struct tio *, u32, loff_t);
-extern int tio_read(struct iet_volume *, struct tio *);
-extern int tio_write(struct iet_volume *, struct tio *);
-extern int tio_sync(struct iet_volume *, struct tio *);
-
-/* iotype.c */
-extern struct iotype *get_iotype(const char *name);
-extern void put_iotype(struct iotype *iot);
-
-/* params.c */
-extern int iscsi_param_set(struct iscsi_target *, struct iscsi_param_info *, int);
-
-/* target_disk.c */
-extern struct target_type disk_ops;
-
-/* event.c */
-extern int event_send(u32, u64, u32, u32, int);
-extern int event_init(void);
-extern void event_exit(void);
-
-/* ua.c */
-int ua_init(void);
-void ua_exit(void);
-struct ua_entry * ua_get_first(struct iscsi_session *, u32 lun);
-struct ua_entry * ua_get_match(struct iscsi_session *, u32 lun, u8 asc,
- u8 ascq);
-void ua_free(struct ua_entry *);
-int ua_pending(struct iscsi_session *, u32 lun);
-void ua_establish_for_session(struct iscsi_session *, u32 lun, u8 asc,
- u8 ascq);
-void ua_establish_for_other_sessions(struct iscsi_session *, u32 lun, u8 asc,
- u8 ascq);
-void ua_establish_for_all_sessions(struct iscsi_target *, u32 lun, u8 asc,
- u8 ascq);
-
-#define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
-
-static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu)
-{
-#if defined(__BIG_ENDIAN)
- pdu->ahssize = pdu->bhs.length.ahslength * 4;
- pdu->datasize = pdu->bhs.length.datalength;
-#elif defined(__LITTLE_ENDIAN)
- pdu->ahssize = (pdu->bhs.length & 0xff) * 4;
- pdu->datasize = be32_to_cpu(pdu->bhs.length & ~0xff);
-#else
-#error
-#endif
-}
-
-static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu)
-{
-#if defined(__BIG_ENDIAN)
- pdu->bhs.length.ahslength = pdu->ahssize / 4;
- pdu->bhs.length.datalength = pdu->datasize;
-#elif defined(__LITTLE_ENDIAN)
- pdu->bhs.length = cpu_to_be32(pdu->datasize) | (pdu->ahssize / 4);
-#else
-#error
-#endif
-}
-
-#define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs)))
-#define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt)
-#define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt)
-#define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK)
-#define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0]
-#define cmnd_immediate(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)
-
-/* default and maximum scsi level block sizes */
-#define IET_DEF_BLOCK_SIZE 512
-#define IET_MAX_BLOCK_SIZE 4096
-
-enum cmnd_flags {
- CMND_hashed,
- CMND_queued,
- CMND_final,
- CMND_waitio,
- CMND_close,
- CMND_lunit,
- CMND_pending,
- CMND_tmfabort,
- CMND_rxstart,
- CMND_timer_active,
-};
-
-#define set_cmnd_hashed(cmnd) set_bit(CMND_hashed, &(cmnd)->flags)
-#define cmnd_hashed(cmnd) test_bit(CMND_hashed, &(cmnd)->flags)
-
-#define set_cmnd_queued(cmnd) set_bit(CMND_queued, &(cmnd)->flags)
-#define cmnd_queued(cmnd) test_bit(CMND_queued, &(cmnd)->flags)
-
-#define set_cmnd_final(cmnd) set_bit(CMND_final, &(cmnd)->flags)
-#define cmnd_final(cmnd) test_bit(CMND_final, &(cmnd)->flags)
-
-#define set_cmnd_waitio(cmnd) set_bit(CMND_waitio, &(cmnd)->flags)
-#define cmnd_waitio(cmnd) test_bit(CMND_waitio, &(cmnd)->flags)
-
-#define set_cmnd_close(cmnd) set_bit(CMND_close, &(cmnd)->flags)
-#define cmnd_close(cmnd) test_bit(CMND_close, &(cmnd)->flags)
-
-#define set_cmnd_lunit(cmnd) set_bit(CMND_lunit, &(cmnd)->flags)
-#define cmnd_lunit(cmnd) test_bit(CMND_lunit, &(cmnd)->flags)
-
-#define set_cmnd_pending(cmnd) set_bit(CMND_pending, &(cmnd)->flags)
-#define clear_cmnd_pending(cmnd) clear_bit(CMND_pending, &(cmnd)->flags)
-#define cmnd_pending(cmnd) test_bit(CMND_pending, &(cmnd)->flags)
-
-#define set_cmnd_tmfabort(cmnd) set_bit(CMND_tmfabort, &(cmnd)->flags)
-#define cmnd_tmfabort(cmnd) test_bit(CMND_tmfabort, &(cmnd)->flags)
-
-#define set_cmnd_rxstart(cmnd) set_bit(CMND_rxstart, &(cmnd)->flags)
-#define cmnd_rxstart(cmnd) test_bit(CMND_rxstart, &(cmnd)->flags)
-
-#define set_cmnd_timer_active(cmnd) set_bit(CMND_timer_active, &(cmnd)->flags)
-#define clear_cmnd_timer_active(cmnd) \
- clear_bit(CMND_timer_active, &(cmnd)->flags)
-#define cmnd_timer_active(cmnd) test_bit(CMND_timer_active, &(cmnd)->flags)
-
-#define VENDOR_ID "IET"
-#define PRODUCT_ID "VIRTUAL-DISK"
-#define PRODUCT_REV "0"
-
-#endif /* __ISCSI_H__ */
deleted file mode 100644
@@ -1,137 +0,0 @@
-#ifndef ISCSI_DBG_H
-#define ISCSI_DBG_H
-
-#define D_SETUP (1UL << 0)
-#define D_EXIT (1UL << 1)
-#define D_GENERIC (1UL << 2)
-#define D_READ (1UL << 3)
-#define D_WRITE (1UL << 4)
-#define D_IOD (1UL << 5)
-#define D_THREAD (1UL << 6)
-#define D_TASK_MGT (1UL << 7)
-#define D_IOMODE (1UL << 8)
-#define D_UAC (1UL << 9)
-
-#define D_DATA (D_READ | D_WRITE)
-
-extern unsigned long debug_enable_flags;
-
-#define PFX "iscsi_trgt: "
-
-#define dprintk(debug, fmt, args...) do { \
- if ((debug) & debug_enable_flags) { \
- printk(KERN_DEBUG PFX "%s(%d) " fmt, __FUNCTION__,\
- __LINE__, args);\
- } \
-} while (0)
-
-#define dprintk_ua(ua, sess, lun) \
- dprintk(D_UAC, "sess %llu, lun %u: %p %x %x\n", \
- (sess)->sid, lun, ua, \
- (ua) ? (ua)->asc : 0, \
- (ua) ? (ua)->ascq : 0)
-
-#define eprintk(fmt, args...) do { \
- printk(KERN_ERR PFX "%s(%d) " fmt, __FUNCTION__, \
- __LINE__, args);\
-} while (0)
-
-#define iprintk(X...) printk(KERN_INFO PFX X)
-
-#define assert(p) do { \
- if (!(p)) { \
- printk(KERN_CRIT PFX "BUG at %s:%d assert(%s)\n",\
- __FILE__, __LINE__, #p); \
- dump_stack(); \
- BUG(); \
- } \
-} while (0)
-
-#ifdef D_IOV
-static inline void iscsi_dump_iov(struct msghdr *msg)
-{
- int i;
- printk(PFX "%p, %d\n", msg->msg_iov, msg->msg_iovlen);
- for (i = 0; i < min_t(size_t, msg->msg_iovlen, ISCSI_CONN_IOV_MAX); i++)
- printk(PFX "%d: %p,%d\n", i, msg->msg_iov[i].iov_base,
- msg->msg_iov[i].iov_len);
-}
-#else
-#define iscsi_dump_iov(x) do {} while (0)
-#endif
-
-#ifdef D_DUMP_PDU
-static void iscsi_dump_char(int ch)
-{
- static unsigned char text[16];
- static int i = 0;
-
- if (ch < 0) {
- while ((i % 16) != 0) {
- printk(" ");
- text[i] = ' ';
- i++;
- if ((i % 16) == 0)
- printk(" | %.16s |\n", text);
- else if ((i % 4) == 0)
- printk(" |");
- }
- i = 0;
- return;
- }
-
- text[i] = (ch < 0x20 || (ch >= 0x80 && ch <= 0xa0)) ? ' ' : ch;
- printk(" %02x", ch);
- i++;
- if ((i % 16) == 0) {
- printk(" | %.16s |\n", text);
- i = 0;
- } else if ((i % 4) == 0)
- printk(" |");
-}
-
-static inline void iscsi_dump_pdu(struct iscsi_pdu *pdu)
-{
- unsigned char *buf;
- int i;
-
- buf = (void *)&pdu->bhs;
- printk(PFX "BHS: (%p,%d)\n", buf, sizeof(pdu->bhs));
- for (i = 0; i < sizeof(pdu->bhs); i++)
- iscsi_dump_char(*buf++);
- iscsi_dump_char(-1);
-
- buf = (void *)pdu->ahs;
- printk(PFX "AHS: (%p,%d)\n", buf, pdu->ahssize);
- for (i = 0; i < pdu->ahssize; i++)
- iscsi_dump_char(*buf++);
- iscsi_dump_char(-1);
-
- printk(PFX "Data: (%d)\n", pdu->datasize);
-}
-
-#else
-#define iscsi_dump_pdu(x) do {} while (0)
-#endif
-
-#define show_param(param)\
-{\
- dprintk(D_SETUP, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",\
- (param)->initial_r2t,\
- (param)->immediate_data,\
- (param)->max_connections,\
- (param)->max_recv_data_length,\
- (param)->max_xmit_data_length,\
- (param)->max_burst_length,\
- (param)->first_burst_length,\
- (param)->default_wait_time,\
- (param)->default_retain_time,\
- (param)->max_outstanding_r2t,\
- (param)->data_pdu_inorder,\
- (param)->data_sequence_inorder,\
- (param)->error_recovery_level,\
- (param)->header_digest,\
- (param)->data_digest);\
-}
-
-#endif
deleted file mode 100644
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#ifndef __ISCSI_HDR_H__
-#define __ISCSI_HDR_H__
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#define ISCSI_VERSION 0
-
-#ifndef __packed
-#define __packed __attribute__ ((packed))
-#endif
-
-struct iscsi_hdr {
- u8 opcode; /* 0 */
- u8 flags;
- u8 spec1[2];
-#if defined(__BIG_ENDIAN_BITFIELD)
- struct { /* 4 */
- unsigned ahslength : 8;
- unsigned datalength : 24;
- } length;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- u32 length; /* 4 */
-#endif
- u16 lun[4]; /* 8 */
- u32 itt; /* 16 */
- u32 ttt; /* 20 */
- u32 sn; /* 24 */
- u32 exp_sn; /* 28 */
- u32 max_sn; /* 32 */
- u32 spec3[3]; /* 36 */
-} __packed; /* 48 */
-
-/* Opcode encoding bits */
-#define ISCSI_OP_RETRY 0x80
-#define ISCSI_OP_IMMEDIATE 0x40
-#define ISCSI_OPCODE_MASK 0x3F
-
-/* Client to Server Message Opcode values */
-#define ISCSI_OP_NOP_OUT 0x00
-#define ISCSI_OP_SCSI_CMD 0x01
-#define ISCSI_OP_SCSI_TASK_MGT_MSG 0x02
-#define ISCSI_OP_LOGIN_CMD 0x03
-#define ISCSI_OP_TEXT_CMD 0x04
-#define ISCSI_OP_SCSI_DATA_OUT 0x05
-#define ISCSI_OP_LOGOUT_CMD 0x06
-#define ISCSI_OP_SNACK_CMD 0x10
-
-#define ISCSI_OP_VENDOR1_CMD 0x1c
-#define ISCSI_OP_VENDOR2_CMD 0x1d
-#define ISCSI_OP_VENDOR3_CMD 0x1e
-#define ISCSI_OP_VENDOR4_CMD 0x1f
-
-/* Server to Client Message Opcode values */
-#define ISCSI_OP_NOP_IN 0x20
-#define ISCSI_OP_SCSI_RSP 0x21
-#define ISCSI_OP_SCSI_TASK_MGT_RSP 0x22
-#define ISCSI_OP_LOGIN_RSP 0x23
-#define ISCSI_OP_TEXT_RSP 0x24
-#define ISCSI_OP_SCSI_DATA_IN 0x25
-#define ISCSI_OP_LOGOUT_RSP 0x26
-#define ISCSI_OP_R2T 0x31
-#define ISCSI_OP_ASYNC_MSG 0x32
-#define ISCSI_OP_REJECT 0x3f
-
-struct iscsi_ahs_hdr {
- u16 ahslength;
- u8 ahstype;
-} __packed;
-
-#define ISCSI_AHSTYPE_CDB 1
-#define ISCSI_AHSTYPE_RLENGTH 2
-
-union iscsi_sid {
- struct {
- u8 isid[6]; /* Initiator Session ID */
- u16 tsih; /* Target Session ID */
- } id;
- u64 id64;
-} __packed;
-
-struct iscsi_scsi_cmd_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 data_length;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u8 scb[16];
-} __packed;
-
-#define ISCSI_CMD_FINAL 0x80
-#define ISCSI_CMD_READ 0x40
-#define ISCSI_CMD_WRITE 0x20
-#define ISCSI_CMD_ATTR_MASK 0x07
-#define ISCSI_CMD_UNTAGGED 0x00
-#define ISCSI_CMD_SIMPLE 0x01
-#define ISCSI_CMD_ORDERED 0x02
-#define ISCSI_CMD_HEAD_OF_QUEUE 0x03
-#define ISCSI_CMD_ACA 0x04
-
-struct iscsi_cdb_ahdr {
- u16 ahslength;
- u8 ahstype;
- u8 reserved;
- u8 cdb[0];
-} __packed;
-
-struct iscsi_rlength_ahdr {
- u16 ahslength;
- u8 ahstype;
- u8 reserved;
- u32 read_length;
-} __packed;
-
-struct iscsi_scsi_rsp_hdr {
- u8 opcode;
- u8 flags;
- u8 response;
- u8 cmd_status;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd1[2];
- u32 itt;
- u32 snack;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 exp_data_sn;
- u32 bi_residual_count;
- u32 residual_count;
-} __packed;
-
-#define ISCSI_FLG_RESIDUAL_UNDERFLOW 0x02
-#define ISCSI_FLG_RESIDUAL_OVERFLOW 0x04
-#define ISCSI_FLG_BIRESIDUAL_UNDERFLOW 0x08
-#define ISCSI_FLG_BIRESIDUAL_OVERFLOW 0x10
-
-#define ISCSI_RESPONSE_COMMAND_COMPLETED 0x00
-#define ISCSI_RESPONSE_TARGET_FAILURE 0x01
-
-struct iscsi_sense_data {
- u16 length;
- u8 data[0];
-} __packed;
-
-struct iscsi_task_mgt_hdr {
- u8 opcode;
- u8 function;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 rtt;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u32 ref_cmd_sn;
- u32 exp_data_sn;
- u32 rsvd2[2];
-} __packed;
-
-#define ISCSI_FUNCTION_MASK 0x7f
-
-#define ISCSI_FUNCTION_ABORT_TASK 1
-#define ISCSI_FUNCTION_ABORT_TASK_SET 2
-#define ISCSI_FUNCTION_CLEAR_ACA 3
-#define ISCSI_FUNCTION_CLEAR_TASK_SET 4
-#define ISCSI_FUNCTION_LOGICAL_UNIT_RESET 5
-#define ISCSI_FUNCTION_TARGET_WARM_RESET 6
-#define ISCSI_FUNCTION_TARGET_COLD_RESET 7
-#define ISCSI_FUNCTION_TASK_REASSIGN 8
-
-struct iscsi_task_rsp_hdr {
- u8 opcode;
- u8 flags;
- u8 response;
- u8 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 rsvd3;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 rsvd4[3];
-} __packed;
-
-#define ISCSI_RESPONSE_FUNCTION_COMPLETE 0
-#define ISCSI_RESPONSE_UNKNOWN_TASK 1
-#define ISCSI_RESPONSE_UNKNOWN_LUN 2
-#define ISCSI_RESPONSE_TASK_ALLEGIANT 3
-#define ISCSI_RESPONSE_FAILOVER_UNSUPPORTED 4
-#define ISCSI_RESPONSE_FUNCTION_UNSUPPORTED 5
-#define ISCSI_RESPONSE_NO_AUTHORIZATION 6
-#define ISCSI_RESPONSE_FUNCTION_REJECTED 255
-
-struct iscsi_data_out_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 ttt;
- u32 rsvd2;
- u32 exp_stat_sn;
- u32 rsvd3;
- u32 data_sn;
- u32 buffer_offset;
- u32 rsvd4;
-} __packed;
-
-struct iscsi_data_in_hdr {
- u8 opcode;
- u8 flags;
- u8 rsvd1;
- u8 cmd_status;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 ttt;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 data_sn;
- u32 buffer_offset;
- u32 residual_count;
-} __packed;
-
-#define ISCSI_FLG_STATUS 0x01
-
-struct iscsi_r2t_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 ttt;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 r2t_sn;
- u32 buffer_offset;
- u32 data_length;
-} __packed;
-
-struct iscsi_async_msg_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 ffffffff;
- u32 rsvd2;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u8 async_event;
- u8 async_vcode;
- u16 param1;
- u16 param2;
- u16 param3;
- u32 rsvd3;
-} __packed;
-
-#define ISCSI_ASYNC_SCSI 0
-#define ISCSI_ASYNC_LOGOUT 1
-#define ISCSI_ASYNC_DROP_CONNECTION 2
-#define ISCSI_ASYNC_DROP_SESSION 3
-#define ISCSI_ASYNC_PARAM_REQUEST 4
-#define ISCSI_ASYNC_VENDOR 255
-
-struct iscsi_text_req_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 ttt;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u32 rsvd3[4];
-} __packed;
-
-struct iscsi_text_rsp_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 ttt;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 rsvd3[3];
-} __packed;
-
-struct iscsi_login_req_hdr {
- u8 opcode;
- u8 flags;
- u8 max_version; /* Max. version supported */
- u8 min_version; /* Min. version supported */
- u8 ahslength;
- u8 datalength[3];
- union iscsi_sid sid;
- u32 itt; /* Initiator Task Tag */
- u16 cid; /* Connection ID */
- u16 rsvd1;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u32 rsvd2[4];
-} __packed;
-
-struct iscsi_login_rsp_hdr {
- u8 opcode;
- u8 flags;
- u8 max_version; /* Max. version supported */
- u8 active_version; /* Active version */
- u8 ahslength;
- u8 datalength[3];
- union iscsi_sid sid;
- u32 itt; /* Initiator Task Tag */
- u32 rsvd1;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u8 status_class; /* see Login RSP ststus classes below */
- u8 status_detail; /* see Login RSP Status details below */
- u8 rsvd2[10];
-} __packed;
-
-#define ISCSI_FLG_FINAL 0x80
-#define ISCSI_FLG_TRANSIT 0x80
-#define ISCSI_FLG_CSG_SECURITY 0x00
-#define ISCSI_FLG_CSG_LOGIN 0x04
-#define ISCSI_FLG_CSG_FULL_FEATURE 0x0c
-#define ISCSI_FLG_CSG_MASK 0x0c
-#define ISCSI_FLG_NSG_SECURITY 0x00
-#define ISCSI_FLG_NSG_LOGIN 0x01
-#define ISCSI_FLG_NSG_FULL_FEATURE 0x03
-#define ISCSI_FLG_NSG_MASK 0x03
-
-/* Login Status response classes */
-#define ISCSI_STATUS_SUCCESS 0x00
-#define ISCSI_STATUS_REDIRECT 0x01
-#define ISCSI_STATUS_INITIATOR_ERR 0x02
-#define ISCSI_STATUS_TARGET_ERR 0x03
-
-/* Login Status response detail codes */
-/* Class-0 (Success) */
-#define ISCSI_STATUS_ACCEPT 0x00
-
-/* Class-1 (Redirection) */
-#define ISCSI_STATUS_TGT_MOVED_TEMP 0x01
-#define ISCSI_STATUS_TGT_MOVED_PERM 0x02
-
-/* Class-2 (Initiator Error) */
-#define ISCSI_STATUS_INIT_ERR 0x00
-#define ISCSI_STATUS_AUTH_FAILED 0x01
-#define ISCSI_STATUS_TGT_FORBIDDEN 0x02
-#define ISCSI_STATUS_TGT_NOT_FOUND 0x03
-#define ISCSI_STATUS_TGT_REMOVED 0x04
-#define ISCSI_STATUS_NO_VERSION 0x05
-#define ISCSI_STATUS_TOO_MANY_CONN 0x06
-#define ISCSI_STATUS_MISSING_FIELDS 0x07
-#define ISCSI_STATUS_CONN_ADD_FAILED 0x08
-#define ISCSI_STATUS_INV_SESSION_TYPE 0x09
-#define ISCSI_STATUS_SESSION_NOT_FOUND 0x0a
-#define ISCSI_STATUS_INV_REQ_TYPE 0x0b
-
-/* Class-3 (Target Error) */
-#define ISCSI_STATUS_TARGET_ERROR 0x00
-#define ISCSI_STATUS_SVC_UNAVAILABLE 0x01
-#define ISCSI_STATUS_NO_RESOURCES 0x02
-
-struct iscsi_logout_req_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u16 cid;
- u16 rsvd3;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u32 rsvd4[4];
-} __packed;
-
-struct iscsi_logout_rsp_hdr {
- u8 opcode;
- u8 flags;
- u8 response;
- u8 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 rsvd3;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 rsvd4;
- u16 time2wait;
- u16 time2retain;
- u32 rsvd5;
-} __packed;
-
-struct iscsi_snack_req_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 itt;
- u32 ttt;
- u32 rsvd3;
- u32 exp_stat_sn;
- u32 rsvd4[2];
- u32 beg_run;
- u32 run_length;
-} __packed;
-
-struct iscsi_reject_hdr {
- u8 opcode;
- u8 flags;
- u8 reason;
- u8 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u32 rsvd2[2];
- u32 ffffffff;
- u32 rsvd3;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 data_sn;
- u32 rsvd4[2];
-} __packed;
-
-#define ISCSI_REASON_NO_FULL_FEATURE_PHASE 0x01
-#define ISCSI_REASON_DATA_DIGEST_ERROR 0x02
-#define ISCSI_REASON_DATA_SNACK_REJECT 0x03
-#define ISCSI_REASON_PROTOCOL_ERROR 0x04
-#define ISCSI_REASON_UNSUPPORTED_COMMAND 0x05
-#define ISCSI_REASON_IMMEDIATE_COMMAND_REJECT 0x06
-#define ISCSI_REASON_TASK_IN_PROGRESS 0x07
-#define ISCSI_REASON_INVALID_SNACK 0x08
-#define ISCSI_REASON_NO_BOOKMARK 0x09
-#define ISCSI_REASON_BOOKMARK_REJECT 0x0a
-#define ISCSI_REASON_NEGOTIATION_RESET 0x0b
-#define ISCSI_REASON_WAITING_LOGOUT 0x0c
-
-
-struct iscsi_nop_out_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 ttt;
- u32 cmd_sn;
- u32 exp_stat_sn;
- u32 rsvd2[4];
-} __packed;
-
-struct iscsi_nop_in_hdr {
- u8 opcode;
- u8 flags;
- u16 rsvd1;
- u8 ahslength;
- u8 datalength[3];
- u16 lun[4];
- u32 itt;
- u32 ttt;
- u32 stat_sn;
- u32 exp_cmd_sn;
- u32 max_cmd_sn;
- u32 rsvd2[3];
-} __packed;
-
-#define ISCSI_RESERVED_TAG (0xffffffffU)
-
-#endif /* __ISCSI_HDR_H__ */
deleted file mode 100644
@@ -1,790 +0,0 @@
-/*
- * Network thread.
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * (C) 2008 Arne Redlich <agr@powerkom-dd.de>
- *
- * This code is licenced under the GPL.
- */
-
-#include <linux/sched.h>
-#include <linux/file.h>
-#include <linux/kthread.h>
-#include <asm/ioctls.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "digest.h"
-
-enum daemon_state_bit {
- D_ACTIVE,
- D_DATA_READY,
-};
-
-void __nthread_wakeup(struct network_thread_info *info)
-{
- set_bit(D_DATA_READY, &info->flags);
- wake_up_process(info->task);
-}
-
-void nthread_wakeup(struct iscsi_target *target)
-{
- struct network_thread_info *info = &target->nthread_info;
-
- spin_lock_bh(&info->nthread_lock);
- __nthread_wakeup(info);
- spin_unlock_bh(&info->nthread_lock);
-}
-
-static inline void iscsi_conn_init_read(struct iscsi_conn *conn, void *data, size_t len)
-{
- len = (len + 3) & -4; // XXX ???
- conn->read_iov[0].iov_base = data;
- conn->read_iov[0].iov_len = len;
- conn->read_msg.msg_iov = conn->read_iov;
- conn->read_msg.msg_iovlen = 1;
- conn->read_size = (len + 3) & -4;
-}
-
-static void iscsi_conn_read_ahs(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd)
-{
- cmnd->pdu.ahs = kmalloc(cmnd->pdu.ahssize, __GFP_NOFAIL|GFP_KERNEL);
- assert(cmnd->pdu.ahs);
- iscsi_conn_init_read(conn, cmnd->pdu.ahs, cmnd->pdu.ahssize);
-}
-
-static struct iscsi_cmnd * iscsi_get_send_cmnd(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *cmnd = NULL;
-
- spin_lock(&conn->list_lock);
- if (!list_empty(&conn->write_list)) {
- cmnd = list_entry(conn->write_list.next, struct iscsi_cmnd, list);
- list_del_init(&cmnd->list);
- }
- spin_unlock(&conn->list_lock);
-
- return cmnd;
-}
-
-static int is_data_available(struct iscsi_conn *conn)
-{
- int avail, res;
- mm_segment_t oldfs;
- struct socket *sock = conn->sock;
-
- oldfs = get_fs();
- set_fs(get_ds());
- res = sock->ops->ioctl(sock, SIOCINQ, (unsigned long) &avail);
- set_fs(oldfs);
- return (res >= 0) ? avail : res;
-}
-
-static void forward_iov(struct msghdr *msg, int len)
-{
- while (msg->msg_iov->iov_len <= len) {
- len -= msg->msg_iov->iov_len;
- msg->msg_iov++;
- msg->msg_iovlen--;
- }
-
- msg->msg_iov->iov_base = (char *) msg->msg_iov->iov_base + len;
- msg->msg_iov->iov_len -= len;
-}
-
-static int do_recv(struct iscsi_conn *conn, int state)
-{
- mm_segment_t oldfs;
- struct msghdr msg;
- struct iovec iov[ISCSI_CONN_IOV_MAX];
- int i, len, res;
-
- if (!test_bit(CONN_ACTIVE, &conn->state)) {
- res = -EIO;
- goto out;
- }
-
- if (is_data_available(conn) <= 0) {
- res = -EAGAIN;
- goto out;
- }
-
- msg.msg_iov = iov;
- msg.msg_iovlen = min_t(size_t, conn->read_msg.msg_iovlen, ISCSI_CONN_IOV_MAX);
- for (i = 0, len = 0; i < msg.msg_iovlen; i++) {
- iov[i] = conn->read_msg.msg_iov[i];
- len += iov[i].iov_len;
- }
-
- oldfs = get_fs();
- set_fs(get_ds());
- res = sock_recvmsg(conn->sock, &msg, len, MSG_DONTWAIT | MSG_NOSIGNAL);
- set_fs(oldfs);
-
- if (res <= 0) {
- switch (res) {
- case -EAGAIN:
- case -ERESTARTSYS:
- break;
- default:
- eprintk("%d\n", res);
- conn_close(conn);
- break;
- }
- } else {
- conn->read_size -= res;
- if (conn->read_size)
- forward_iov(&conn->read_msg, res);
- else
- conn->read_state = state;
- }
-
-out:
- dprintk(D_IOD, "%d\n", res);
-
- return res;
-}
-
-enum rx_state {
- RX_INIT_BHS, /* Must be zero. */
- RX_BHS,
-
- RX_INIT_AHS,
- RX_AHS,
-
- RX_INIT_HDIGEST,
- RX_HDIGEST,
- RX_CHECK_HDIGEST,
-
- RX_INIT_DATA,
- RX_DATA,
-
- RX_INIT_DDIGEST,
- RX_DDIGEST,
- RX_CHECK_DDIGEST,
-
- RX_END,
-};
-
-static void rx_ddigest(struct iscsi_conn *conn, int state)
-{
- struct iscsi_cmnd *cmnd = conn->read_cmnd;
- int res = digest_rx_data(cmnd);
-
- if (!res)
- conn->read_state = state;
- else
- conn_close(conn);
-}
-
-static void rx_hdigest(struct iscsi_conn *conn, int state)
-{
- struct iscsi_cmnd *cmnd = conn->read_cmnd;
- int res = digest_rx_header(cmnd);
-
- if (!res)
- conn->read_state = state;
- else
- conn_close(conn);
-}
-
-static struct iscsi_cmnd *create_cmnd(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *cmnd;
-
- cmnd = cmnd_alloc(conn, 1);
- iscsi_conn_init_read(cmnd->conn, &cmnd->pdu.bhs, sizeof(cmnd->pdu.bhs));
- conn->read_state = RX_BHS;
-
- return cmnd;
-}
-
-static int recv(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *cmnd = conn->read_cmnd;
- int hdigest, ddigest, res = 1;
-
- if (!test_bit(CONN_ACTIVE, &conn->state))
- return -EIO;
-
- hdigest = conn->hdigest_type & DIGEST_NONE ? 0 : 1;
- ddigest = conn->ddigest_type & DIGEST_NONE ? 0 : 1;
-
-next_state:
- switch (conn->read_state) {
- case RX_INIT_BHS:
- assert(!cmnd);
- cmnd = conn->read_cmnd = create_cmnd(conn);
- case RX_BHS:
- res = do_recv(conn, RX_INIT_AHS);
- if (res <= 0 || conn->read_state != RX_INIT_AHS)
- break;
- case RX_INIT_AHS:
- iscsi_cmnd_get_length(&cmnd->pdu);
- if (cmnd->pdu.ahssize) {
- iscsi_conn_read_ahs(conn, cmnd);
- conn->read_state = RX_AHS;
- } else
- conn->read_state = hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA;
-
- if (conn->read_state != RX_AHS)
- break;
- case RX_AHS:
- res = do_recv(conn, hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA);
- if (res <= 0 || conn->read_state != RX_INIT_HDIGEST)
- break;
- case RX_INIT_HDIGEST:
- iscsi_conn_init_read(conn, &cmnd->hdigest, sizeof(u32));
- conn->read_state = RX_HDIGEST;
- case RX_HDIGEST:
- res = do_recv(conn, RX_CHECK_HDIGEST);
- if (res <= 0 || conn->read_state != RX_CHECK_HDIGEST)
- break;
- case RX_CHECK_HDIGEST:
- rx_hdigest(conn, RX_INIT_DATA);
- if (conn->read_state != RX_INIT_DATA)
- break;
- case RX_INIT_DATA:
- cmnd_rx_start(cmnd);
- conn->read_state = cmnd->pdu.datasize ? RX_DATA : RX_END;
- if (conn->read_state != RX_DATA)
- break;
- case RX_DATA:
- res = do_recv(conn, ddigest ? RX_INIT_DDIGEST : RX_END);
- if (res <= 0 || conn->read_state != RX_INIT_DDIGEST)
- break;
- case RX_INIT_DDIGEST:
- iscsi_conn_init_read(conn, &cmnd->ddigest, sizeof(u32));
- conn->read_state = RX_DDIGEST;
- case RX_DDIGEST:
- res = do_recv(conn, RX_CHECK_DDIGEST);
- if (res <= 0 || conn->read_state != RX_CHECK_DDIGEST)
- break;
- case RX_CHECK_DDIGEST:
- rx_ddigest(conn, RX_END);
- break;
- default:
- eprintk("%d %d %x\n", res, conn->read_state, cmnd_opcode(cmnd));
- assert(0);
- }
-
- if (res <= 0)
- return res;
-
- if (conn->read_state != RX_END)
- goto next_state;
-
- if (conn->read_size) {
- eprintk("%d %x %d\n", res, cmnd_opcode(cmnd), conn->read_size);
- assert(0);
- }
-
- cmnd_rx_end(cmnd);
- if (conn->read_size) {
- eprintk("%x %d\n", cmnd_opcode(cmnd), conn->read_size);
- conn->read_state = RX_DATA;
- return 1;
- }
-
- conn->read_cmnd = NULL;
- conn->read_state = RX_INIT_BHS;
-
- return 0;
-}
-
-/*
- * @locking: grabs the target's nthread_lock to protect it from races with
- * iet_write_space()
- */
-static void set_conn_wspace_wait(struct iscsi_conn *conn)
-{
- struct network_thread_info *info = &conn->session->target->nthread_info;
- struct sock *sk = conn->sock->sk;
-
- spin_lock_bh(&info->nthread_lock);
-
- if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk))
- set_bit(CONN_WSPACE_WAIT, &conn->state);
-
- spin_unlock_bh(&info->nthread_lock);
-}
-
-/* This is taken from the Ardis code. */
-static int write_data(struct iscsi_conn *conn)
-{
- mm_segment_t oldfs;
- struct file *file;
- struct socket *sock;
- ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
- struct tio *tio;
- struct iovec *iop;
- int saved_size, size, sendsize;
- int offset, idx;
- int flags, res;
-
- file = conn->file;
- saved_size = size = conn->write_size;
- iop = conn->write_iop;
-
- if (iop) while (1) {
- loff_t off = 0;
- unsigned long count;
- struct iovec *vec;
- int rest;
-
- vec = iop;
- for (count = 0; vec->iov_len; count++, vec++)
- ;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
- res = vfs_writev(file, (struct iovec __user *) iop, count, &off);
- set_fs(oldfs);
- dprintk(D_DATA, "%#Lx:%u: %d(%ld)\n",
- (unsigned long long) conn->session->sid, conn->cid,
- res, (long) iop->iov_len);
- if (unlikely(res <= 0)) {
- if (res == -EAGAIN || res == -EINTR) {
- conn->write_iop = iop;
- goto out_iov;
- }
- goto err;
- }
-
- rest = res;
- size -= res;
- while (iop->iov_len <= rest && rest) {
- rest -= iop->iov_len;
- iop++;
- }
- iop->iov_base += rest;
- iop->iov_len -= rest;
-
- if (!iop->iov_len) {
- conn->write_iop = NULL;
- if (size)
- break;
- goto out_iov;
- }
- }
-
- if (!(tio = conn->write_tcmnd)) {
- eprintk("%s\n", "warning data missing!");
- return 0;
- }
- offset = conn->write_offset;
- idx = offset >> PAGE_CACHE_SHIFT;
- offset &= ~PAGE_CACHE_MASK;
-
- sock = conn->sock;
- sendpage = sock->ops->sendpage ? : sock_no_sendpage;
- flags = MSG_DONTWAIT;
-
- while (1) {
- sendsize = PAGE_CACHE_SIZE - offset;
- if (size <= sendsize) {
- res = sendpage(sock, tio->pvec[idx], offset, size, flags);
- dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n",
- sock->ops->sendpage ? "sendpage" : "writepage",
- (unsigned long long ) conn->session->sid, conn->cid,
- res, tio->pvec[idx]->index, offset, size);
- if (unlikely(res <= 0)) {
- if (res == -EAGAIN || res == -EINTR) {
- goto out;
- }
- goto err;
- }
- if (res == size) {
- conn->write_tcmnd = NULL;
- conn->write_size = 0;
- return saved_size;
- }
- offset += res;
- size -= res;
- continue;
- }
-
- res = sendpage(sock, tio->pvec[idx], offset,sendsize, flags | MSG_MORE);
- dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n",
- sock->ops->sendpage ? "sendpage" : "writepage",
- (unsigned long long ) conn->session->sid, conn->cid,
- res, tio->pvec[idx]->index, offset, sendsize);
- if (unlikely(res <= 0)) {
- if (res == -EAGAIN || res == -EINTR) {
- goto out;
- }
- goto err;
- }
- if (res == sendsize) {
- idx++;
- offset = 0;
- } else
- offset += res;
- size -= res;
- }
- out:
- conn->write_offset = (idx << PAGE_CACHE_SHIFT) + offset;
- out_iov:
- conn->write_size = size;
- if (res == -EAGAIN) {
- set_conn_wspace_wait(conn);
- if (saved_size == size)
- return res;
- }
-
- return saved_size - size;
-
- err:
- eprintk("error %d at %#Lx:%u\n", res,
- (unsigned long long) conn->session->sid, conn->cid);
- return res;
-}
-
-static void exit_tx(struct iscsi_conn *conn, int res)
-{
- if (res > 0)
- return;
-
- switch (res) {
- case -EAGAIN:
- case -ERESTARTSYS:
- break;
- default:
- eprintk("%d %d %d\n", conn->write_size, conn->write_state, res);
- conn_close(conn);
- break;
- }
-}
-
-static int tx_ddigest(struct iscsi_cmnd *cmnd, int state)
-{
- int res, rest = cmnd->conn->write_size;
- struct msghdr msg = {.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT};
- struct kvec iov;
-
- iov.iov_base = (char *) (&cmnd->ddigest) + (sizeof(u32) - rest);
- iov.iov_len = rest;
-
- res = kernel_sendmsg(cmnd->conn->sock, &msg, &iov, 1, rest);
-
- if (res > 0) {
- cmnd->conn->write_size -= res;
- if (!cmnd->conn->write_size)
- cmnd->conn->write_state = state;
- } else
- exit_tx(cmnd->conn, res);
-
- return res;
-}
-
-static void init_tx_hdigest(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_conn *conn = cmnd->conn;
- struct iovec *iop;
-
- if (conn->hdigest_type & DIGEST_NONE)
- return;
-
- digest_tx_header(cmnd);
-
- for (iop = conn->write_iop; iop->iov_len; iop++)
- ;
- iop->iov_base = &(cmnd->hdigest);
- iop->iov_len = sizeof(u32);
- conn->write_size += sizeof(u32);
- iop++;
- iop->iov_len = 0;
-
- return;
-}
-
-enum tx_state {
- TX_INIT, /* Must be zero. */
- TX_BHS_DATA,
- TX_INIT_DDIGEST,
- TX_DDIGEST,
- TX_END,
-};
-
-static int do_send(struct iscsi_conn *conn, int state)
-{
- int res;
-
- res = write_data(conn);
-
- if (res > 0) {
- if (!conn->write_size)
- conn->write_state = state;
- } else
- exit_tx(conn, res);
-
- return res;
-}
-
-static int send(struct iscsi_conn *conn)
-{
- struct iscsi_cmnd *cmnd = conn->write_cmnd;
- int ddigest, res = 0;
-
- ddigest = conn->ddigest_type != DIGEST_NONE ? 1 : 0;
-
-next_state:
- switch (conn->write_state) {
- case TX_INIT:
- assert(!cmnd);
- cmnd = conn->write_cmnd = iscsi_get_send_cmnd(conn);
- if (!cmnd)
- return 0;
- cmnd_tx_start(cmnd);
- init_tx_hdigest(cmnd);
- conn->write_state = TX_BHS_DATA;
- case TX_BHS_DATA:
- res = do_send(conn, ddigest && cmnd->pdu.datasize ? TX_INIT_DDIGEST : TX_END);
- if (res <= 0 || conn->write_state != TX_INIT_DDIGEST)
- break;
- case TX_INIT_DDIGEST:
- digest_tx_data(cmnd);
- assert(!cmnd->conn->write_size);
- cmnd->conn->write_size += sizeof(u32);
- conn->write_state = TX_DDIGEST;
- case TX_DDIGEST:
- res = tx_ddigest(cmnd, TX_END);
- break;
- default:
- eprintk("%d %d %x\n", res, conn->write_state, cmnd_opcode(cmnd));
- assert(0);
- }
-
- if (res <= 0)
- return res;
-
- if (conn->write_state != TX_END)
- goto next_state;
-
- if (conn->write_size) {
- eprintk("%d %x %u\n", res, cmnd_opcode(cmnd), conn->write_size);
- assert(!conn->write_size);
- }
- cmnd_tx_end(cmnd);
- cmnd_release(cmnd, 0);
- conn->write_cmnd = NULL;
- conn->write_state = TX_INIT;
-
- return 0;
-}
-
-static void conn_nop_timeout(unsigned long data)
-{
- struct iscsi_conn *conn = (struct iscsi_conn *)data;
-
- if (test_bit(CONN_ACTIVE, &conn->state))
- set_bit(CONN_NEED_NOP_IN, &conn->state);
-
- dprintk(D_THREAD, "conn %llu:%hu, NOP timer %p\n", conn->session->sid,
- conn->cid, &conn->nop_timer);
-
- nthread_wakeup(conn->session->target);
-}
-
-static void conn_reset_nop_timer(struct iscsi_conn *conn)
-{
- struct iscsi_target *target = conn->session->target;
-
- if (target->trgt_param.nop_interval)
- mod_timer(&conn->nop_timer,
- jiffies + HZ * target->trgt_param.nop_interval);
-}
-
-static void conn_start_nop_timer(struct iscsi_conn *conn)
-{
- struct iscsi_target *target = conn->session->target;
-
- if (!target->trgt_param.nop_interval || timer_pending(&conn->nop_timer))
- return;
-
- conn->nop_timer.data = (unsigned long)conn;
- conn->nop_timer.function = conn_nop_timeout;
-
- dprintk(D_THREAD, "conn %llu:%hu, NOP timer %p\n", conn->session->sid,
- conn->cid, &conn->nop_timer);
-
- mod_timer(&conn->nop_timer,
- jiffies + HZ * target->trgt_param.nop_interval);
-}
-
-static void process_io(struct iscsi_conn *conn)
-{
- struct iscsi_target *target = conn->session->target;
- int res, wakeup = 0;
-
- res = recv(conn);
-
- if (is_data_available(conn) > 0 || res > 0) {
- conn_reset_nop_timer(conn);
- wakeup = 1;
- }
-
- if (!test_bit(CONN_ACTIVE, &conn->state)) {
- wakeup = 1;
- goto out;
- }
-
- if (test_bit(CONN_WSPACE_WAIT, &conn->state))
- goto out;
-
- res = send(conn);
-
- if (!list_empty(&conn->write_list) || conn->write_cmnd) {
- conn_reset_nop_timer(conn);
- wakeup = 1;
- }
-
-out:
- if (wakeup)
- nthread_wakeup(target);
- else if (test_and_clear_bit(CONN_NEED_NOP_IN, &conn->state)) {
- send_nop_in(conn);
- nthread_wakeup(target);
- } else
- conn_start_nop_timer(conn);
-
- return;
-}
-
-static void close_conn(struct iscsi_conn *conn)
-{
- struct iscsi_session *session = conn->session;
- struct iscsi_target *target = conn->session->target;
- struct iscsi_cmnd *cmnd;
-
- if (target->trgt_param.nop_interval)
- del_timer_sync(&conn->nop_timer);
-
- conn->sock->ops->shutdown(conn->sock, 2);
-
- write_lock_bh(&conn->sock->sk->sk_callback_lock);
- conn->sock->sk->sk_state_change = target->nthread_info.old_state_change;
- conn->sock->sk->sk_data_ready = target->nthread_info.old_data_ready;
- conn->sock->sk->sk_write_space = target->nthread_info.old_write_space;
- write_unlock_bh(&conn->sock->sk->sk_callback_lock);
-
- fput(conn->file);
- conn->file = NULL;
- conn->sock = NULL;
-
- while (atomic_read(&conn->nr_busy_cmnds))
- yield();
-
- while (!list_empty(&conn->pdu_list)) {
- cmnd = list_entry(conn->pdu_list.next, struct iscsi_cmnd, conn_list);
-
- list_del_init(&cmnd->list);
- cmnd_release(cmnd, 1);
- }
-
- if (atomic_read(&conn->nr_cmnds)) {
- eprintk("%u\n", atomic_read(&conn->nr_cmnds));
- list_for_each_entry(cmnd, &conn->pdu_list, conn_list)
- eprintk("%x %x\n", cmnd_opcode(cmnd), cmnd_itt(cmnd));
- assert(0);
- }
-
- event_send(target->tid, session->sid, conn->cid, E_CONN_CLOSE, 0);
- conn_free(conn);
-
- if (list_empty(&session->conn_list)) {
- if (session->done)
- complete(session->done);
- else
- session_del(target, session->sid);
- }
-}
-
-static int istd(void *arg)
-{
- struct iscsi_target *target = arg;
- struct network_thread_info *info = &target->nthread_info;
- struct iscsi_conn *conn, *tmp;
-
- __set_current_state(TASK_RUNNING);
- do {
- spin_lock_bh(&info->nthread_lock);
- __set_current_state(TASK_INTERRUPTIBLE);
-
- if (!test_bit(D_DATA_READY, &info->flags)) {
- spin_unlock_bh(&info->nthread_lock);
- schedule();
- spin_lock_bh(&info->nthread_lock);
- }
- __set_current_state(TASK_RUNNING);
- clear_bit(D_DATA_READY, &info->flags);
- spin_unlock_bh(&info->nthread_lock);
-
- target_lock(target, 0);
- list_for_each_entry_safe(conn, tmp, &info->active_conns, poll_list) {
- if (test_bit(CONN_ACTIVE, &conn->state))
- process_io(conn);
- else
- close_conn(conn);
- }
- target_unlock(target);
-
- } while (!kthread_should_stop());
-
- return 0;
-}
-
-int nthread_init(struct iscsi_target *target)
-{
- struct network_thread_info *info = &target->nthread_info;
-
- info->flags = 0;
- info->task = NULL;
-
- info->old_state_change = NULL;
- info->old_data_ready = NULL;
- info->old_write_space = NULL;
-
- INIT_LIST_HEAD(&info->active_conns);
-
- spin_lock_init(&info->nthread_lock);
-
- return 0;
-}
-
-int nthread_start(struct iscsi_target *target)
-{
- int err = 0;
- struct network_thread_info *info = &target->nthread_info;
- struct task_struct *task;
-
- if (info->task) {
- eprintk("Target (%u) already runs\n", target->tid);
- return -EALREADY;
- }
-
- task = kthread_run(istd, target, "istd%d", target->tid);
-
- if (IS_ERR(task))
- err = PTR_ERR(task);
- else
- info->task = task;
-
- return err;
-}
-
-int nthread_stop(struct iscsi_target *target)
-{
- int err;
- struct network_thread_info *info = &target->nthread_info;
-
- if (!info->task)
- return -ESRCH;
-
- err = kthread_stop(info->task);
-
- if (err < 0 && err != -EINTR)
- return err;
-
- info->task = NULL;
-
- return 0;
-}
deleted file mode 100644
@@ -1,98 +0,0 @@
-/*
- * Target device null I/O.
- * (C) 2005 MING Zhang <mingz@ele.uri.edu>
- * This code is licenced under the GPL.
- *
- * The nullio mode will not return any meaningful or previous written
- * data. It is only for performance measurement purpose.
- */
-
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/parser.h>
-#include <linux/writeback.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-enum {
- opt_blk_cnt, opt_ignore, opt_err,
-};
-
-static match_table_t tokens = {
- /* alias for compatibility with existing setups and documentation */
- {opt_blk_cnt, "sectors=%u"},
- /* but actually it is the scsi block count, now that we can
- * specify the block size. */
- {opt_blk_cnt, "blocks=%u"},
- {opt_ignore, "scsiid=%s"},
- {opt_ignore, "scsisn=%s"},
- {opt_ignore, "blocksize=%s"},
- {opt_ignore, "type=%s"},
- {opt_err, NULL},
-};
-
-static int parse_nullio_params(struct iet_volume *volume, char *params)
-{
- int err = 0;
- char *p, *q;
-
- while ((p = strsep(¶ms, ",")) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- int token;
- if (!*p)
- continue;
- iet_strtolower(p);
- token = match_token(p, tokens, args);
- switch (token) {
- case opt_blk_cnt:
- q = match_strdup(&args[0]);
- if (!q)
- return -ENOMEM;
- volume->blk_cnt = simple_strtoull(q, NULL, 10);
- kfree(q);
- break;
- case opt_ignore:
- break;
- default:
- eprintk("Unknown %s\n", p);
- return -EINVAL;
- break;
- }
- }
- return err;
-}
-
-static void nullio_detach(struct iet_volume *lu)
-{
-}
-
-static int nullio_attach(struct iet_volume *lu, char *args)
-{
- int err = 0;
-
- if ((err = parse_nullio_params(lu, args)) < 0) {
- eprintk("%d\n", err);
- goto out;
- }
-
- if (!lu->blk_shift)
- lu->blk_shift = blksize_bits(IET_DEF_BLOCK_SIZE);
-
- /* defaults to 64 GiB */
- if (!lu->blk_cnt)
- lu->blk_cnt = 1 << (36 - lu->blk_shift);
-
-out:
- if (err < 0)
- nullio_detach(lu);
- return err;
-}
-
-struct iotype nullio =
-{
- .name = "nullio",
- .attach = nullio_attach,
- .detach = nullio_detach,
-};
deleted file mode 100644
@@ -1,205 +0,0 @@
-/*
- * (C) 2005 FUJITA Tomonori <tomof@acm.org>
- *
- * This code is licenced under the GPL.
- */
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "digest.h"
-
-struct target_type *target_type_array[] = {
- &disk_ops,
-};
-
-#define CHECK_PARAM(info, iparam, word, min, max) \
-do { \
- if (!info->partial || (info->partial & 1 << key_##word)) \
- if (iparam[key_##word] < min || \
- iparam[key_##word] > max) { \
- eprintk("%s: %u is out of range (%u %u)\n", \
- #word, iparam[key_##word], min, max); \
- iparam[key_##word] = min; \
- } \
-} while (0)
-
-#define SET_PARAM(param, info, iparam, word) \
-({ \
- int changed = 0; \
- if (!info->partial || (info->partial & 1 << key_##word)) { \
- if (param->word != iparam[key_##word]) \
- changed = 1; \
- param->word = iparam[key_##word]; \
- } \
- changed; \
-})
-
-#define GET_PARAM(param, info, iparam, word) \
-do { \
- iparam[key_##word] = param->word; \
-} while (0)
-
-static void sess_param_check(struct iscsi_param_info *info)
-{
- u32 *iparam = info->session_param;
-
- CHECK_PARAM(info, iparam, max_connections, 1, 65535);
- CHECK_PARAM(info, iparam, max_recv_data_length, 512,
- (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE));
- CHECK_PARAM(info, iparam, max_xmit_data_length, 512,
- (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE));
- CHECK_PARAM(info, iparam, error_recovery_level, 0, 0);
- CHECK_PARAM(info, iparam, data_pdu_inorder, 1, 1);
- CHECK_PARAM(info, iparam, data_sequence_inorder, 1, 1);
-
- digest_alg_available(&iparam[key_header_digest]);
- digest_alg_available(&iparam[key_data_digest]);
-
- CHECK_PARAM(info, iparam, ofmarker, 0, 0);
- CHECK_PARAM(info, iparam, ifmarker, 0, 0);
-}
-
-static void sess_param_set(struct iscsi_sess_param *param, struct iscsi_param_info *info)
-{
- u32 *iparam = info->session_param;
-
- SET_PARAM(param, info, iparam, initial_r2t);
- SET_PARAM(param, info, iparam, immediate_data);
- SET_PARAM(param, info, iparam, max_connections);
- SET_PARAM(param, info, iparam, max_recv_data_length);
- SET_PARAM(param, info, iparam, max_xmit_data_length);
- SET_PARAM(param, info, iparam, max_burst_length);
- SET_PARAM(param, info, iparam, first_burst_length);
- SET_PARAM(param, info, iparam, default_wait_time);
- SET_PARAM(param, info, iparam, default_retain_time);
- SET_PARAM(param, info, iparam, max_outstanding_r2t);
- SET_PARAM(param, info, iparam, data_pdu_inorder);
- SET_PARAM(param, info, iparam, data_sequence_inorder);
- SET_PARAM(param, info, iparam, error_recovery_level);
- SET_PARAM(param, info, iparam, header_digest);
- SET_PARAM(param, info, iparam, data_digest);
- SET_PARAM(param, info, iparam, ofmarker);
- SET_PARAM(param, info, iparam, ifmarker);
- SET_PARAM(param, info, iparam, ofmarkint);
- SET_PARAM(param, info, iparam, ifmarkint);
-}
-
-static void sess_param_get(struct iscsi_sess_param *param, struct iscsi_param_info *info)
-{
- u32 *iparam = info->session_param;
-
- GET_PARAM(param, info, iparam, initial_r2t);
- GET_PARAM(param, info, iparam, immediate_data);
- GET_PARAM(param, info, iparam, max_connections);
- GET_PARAM(param, info, iparam, max_recv_data_length);
- GET_PARAM(param, info, iparam, max_xmit_data_length);
- GET_PARAM(param, info, iparam, max_burst_length);
- GET_PARAM(param, info, iparam, first_burst_length);
- GET_PARAM(param, info, iparam, default_wait_time);
- GET_PARAM(param, info, iparam, default_retain_time);
- GET_PARAM(param, info, iparam, max_outstanding_r2t);
- GET_PARAM(param, info, iparam, data_pdu_inorder);
- GET_PARAM(param, info, iparam, data_sequence_inorder);
- GET_PARAM(param, info, iparam, error_recovery_level);
- GET_PARAM(param, info, iparam, header_digest);
- GET_PARAM(param, info, iparam, data_digest);
- GET_PARAM(param, info, iparam, ofmarker);
- GET_PARAM(param, info, iparam, ifmarker);
- GET_PARAM(param, info, iparam, ofmarkint);
- GET_PARAM(param, info, iparam, ifmarkint);
-}
-
-static void trgt_param_check(struct iscsi_param_info *info)
-{
- u32 *iparam = info->target_param;
-
- CHECK_PARAM(info, iparam, wthreads, MIN_NR_WTHREADS, MAX_NR_WTHREADS);
- CHECK_PARAM(info, iparam, target_type, 0,
- (unsigned int) ARRAY_SIZE(target_type_array) - 1);
- CHECK_PARAM(info, iparam, queued_cmnds, MIN_NR_QUEUED_CMNDS,
- MAX_NR_QUEUED_CMNDS);
- CHECK_PARAM(info, iparam, nop_interval, MIN_NOP_INTERVAL,
- MAX_NOP_INTERVAL);
- CHECK_PARAM(info, iparam, nop_timeout, MIN_NOP_TIMEOUT,
- MAX_NOP_TIMEOUT);
-}
-
-static void trgt_param_set(struct iscsi_target *target, struct iscsi_param_info *info)
-{
- struct iscsi_trgt_param *param = &target->trgt_param;
- u32 *iparam = info->target_param;
-
- if (!worker_thread_pool &&
- SET_PARAM(param, info, iparam, wthreads))
- wthread_start(target->wthread_info,
- target->trgt_param.wthreads, target->tid);
- SET_PARAM(param, info, iparam, target_type);
- SET_PARAM(param, info, iparam, queued_cmnds);
- SET_PARAM(param, info, iparam, nop_interval);
- SET_PARAM(param, info, iparam, nop_timeout);
-}
-
-static void trgt_param_get(struct iscsi_trgt_param *param, struct iscsi_param_info *info)
-{
- u32 *iparam = info->target_param;
-
- GET_PARAM(param, info, iparam, wthreads);
- GET_PARAM(param, info, iparam, target_type);
- GET_PARAM(param, info, iparam, queued_cmnds);
- GET_PARAM(param, info, iparam, nop_interval);
- GET_PARAM(param, info, iparam, nop_timeout);
-}
-
-static int trgt_param(struct iscsi_target *target, struct iscsi_param_info *info, int set)
-{
-
- if (set) {
- trgt_param_check(info);
- trgt_param_set(target, info);
- } else
- trgt_param_get(&target->trgt_param, info);
-
- return 0;
-}
-
-static int sess_param(struct iscsi_target *target, struct iscsi_param_info *info, int set)
-{
- struct iscsi_session *session = NULL;
- struct iscsi_sess_param *param;
- int err = -ENOENT;
-
- if (set)
- sess_param_check(info);
-
- if (info->sid) {
- if (!(session = session_lookup(target, info->sid)))
- goto out;
- param = &session->param;
- } else {
- param = &target->sess_param;
- }
-
- if (set) {
- sess_param_set(param, info);
- show_param(param);
- } else
- sess_param_get(param, info);
-
- err = 0;
-out:
- return err;
-}
-
-int iscsi_param_set(struct iscsi_target *target, struct iscsi_param_info *info, int set)
-{
- int err;
-
- if (info->param_type == key_session)
- err = sess_param(target, info, set);
- else if (info->param_type == key_target)
- err = trgt_param(target, info, set);
- else
- err = -EINVAL;
-
- return err;
-}
deleted file mode 100644
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-
-struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid)
-{
- struct iscsi_session *session;
-
- list_for_each_entry(session, &target->session_list, list) {
- if (session->sid == sid)
- return session;
- }
- return NULL;
-}
-
-static struct iscsi_session *
-iet_session_alloc(struct iscsi_target *target, struct session_info *info)
-{
- int i;
- struct iscsi_session *session;
- struct iet_volume *vol;
-
- dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid,
- (unsigned long long) info->sid);
-
- session = kzalloc(sizeof(*session), GFP_KERNEL);
- if (!session)
- return NULL;
-
- session->target = target;
- session->sid = info->sid;
- memcpy(&session->param, &target->sess_param, sizeof(session->param));
- session->max_queued_cmnds = target->trgt_param.queued_cmnds;
-
- session->exp_cmd_sn = info->exp_cmd_sn;
- session->max_cmd_sn = info->max_cmd_sn;
-
- session->initiator = kstrdup(info->initiator_name, GFP_KERNEL);
- if (!session->initiator) {
- kfree(session);
- return NULL;
- }
-
- INIT_LIST_HEAD(&session->conn_list);
- INIT_LIST_HEAD(&session->pending_list);
-
- spin_lock_init(&session->cmnd_hash_lock);
- for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++)
- INIT_LIST_HEAD(&session->cmnd_hash[i]);
-
- spin_lock_init(&session->ua_hash_lock);
- for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++)
- INIT_LIST_HEAD(&session->ua_hash[i]);
-
- list_for_each_entry(vol, &target->volumes, list)
- /* power-on, reset, or bus device reset occurred */
- ua_establish_for_session(session, vol->lun, 0x29, 0x0);
-
- session->next_ttt = 1;
-
- spin_lock(&target->session_list_lock);
- list_add(&session->list, &target->session_list);
- spin_unlock(&target->session_list_lock);
-
- return session;
-}
-
-static int session_free(struct iscsi_session *session)
-{
- int i;
- struct ua_entry *ua, *tmp;
- struct list_head *l;
- struct iscsi_target *target = session->target;
-
- dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid);
-
- spin_lock(&target->session_list_lock);
-
- assert(list_empty(&session->conn_list));
-
- for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) {
- if (!list_empty(&session->cmnd_hash[i]))
- BUG();
- }
-
- for (i = 0; i < ARRAY_SIZE(session->ua_hash); i++) {
- l = &session->ua_hash[i];
- list_for_each_entry_safe(ua, tmp, l, entry) {
- list_del_init(&ua->entry);
- ua_free(ua);
- }
- }
-
- list_del(&session->list);
-
- kfree(session->initiator);
- kfree(session);
-
- spin_unlock(&target->session_list_lock);
-
- return 0;
-}
-
-int session_add(struct iscsi_target *target, struct session_info *info)
-{
- struct iscsi_session *session;
-
- session = session_lookup(target, info->sid);
- if (session)
- return -EEXIST;
-
- session = iet_session_alloc(target, info);
- if (!session)
- return -ENOMEM;
-
- return 0;
-}
-
-int session_del(struct iscsi_target *target, u64 sid)
-{
- struct iscsi_session *session;
- struct iet_volume *volume;
-
- session = session_lookup(target, sid);
- if (!session)
- return -ENOENT;
-
- if (!list_empty(&session->conn_list)) {
- DECLARE_COMPLETION_ONSTACK(done);
- struct iscsi_conn *conn;
-
- session->done = &done;
- list_for_each_entry(conn, &session->conn_list, list)
- conn_close(conn);
-
- target_unlock(target);
- wait_for_completion(&done);
- target_lock(target, 0);
- }
-
- list_for_each_entry(volume, &target->volumes, list){
- volume_release(volume, sid, 0);
- }
-
- return session_free(session);
-}
-
-static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target)
-{
- struct iscsi_session *session;
-
- list_for_each_entry(session, &target->session_list, list) {
- seq_printf(seq, "\tsid:%llu initiator:%s\n",
- (unsigned long long) session->sid, session->initiator);
- conn_info_show(seq, session);
- }
-}
-
-static int iet_session_seq_open(struct inode *inode, struct file *file)
-{
- int res;
- res = seq_open(file, &iet_seq_op);
- if (!res)
- ((struct seq_file *)file->private_data)->private =
- iet_session_info_show;
- return res;
-}
-
-struct file_operations session_seq_fops = {
- .owner = THIS_MODULE,
- .open = iet_session_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
deleted file mode 100644
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include "iscsi.h"
-#include "digest.h"
-#include "iscsi_dbg.h"
-
-#define MAX_NR_TARGETS (1UL << 30)
-
-static LIST_HEAD(target_list);
-static DEFINE_SEMAPHORE(target_list_sem);
-static u32 next_target_id;
-static u32 nr_targets;
-
-static struct iscsi_sess_param default_session_param = {
- .initial_r2t = 1,
- .immediate_data = 1,
- .max_connections = 1,
- .max_recv_data_length = 8192,
- .max_xmit_data_length = 8192,
- .max_burst_length = 262144,
- .first_burst_length = 65536,
- .default_wait_time = 2,
- .default_retain_time = 20,
- .max_outstanding_r2t = 1,
- .data_pdu_inorder = 1,
- .data_sequence_inorder = 1,
- .error_recovery_level = 0,
- .header_digest = DIGEST_NONE,
- .data_digest = DIGEST_NONE,
- .ofmarker = 0,
- .ifmarker = 0,
- .ofmarkint = 2048,
- .ifmarkint = 2048,
-};
-
-static struct iscsi_trgt_param default_target_param = {
- .wthreads = DEFAULT_NR_WTHREADS,
- .target_type = 0,
- .queued_cmnds = DEFAULT_NR_QUEUED_CMNDS,
-};
-
-inline int target_lock(struct iscsi_target *target, int interruptible)
-{
- int err = 0;
-
- if (interruptible)
- err = down_interruptible(&target->target_sem);
- else
- down(&target->target_sem);
-
- return err;
-}
-
-inline void target_unlock(struct iscsi_target *target)
-{
- up(&target->target_sem);
-}
-
-static struct iscsi_target *__target_lookup_by_id(u32 id)
-{
- struct iscsi_target *target;
-
- list_for_each_entry(target, &target_list, t_list) {
- if (target->tid == id)
- return target;
- }
- return NULL;
-}
-
-static struct iscsi_target *__target_lookup_by_name(char *name)
-{
- struct iscsi_target *target;
-
- list_for_each_entry(target, &target_list, t_list) {
- if (!strcmp(target->name, name))
- return target;
- }
- return NULL;
-}
-
-struct iscsi_target *target_lookup_by_id(u32 id)
-{
- struct iscsi_target *target;
-
- down(&target_list_sem);
- target = __target_lookup_by_id(id);
- up(&target_list_sem);
-
- return target;
-}
-
-static int target_thread_start(struct iscsi_target *target)
-{
- int err;
-
- if ((err = nthread_start(target)) < 0)
- return err;
-
- if (!worker_thread_pool) {
- err = wthread_start(target->wthread_info,
- target->trgt_param.wthreads, target->tid);
- if (err)
- nthread_stop(target);
- }
-
- return err;
-}
-
-static void target_thread_stop(struct iscsi_target *target)
-{
- if (!worker_thread_pool)
- wthread_stop(target->wthread_info);
-
- nthread_stop(target);
-}
-
-static int iscsi_target_create(struct target_info *info, u32 tid)
-{
- int err = -EINVAL, len;
- char *name = info->name;
- struct iscsi_target *target;
-
- dprintk(D_SETUP, "%u %s\n", tid, name);
-
- if (!(len = strlen(name))) {
- eprintk("The length of the target name is zero %u\n", tid);
- return err;
- }
-
- if (!try_module_get(THIS_MODULE)) {
- eprintk("Fail to get module %u\n", tid);
- return err;
- }
-
- target = kzalloc(sizeof(*target), GFP_KERNEL);
- if (!target) {
- err = -ENOMEM;
- goto out;
- }
-
- if (!worker_thread_pool) {
- target->wthread_info = kmalloc(sizeof(struct worker_thread_info), GFP_KERNEL);
- if (!target->wthread_info) {
- err = -ENOMEM;
- goto out;
- }
- }
-
- target->tid = info->tid = tid;
-
- memcpy(&target->sess_param, &default_session_param, sizeof(default_session_param));
- memcpy(&target->trgt_param, &default_target_param, sizeof(default_target_param));
-
- strncpy(target->name, name, sizeof(target->name) - 1);
-
- sema_init(&target->target_sem, 1);
- spin_lock_init(&target->session_list_lock);
-
- INIT_LIST_HEAD(&target->session_list);
- INIT_LIST_HEAD(&target->volumes);
-
- atomic_set(&target->nr_volumes, 0);
-
- nthread_init(target);
-
- if (!worker_thread_pool)
- wthread_init(target->wthread_info);
- else
- target->wthread_info = worker_thread_pool;
-
-
- if ((err = target_thread_start(target)) < 0) {
- target_thread_stop(target);
- goto out;
- }
-
- list_add(&target->t_list, &target_list);
-
- return 0;
-out:
- if (!worker_thread_pool)
- kfree(target->wthread_info);
- kfree(target);
- module_put(THIS_MODULE);
-
- return err;
-}
-
-int target_add(struct target_info *info)
-{
- u32 tid = info->tid;
- int err;
-
- err = down_interruptible(&target_list_sem);
- if (err < 0)
- return err;
-
- if (nr_targets > MAX_NR_TARGETS) {
- err = -EBUSY;
- goto out;
- }
-
- if (__target_lookup_by_name(info->name) ||
- (tid && __target_lookup_by_id(tid))) {
- err = -EEXIST;
- goto out;
- }
-
- if (!tid) {
- do {
- if (!++next_target_id)
- ++next_target_id;
- } while (__target_lookup_by_id(next_target_id));
-
- tid = next_target_id;
- }
-
- err = iscsi_target_create(info, tid);
- if (!err)
- nr_targets++;
-out:
- up(&target_list_sem);
-
- return err;
-}
-
-static void target_destroy(struct iscsi_target *target)
-{
- dprintk(D_SETUP, "%u\n", target->tid);
-
- target_thread_stop(target);
-
- while (!list_empty(&target->volumes)) {
- struct iet_volume *volume;
- volume = list_entry(target->volumes.next, struct iet_volume, list);
- volume->l_state = IDEV_DEL;
- iscsi_volume_destroy(volume);
- }
-
- if (!worker_thread_pool)
- kfree(target->wthread_info);
- kfree(target);
-
- module_put(THIS_MODULE);
-}
-
-/* @locking: target_list_sem must be locked */
-static int __target_del(struct iscsi_target *target)
-{
- int err;
-
- target_lock(target, 0);
-
- if (!list_empty(&target->session_list)) {
- struct iscsi_session *session;
-
- do {
- session = list_entry(target->session_list.next,
- struct iscsi_session, list);
- err = session_del(target, session->sid);
- if (err < 0) {
- target_unlock(target);
- return err;
- }
- } while (!list_empty(&target->session_list));
- }
-
- list_del(&target->t_list);
- nr_targets--;
-
- target_unlock(target);
- target_destroy(target);
-
- return 0;
-}
-
-int target_del(u32 id)
-{
- struct iscsi_target *target;
- int err;
-
- err = down_interruptible(&target_list_sem);
- if (err < 0)
- return err;
-
- target = __target_lookup_by_id(id);
- if (!target) {
- err = -ENOENT;
- goto out;
- }
-
- err = __target_del(target);
-out:
- up(&target_list_sem);
-
- return err;
-}
-
-void target_del_all(void)
-{
- struct iscsi_target *target, *tmp;
- int err;
-
- down(&target_list_sem);
-
- if (!list_empty(&target_list))
- iprintk("Removing all connections, sessions and targets\n");
-
- list_for_each_entry_safe(target, tmp, &target_list, t_list) {
- u32 tid = target->tid;
- err =__target_del(target);
- if (err)
- eprintk("Error deleteing target %u: %d\n", tid, err);
- }
-
- next_target_id = 0;
-
- up(&target_list_sem);
-}
-
-static void *iet_seq_start(struct seq_file *m, loff_t *pos)
-{
- int err;
-
- /* are you sure this is to be interruptible? */
- err = down_interruptible(&target_list_sem);
- if (err < 0)
- return ERR_PTR(err);
-
- return seq_list_start(&target_list, *pos);
-}
-
-static void *iet_seq_next(struct seq_file *m, void *v, loff_t *pos)
-{
- return seq_list_next(v, &target_list, pos);
-}
-
-static void iet_seq_stop(struct seq_file *m, void *v)
-{
- up(&target_list_sem);
-}
-
-static int iet_seq_show(struct seq_file *m, void *p)
-{
- iet_show_info_t *func = (iet_show_info_t *)m->private;
- struct iscsi_target *target =
- list_entry(p, struct iscsi_target, t_list);
- int err;
-
- /* relly, interruptible? I'd think target_lock(target, 0)
- * would be more appropriate. --lge */
- err = target_lock(target, 1);
- if (err < 0)
- return err;
-
- seq_printf(m, "tid:%u name:%s\n", target->tid, target->name);
-
- func(m, target);
-
- target_unlock(target);
-
- return 0;
-}
-
-struct seq_operations iet_seq_op = {
- .start = iet_seq_start,
- .next = iet_seq_next,
- .stop = iet_seq_stop,
- .show = iet_seq_show,
-};
deleted file mode 100644
@@ -1,589 +0,0 @@
-/*
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- *
- * heavily based on code from kernel/iscsi.c:
- * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>,
- * licensed under the terms of the GNU GPL v2.0,
- */
-
-#include <linux/ctype.h>
-#include <scsi/scsi.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-
-static int insert_disconnect_pg(u8 *ptr)
-{
- unsigned char disconnect_pg[] = {0x02, 0x0e, 0x80, 0x80, 0x00, 0x0a, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-
- memcpy(ptr, disconnect_pg, sizeof(disconnect_pg));
- return sizeof(disconnect_pg);
-}
-
-static int insert_caching_pg(u8 *ptr, int wcache, int rcache)
-{
- unsigned char caching_pg[] = {0x08, 0x12, 0x10, 0x00, 0xff, 0xff, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00};
-
- memcpy(ptr, caching_pg, sizeof(caching_pg));
- if (wcache)
- ptr[2] |= 0x04; /* set WCE bit if we're caching writes */
- if (!rcache)
- ptr[2] |= 0x01; /* Read Cache Disable */
-
- return sizeof(caching_pg);
-}
-
-static int insert_ctrl_m_pg(u8 *ptr)
-{
- unsigned char ctrl_m_pg[] = {0x0a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x02, 0x4b};
-
- memcpy(ptr, ctrl_m_pg, sizeof(ctrl_m_pg));
- return sizeof(ctrl_m_pg);
-}
-
-static int insert_iec_m_pg(u8 *ptr)
-{
- unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00};
-
- memcpy(ptr, iec_m_pg, sizeof(iec_m_pg));
- return sizeof(iec_m_pg);
-}
-
-static int insert_format_m_pg(u8 *ptr, u32 sector_size)
-{
- unsigned char format_m_pg[] = {0x03, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00};
-
- memcpy(ptr, format_m_pg, sizeof(format_m_pg));
- ptr[12] = (sector_size >> 8) & 0xff;
- ptr[13] = sector_size & 0xff;
- return sizeof(format_m_pg);
-}
-
-static int insert_geo_m_pg(u8 *ptr, u64 sec)
-{
- unsigned char geo_m_pg[] = {0x04, 0x16, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00};
- u32 ncyl;
- u32 n;
-
- /* assume 0xff heads, 15krpm. */
- memcpy(ptr, geo_m_pg, sizeof(geo_m_pg));
- ncyl = sec >> 14; /* 256 * 64 */
- memcpy(&n, ptr+1, sizeof(u32));
- n = n | cpu_to_be32(ncyl);
- memcpy(ptr+1, &n, sizeof(u32));
- return sizeof(geo_m_pg);
-}
-
-static void build_mode_sense_response(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- struct tio *tio = cmnd->tio;
- u8 *data, *scb = req->scb;
- int len = 4, err = 0;
- u8 pcode;
-
- /* changeable parameter mode pages are unsupported */
- if ((scb[2] & 0xc0) >> 6 == 0x1)
- goto set_sense;
-
- pcode = req->scb[2] & 0x3f;
-
- assert(!tio);
- tio = cmnd->tio = tio_alloc(1);
- data = page_address(tio->pvec[0]);
- assert(data);
- clear_page(data);
-
- if (LUReadonly(cmnd->lun))
- data[2] = 0x80;
-
- if ((scb[1] & 0x8))
- data[3] = 0;
- else {
- data[3] = 8;
- len += 8;
- *(u32 *)(data + 4) = (cmnd->lun->blk_cnt >> 32) ?
- cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt);
- *(u32 *)(data + 8) = cpu_to_be32(1 << cmnd->lun->blk_shift);
- }
-
- switch (pcode) {
- case 0x0:
- break;
- case 0x2:
- len += insert_disconnect_pg(data + len);
- break;
- case 0x3:
- len += insert_format_m_pg(data + len, 1 << cmnd->lun->blk_shift);
- break;
- case 0x4:
- len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt);
- break;
- case 0x8:
- len += insert_caching_pg(data + len, LUWCache(cmnd->lun),
- LURCache(cmnd->lun));
- break;
- case 0xa:
- len += insert_ctrl_m_pg(data + len);
- break;
- case 0x1c:
- len += insert_iec_m_pg(data + len);
- break;
- case 0x3f:
- len += insert_disconnect_pg(data + len);
- len += insert_format_m_pg(data + len, 1 << cmnd->lun->blk_shift);
- len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt);
- len += insert_caching_pg(data + len, LUWCache(cmnd->lun),
- LURCache(cmnd->lun));
- len += insert_ctrl_m_pg(data + len);
- len += insert_iec_m_pg(data + len);
- break;
- default:
- err = -1;
- }
-
- if (!err) {
- data[0] = len - 1;
- tio_set(tio, len, 0);
- return;
- }
-
- tio_put(tio);
- cmnd->tio = NULL;
- set_sense:
- /* Invalid Field In CDB */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
-}
-
-static void build_inquiry_response(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- struct tio *tio = cmnd->tio;
- u8 *data;
- u8 *scb = req->scb;
- int err = -1;
-
- /*
- * - CmdDt and EVPD both set or EVPD and Page Code set: illegal
- * - CmdDt set: not supported
- */
- if ((scb[1] & 0x3) > 0x1 || (!(scb[1] & 0x3) && scb[2]))
- goto set_sense;
-
- assert(!tio);
- tio = cmnd->tio = tio_alloc(1);
- data = page_address(tio->pvec[0]);
- assert(data);
- clear_page(data);
-
- if (!(scb[1] & 0x3)) {
- data[2] = 4;
- data[3] = 0x52;
- data[4] = 59;
- data[7] = 0x02;
- memset(data + 8, 0x20, 28);
- memcpy(data + 8,
- VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
- memcpy(data + 16,
- PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
- memcpy(data + 32,
- PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
- data[58] = 0x03;
- data[59] = 0x20;
- data[60] = 0x09;
- data[61] = 0x60;
- data[62] = 0x03;
- data[63] = 0x00;
- tio_set(tio, 64, 0);
- err = 0;
- } else if (scb[1] & 0x1) {
- /* EVPD bit set */
- if (scb[2] == 0x0) {
- data[1] = 0x0;
- data[3] = 3;
- data[4] = 0x0;
- data[5] = 0x80;
- data[6] = 0x83;
- tio_set(tio, 7, 0);
- err = 0;
- } else if (scb[2] == 0x80) {
- u32 len = 4;
-
- if (cmnd->lun) {
- if (strlen(cmnd->lun->scsi_sn) <= 16)
- len = 16;
- else
- len = SCSI_SN_LEN;
- }
-
- data[1] = 0x80;
- data[3] = len;
- memset(data + 4, 0x20, len);
- if (cmnd->lun) {
- size_t offset = len -
- strlen(cmnd->lun->scsi_sn);
- memcpy(data + 4 + offset, cmnd->lun->scsi_sn,
- strlen(cmnd->lun->scsi_sn));
- }
- tio_set(tio, len + 4, 0);
- err = 0;
- } else if (scb[2] == 0x83) {
- u32 len = SCSI_ID_LEN + 8;
-
- data[1] = 0x83;
- data[3] = len + 4;
- data[4] = 0x1;
- data[5] = 0x1;
- data[7] = len;
- if (cmnd->lun) { /* We need this ? */
- memset(data + 8, 0x00, 8);
- memcpy(data + 8, VENDOR_ID,
- min_t(size_t, strlen(VENDOR_ID), 8));
- memcpy(data + 16, cmnd->lun->scsi_id,
- SCSI_ID_LEN);
- }
- tio_set(tio, len + 8, 0);
- err = 0;
- }
- }
-
- if (!err) {
- tio_set(tio, min_t(u8, tio->size, scb[4]), 0);
- if (!cmnd->lun)
- data[0] = TYPE_NO_LUN;
- return;
- }
-
- tio_put(tio);
- cmnd->tio = NULL;
- set_sense:
- /* Invalid Field In CDB */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
-}
-
-static void build_report_luns_response(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- struct tio *tio = cmnd->tio;
- u32 *data, size, len;
- struct iet_volume *lun;
- int rest, idx = 0;
-
- size = (u32)req->scb[6] << 24 | (u32)req->scb[7] << 16 |
- (u32)req->scb[8] << 8 | (u32)req->scb[9];
- if (size < 16) {
- /* Invalid Field In CDB */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
- return;
- }
-
- len = atomic_read(&cmnd->conn->session->target->nr_volumes) * 8;
- size = min(size & ~(8 - 1), len + 8);
-
- assert(!tio);
- tio = cmnd->tio = tio_alloc(get_pgcnt(size, 0));
- tio_set(tio, size, 0);
-
- data = page_address(tio->pvec[idx]);
- assert(data);
- *data++ = cpu_to_be32(len);
- *data++ = 0;
- size -= 8;
- rest = PAGE_CACHE_SIZE - 8;
- list_for_each_entry(lun, &cmnd->conn->session->target->volumes, list) {
- if (lun->l_state != IDEV_RUNNING)
- continue;
-
- *data++ = cpu_to_be32((0x3ff & lun->lun) << 16 |
- ((lun->lun > 0xff) ? (0x1 << 30) : 0));
- *data++ = 0;
- if ((size -= 8) == 0)
- break;
- if ((rest -= 8) == 0) {
- idx++;
- data = page_address(tio->pvec[idx]);
- rest = PAGE_CACHE_SIZE;
- }
- }
-}
-
-static void build_read_capacity_response(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio = cmnd->tio;
- u32 *data;
-
- assert(!tio);
- tio = cmnd->tio = tio_alloc(1);
- data = page_address(tio->pvec[0]);
- assert(data);
- clear_page(data);
-
- data[0] = (cmnd->lun->blk_cnt >> 32) ?
- cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt - 1);
- data[1] = cpu_to_be32(1U << cmnd->lun->blk_shift);
-
- tio_set(tio, 8, 0);
-}
-
-static void build_request_sense_response(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio = cmnd->tio;
- u8 *data;
-
- assert(!tio);
- tio = cmnd->tio = tio_alloc(1);
- data = page_address(tio->pvec[0]);
- assert(data);
- memset(data, 0, 18);
- data[0] = 0xf0;
- data[1] = 0;
- data[2] = NO_SENSE;
- data[7] = 10;
- tio_set(tio, 18, 0);
-}
-
-static void build_service_action_in_response(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio = cmnd->tio;
- u32 *data;
- u64 *data64;
-
- assert(!tio);
-
- /* only READ_CAPACITY_16 service action is currently supported */
- if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) != 0x10) {
- /* Invalid Field In CDB */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
- return;
- }
-
- tio = cmnd->tio = tio_alloc(1);
- data = page_address(tio->pvec[0]);
- assert(data);
- clear_page(data);
- data64 = (u64*) data;
- data64[0] = cpu_to_be64(cmnd->lun->blk_cnt - 1);
- data[2] = cpu_to_be32(1UL << cmnd->lun->blk_shift);
-
- tio_set(tio, 12, 0);
-}
-
-static void build_read_response(struct iscsi_cmnd *cmnd)
-{
- struct tio *tio = cmnd->tio;
-
- assert(tio);
- assert(cmnd->lun);
-
- if (tio_read(cmnd->lun, tio))
- /* Medium Error/Unrecovered Read Error */
- iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x11, 0x0);
-}
-
-static void build_write_response(struct iscsi_cmnd *cmnd)
-{
- int err;
- struct tio *tio = cmnd->tio;
-
- assert(tio);
- assert(cmnd->lun);
-
- list_del_init(&cmnd->list);
- err = tio_write(cmnd->lun, tio);
- if (!err && !LUWCache(cmnd->lun))
- err = tio_sync(cmnd->lun, tio);
-
- if (err)
- /* Medium Error/Write Fault */
- iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
-}
-
-static void build_sync_cache_response(struct iscsi_cmnd *cmnd)
-{
- assert(cmnd->lun);
- if (tio_sync(cmnd->lun, NULL))
- /* Medium Error/Write Fault */
- iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
-}
-
-static void build_generic_response(struct iscsi_cmnd *cmnd)
-{
- return;
-}
-
-static void build_reserve_response(struct iscsi_cmnd *cmnd)
-{
- switch (volume_reserve(cmnd->lun, cmnd->conn->session->sid)) {
- case -ENOENT:
- /* Logical Unit Not Supported (?) */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
- break;
- case -EBUSY:
- cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
- break;
- default:
- break;
- }
-}
-
-static void build_release_response(struct iscsi_cmnd *cmnd)
-{
- int ret = volume_release(cmnd->lun,
- cmnd->conn->session->sid, 0);
- switch (ret) {
- case -ENOENT:
- /* Logical Unit Not Supported (?) */
- iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
- break;
- case -EBUSY:
- cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
- break;
- default:
- break;
- }
-}
-
-static void build_reservation_conflict_response(struct iscsi_cmnd *cmnd)
-{
- cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
-}
-
-static int disk_check_ua(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- struct ua_entry *ua;
-
- if (cmnd->lun && ua_pending(cmnd->conn->session, cmnd->lun->lun)) {
- switch(req->scb[0]){
- case INQUIRY:
- case REQUEST_SENSE:
- break;
- case REPORT_LUNS:
- ua = ua_get_match(cmnd->conn->session,
- cmnd->lun->lun,
- /* reported luns data has changed */
- 0x3f, 0x0e);
- ua_free(ua);
- break;
- default:
- ua = ua_get_first(cmnd->conn->session, cmnd->lun->lun);
- iscsi_cmnd_set_sense(cmnd, UNIT_ATTENTION, ua->asc,
- ua->ascq);
- ua_free(ua);
- send_scsi_rsp(cmnd, build_generic_response);
- return 1;
- }
- }
- return 0;
-}
-
-static int disk_check_reservation(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
-
- int ret = is_volume_reserved(cmnd->lun,
- cmnd->conn->session->sid);
- if (ret == -EBUSY) {
- switch (req->scb[0]) {
- case INQUIRY:
- case RELEASE:
- case REPORT_LUNS:
- case REQUEST_SENSE:
- case READ_CAPACITY:
- /* allowed commands when reserved */
- break;
- case SERVICE_ACTION_IN:
- if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) == 0x10)
- break;
- /* fall through */
- default:
- /* return reservation conflict for all others */
- send_scsi_rsp(cmnd,
- build_reservation_conflict_response);
- return 1;
- }
- }
-
- return 0;
-}
-
-static int disk_execute_cmnd(struct iscsi_cmnd *cmnd)
-{
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
-
- req->opcode &= ISCSI_OPCODE_MASK;
-
- if (disk_check_ua(cmnd))
- return 0;
-
- if (disk_check_reservation(cmnd))
- return 0;
-
- switch (req->scb[0]) {
- case INQUIRY:
- send_data_rsp(cmnd, build_inquiry_response);
- break;
- case REPORT_LUNS:
- send_data_rsp(cmnd, build_report_luns_response);
- break;
- case READ_CAPACITY:
- send_data_rsp(cmnd, build_read_capacity_response);
- break;
- case MODE_SENSE:
- send_data_rsp(cmnd, build_mode_sense_response);
- break;
- case REQUEST_SENSE:
- send_data_rsp(cmnd, build_request_sense_response);
- break;
- case SERVICE_ACTION_IN:
- send_data_rsp(cmnd, build_service_action_in_response);
- break;
- case READ_6:
- case READ_10:
- case READ_16:
- send_data_rsp(cmnd, build_read_response);
- break;
- case WRITE_6:
- case WRITE_10:
- case WRITE_16:
- case WRITE_VERIFY:
- send_scsi_rsp(cmnd, build_write_response);
- break;
- case SYNCHRONIZE_CACHE:
- send_scsi_rsp(cmnd, build_sync_cache_response);
- break;
- case RESERVE:
- send_scsi_rsp(cmnd, build_reserve_response);
- break;
- case RELEASE:
- send_scsi_rsp(cmnd, build_release_response);
- break;
- case START_STOP:
- case TEST_UNIT_READY:
- case VERIFY:
- case VERIFY_16:
- send_scsi_rsp(cmnd, build_generic_response);
- break;
- default:
- eprintk("%s\n", "we should not come here!");
- break;
- }
-
- return 0;
-}
-
-struct target_type disk_ops =
-{
- .id = 0,
- .execute_cmnd = disk_execute_cmnd,
-};
deleted file mode 100644
@@ -1,121 +0,0 @@
-/*
- * Target I/O.
- * (C) 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-static int tio_add_pages(struct tio *tio, int count)
-{
- int i;
- struct page *page;
-
- dprintk(D_GENERIC, "%p %d (%d)\n", tio, count, tio->pg_cnt);
-
- tio->pg_cnt = count;
-
- count *= sizeof(struct page *);
-
- do {
- tio->pvec = kzalloc(count, GFP_KERNEL);
- if (!tio->pvec)
- yield();
- } while (!tio->pvec);
-
- for (i = 0; i < tio->pg_cnt; i++) {
- do {
- if (!(page = alloc_page(GFP_KERNEL)))
- yield();
- } while (!page);
- tio->pvec[i] = page;
- }
- return 0;
-}
-
-static struct kmem_cache *tio_cache;
-
-struct tio *tio_alloc(int count)
-{
- struct tio *tio;
-
- tio = kmem_cache_alloc(tio_cache, GFP_KERNEL | __GFP_NOFAIL);
-
- tio->pg_cnt = 0;
- tio->idx = 0;
- tio->offset = 0;
- tio->size = 0;
- tio->pvec = NULL;
-
- atomic_set(&tio->count, 1);
-
- if (count)
- tio_add_pages(tio, count);
-
- return tio;
-}
-
-static void tio_free(struct tio *tio)
-{
- int i;
- for (i = 0; i < tio->pg_cnt; i++) {
- assert(tio->pvec[i]);
- __free_page(tio->pvec[i]);
- }
- kfree(tio->pvec);
- kmem_cache_free(tio_cache, tio);
-}
-
-void tio_put(struct tio *tio)
-{
- assert(atomic_read(&tio->count));
- if (atomic_dec_and_test(&tio->count))
- tio_free(tio);
-}
-
-void tio_get(struct tio *tio)
-{
- atomic_inc(&tio->count);
-}
-
-void tio_set(struct tio *tio, u32 size, loff_t offset)
-{
- tio->idx = offset >> PAGE_CACHE_SHIFT;
- tio->offset = offset & ~PAGE_CACHE_MASK;
- tio->size = size;
-}
-
-int tio_read(struct iet_volume *lu, struct tio *tio)
-{
- struct iotype *iot = lu->iotype;
- assert(iot);
- return iot->make_request ? iot->make_request(lu, tio, READ) : 0;
-}
-
-int tio_write(struct iet_volume *lu, struct tio *tio)
-{
- struct iotype *iot = lu->iotype;
- assert(iot);
- return iot->make_request ? iot->make_request(lu, tio, WRITE) : 0;
-}
-
-int tio_sync(struct iet_volume *lu, struct tio *tio)
-{
- struct iotype *iot = lu->iotype;
- assert(iot);
- return iot->sync ? iot->sync(lu, tio) : 0;
-}
-
-int tio_init(void)
-{
- tio_cache = KMEM_CACHE(tio, 0);
- return tio_cache ? 0 : -ENOMEM;
-}
-
-void tio_exit(void)
-{
- if (tio_cache)
- kmem_cache_destroy(tio_cache);
-}
deleted file mode 100644
@@ -1,176 +0,0 @@
-/*
- * IET Unit Attention support
- *
- * Copyright (C) 2009 Xie Gang <xiegang112@gmail.com>
- * Copyright (C) 2009 Arne Redlich <arne.redlich@googlemail.com>
- *
- * Released under the terms of the GNU GPL v2.0.
- */
-
-#include <scsi/scsi.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-
-#define ua_hashfn(lun) ((lun % UA_HASH_LEN))
-
-static struct kmem_cache *ua_cache;
-
-int ua_init(void)
-{
- ua_cache = KMEM_CACHE(ua_entry, 0);
- if (!ua_cache) {
- eprintk("%s", "Failed to create ua cache\n");
- return -ENOMEM;
- }
-
- return 0;
-}
-
-void ua_exit(void)
-{
- if (ua_cache)
- kmem_cache_destroy(ua_cache);
-}
-
-/* sess->ua_hash_lock needs to be held */
-static struct ua_entry * ua_find_hash(struct iscsi_session *sess, u32 lun,
- u8 asc, u8 ascq, int match)
-{
- struct ua_entry *ua;
- struct list_head *h = &sess->ua_hash[ua_hashfn(lun)];
-
- list_for_each_entry(ua, h, entry) {
- if (ua->lun == lun) {
- if (!match)
- return ua;
- if (ua->asc == asc && ua->ascq == ascq)
- return ua;
- }
- }
-
- return NULL;
-}
-
-int ua_pending(struct iscsi_session *sess, u32 lun)
-{
- struct ua_entry *ua;
-
- spin_lock(&sess->ua_hash_lock);
- ua = ua_find_hash(sess, lun, 0, 0, 0);
- spin_unlock(&sess->ua_hash_lock);
-
- dprintk_ua(ua, sess, lun);
-
- return ua ? 1 : 0;
-}
-
-/* sess->ua_hash_lock needs to be held */
-static struct ua_entry * __ua_get_hash(struct iscsi_session *sess, u32 lun,
- u8 asc, u8 ascq, int match)
-{
- struct ua_entry *ua = ua_find_hash(sess, lun, asc, ascq, match);
-
- if (ua)
- list_del_init(&ua->entry);
-
- return ua;
-}
-
-struct ua_entry * ua_get_first(struct iscsi_session *sess, u32 lun)
-{
- struct ua_entry *ua;
-
- spin_lock(&sess->ua_hash_lock);
- ua = __ua_get_hash(sess, lun, 0, 0, 0);
- spin_unlock(&sess->ua_hash_lock);
-
- dprintk_ua(ua, sess, lun);
-
- return ua;
-}
-
-struct ua_entry * ua_get_match(struct iscsi_session *sess, u32 lun,
- u8 asc, u8 ascq)
-{
- struct ua_entry *ua;
-
- spin_lock(&sess->ua_hash_lock);
- ua = __ua_get_hash(sess, lun, asc, ascq, 1);
- spin_unlock(&sess->ua_hash_lock);
-
- dprintk_ua(ua, sess, lun);
-
- return ua;
-}
-
-void ua_establish_for_session(struct iscsi_session *sess, u32 lun,
- u8 asc, u8 ascq)
-{
- struct list_head *l = &sess->ua_hash[ua_hashfn(lun)];
- struct ua_entry *ua = kmem_cache_alloc(ua_cache, GFP_ATOMIC);
- struct ua_entry *e;
-
- if (!ua) {
- eprintk("%s", "Failed to alloc ua");
- return;
- }
-
- ua->asc = asc;
- ua->ascq = ascq;
- ua->lun = lun;
- ua->session = sess;
- INIT_LIST_HEAD(&ua->entry);
-
- spin_lock(&sess->ua_hash_lock);
- /* One UA per occurrence of an event */
- list_for_each_entry(e, l, entry) {
- if (e->session == sess && e->lun == lun &&
- e->asc == asc && e->ascq == ascq &&
- e->session->exp_cmd_sn == sess->exp_cmd_sn) {
- spin_unlock(&sess->ua_hash_lock);
- ua_free(ua);
- return;
- }
- }
- list_add_tail(&ua->entry, l);
- spin_unlock(&sess->ua_hash_lock);
-
- dprintk_ua(ua, sess, lun);
-}
-
-void ua_establish_for_other_sessions(struct iscsi_session *sess, u32 lun,
- u8 asc, u8 ascq)
-{
- struct list_head *l = &sess->target->session_list;
- struct iscsi_session *s;
-
- spin_lock(&sess->target->session_list_lock);
- list_for_each_entry(s, l, list)
- if (s->sid != sess->sid)
- ua_establish_for_session(s, lun, asc, ascq);
- spin_unlock(&sess->target->session_list_lock);
-}
-
-void ua_establish_for_all_sessions(struct iscsi_target *target, u32 lun,
- u8 asc, u8 ascq)
-{
- struct list_head *l = &target->session_list;
- struct iscsi_session *s;
-
- spin_lock(&target->session_list_lock);
- list_for_each_entry(s, l, list)
- ua_establish_for_session(s, lun, asc, ascq);
- spin_unlock(&target->session_list_lock);
-
-}
-
-void ua_free(struct ua_entry *ua)
-{
- if (!ua)
- return;
-
- dprintk_ua(ua, ua->session, ua->lun);
- BUG_ON(!list_empty(&ua->entry));
- kmem_cache_free(ua_cache, ua);
-}
deleted file mode 100644
@@ -1,422 +0,0 @@
-/*
- * Volume manager
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include <linux/types.h>
-#include <linux/parser.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-#include "iotype.h"
-
-struct iet_volume *volume_lookup(struct iscsi_target *target, u32 lun)
-{
- struct iet_volume *volume;
-
- list_for_each_entry(volume, &target->volumes, list) {
- if (volume->lun == lun)
- return volume;
- }
- return NULL;
-}
-
-enum {
- opt_type,
- opt_iomode,
- opt_scsiid,
- opt_scsisn,
- opt_blk_size,
- opt_err,
-};
-
-static match_table_t tokens = {
- {opt_type, "type=%s"},
- {opt_iomode, "iomode=%s"},
- {opt_scsiid, "scsiid=%s"},
- {opt_scsisn, "scsisn=%s"},
- {opt_blk_size, "blocksize=%u"},
- {opt_err, NULL},
-};
-
-static int set_scsiid(struct iet_volume *volume, const char *id)
-{
- size_t len;
-
- if ((len = strlen(id)) > SCSI_ID_LEN) {
- eprintk("SCSI ID too long, %zd provided, %u max\n", len,
- SCSI_ID_LEN);
- return -EINVAL;
- }
-
- memcpy(volume->scsi_id, id, len);
-
- return 0;
-}
-
-static int set_scsisn(struct iet_volume *volume, const char *sn)
-{
- size_t len;
- int i;
-
- if ((len = strlen(sn)) > SCSI_SN_LEN) {
- eprintk("SCSI SN too long, %zd provided, %u max\n", len,
- SCSI_SN_LEN);
- return -EINVAL;
- }
-
- for (i = 0; i < len; i++) {
- if (!isascii(*(sn + i)) || !isprint(*(sn + i))) {
- eprintk("invalid characters in SCSI SN, %s\n",
- "only printable ascii characters allowed!");
- return -EINVAL;
- }
- }
-
- memcpy(volume->scsi_sn, sn, len);
-
- return 0;
-}
-
-/* Generate a MD5 hash of the target IQN and LUN number */
-static void gen_scsiid(struct iet_volume *volume)
-{
- struct hash_desc hash;
-
- hash.tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
- hash.flags = 0;
-
- if (hash.tfm) {
- struct scatterlist sg[2];
- unsigned int nbytes = 0;
-
- sg_init_table(sg, 2);
-
- sg_set_buf(&sg[0], volume->target->name,
- strlen(volume->target->name));
- nbytes += strlen(volume->target->name);
-
- sg_set_buf(&sg[1], &volume->lun, sizeof(volume->lun));
- nbytes += sizeof(volume->lun);
-
- crypto_hash_init(&hash);
- crypto_hash_update(&hash, sg, nbytes);
- crypto_hash_final(&hash, volume->scsi_id);
-
- crypto_free_hash(hash.tfm);
- } else {
- /* If no MD5 available set ID to TID and LUN */
- memcpy(volume->scsi_id, &volume->target->tid,
- sizeof(volume->target->tid));
- memcpy(volume->scsi_id + sizeof(volume->target->tid),
- &volume->lun, sizeof(volume->lun));
- }
-
-}
-
-static int parse_volume_params(struct iet_volume *volume, char *params)
-{
- int err = 0;
- unsigned blk_sz;
- substring_t args[MAX_OPT_ARGS];
- char *p, *argp = NULL, *buf = (char *) get_zeroed_page(GFP_USER);
-
- if (!buf)
- return -ENOMEM;
-
- strncpy(buf, params, PAGE_CACHE_SIZE);
-
- while ((p = strsep(&buf, ",")) != NULL) {
- int token;
-
- if (!*p)
- continue;
- iet_strtolower(p);
- token = match_token(p, tokens, args);
- switch (token) {
- case opt_type:
- argp = match_strdup(&args[0]);
- if (!argp) {
- err = -ENOMEM;
- break;
- }
- if (!(volume->iotype = get_iotype(argp)))
- err = -ENOENT;
- kfree(argp);
- break;
- case opt_iomode:
- argp = match_strdup(&args[0]);
- if (!argp) {
- err = -ENOMEM;
- break;
- }
- if (!strcmp(argp, "ro"))
- SetLUReadonly(volume);
- else if (!strcmp(argp, "wb"))
- SetLUWCache(volume);
- else if (strcmp(argp, "wt"))
- err = -EINVAL;
- kfree(argp);
- break;
- case opt_scsiid:
- argp = match_strdup(&args[0]);
- if (!argp) {
- err = -ENOMEM;
- break;
- }
- err = set_scsiid(volume, argp);
- kfree(argp);
- break;
- case opt_scsisn:
- argp = match_strdup(&args[0]);
- if (!argp) {
- err = -ENOMEM;
- break;
- }
- err = set_scsisn(volume, argp);
- kfree(argp);
- break;
- case opt_blk_size:
- argp = match_strdup(&args[0]);
- if (!argp) {
- err = -ENOMEM;
- break;
- }
- blk_sz = simple_strtoull(argp, NULL, 10);
- if (is_power_of_2(blk_sz) &&
- 512 <= blk_sz && blk_sz <= IET_MAX_BLOCK_SIZE)
- volume->blk_shift = blksize_bits(blk_sz);
- else {
- eprintk("invalid BlockSize=%u\n", blk_sz);
- err = -EINVAL;
- }
- kfree(argp);
- break;
- default:
- break;
- }
- }
-
- if (!err && !volume->iotype && !(volume->iotype = get_iotype("fileio"))) {
- eprintk("%s\n", "Cannot find fileio");
- err = -EINVAL;
- }
-
- free_page((unsigned long) buf);
-
- return err;
-}
-
-int volume_add(struct iscsi_target *target, struct volume_info *info)
-{
- int ret;
- struct iet_volume *volume;
- char *args;
-
- volume = volume_lookup(target, info->lun);
- if (volume)
- return -EEXIST;
-
- if (info->lun > 0x3fff)
- return -EINVAL;
-
- volume = kzalloc(sizeof(*volume), GFP_KERNEL);
- if (!volume)
- return -ENOMEM;
-
- volume->target = target;
- volume->lun = info->lun;
-
- args = kzalloc(info->args_len + 1, GFP_KERNEL);
- if (!args) {
- ret = -ENOMEM;
- goto free_volume;
- }
-
- ret = copy_from_user(args, (void *)(unsigned long)info->args_ptr,
- info->args_len);
- if (ret) {
- ret = -EFAULT;
- goto free_args;
- }
-
- ret = parse_volume_params(volume, args);
- if (ret < 0)
- goto free_args;
-
- ret = volume->iotype->attach(volume, args);
- if (ret < 0)
- goto free_args;
-
- if (!volume->scsi_id[0])
- gen_scsiid(volume);
-
- if (!volume->scsi_sn[0]) {
- int i;
-
- for (i = 0; i < SCSI_ID_LEN; i++)
- snprintf(volume->scsi_sn + (i * 2), 3, "%02x",
- volume->scsi_id[i]);
- }
-
- INIT_LIST_HEAD(&volume->queue.wait_list);
- spin_lock_init(&volume->queue.queue_lock);
- spin_lock_init(&volume->reserve_lock);
-
- volume->l_state = IDEV_RUNNING;
- atomic_set(&volume->l_count, 0);
-
- list_add_tail(&volume->list, &target->volumes);
- atomic_inc(&target->nr_volumes);
-
- kfree(args);
-
- return 0;
-free_args:
- kfree(args);
-free_volume:
- put_iotype(volume->iotype);
- kfree(volume);
-
- return ret;
-}
-
-void iscsi_volume_destroy(struct iet_volume *volume)
-{
- assert(volume->l_state == IDEV_DEL);
- assert(!atomic_read(&volume->l_count));
-
- volume->iotype->detach(volume);
- put_iotype(volume->iotype);
- list_del(&volume->list);
- kfree(volume);
-}
-
-int iscsi_volume_del(struct iscsi_target *target, struct volume_info *info)
-{
- struct iet_volume *volume;
-
- eprintk("%x %x\n", target->tid, info->lun);
- if (!(volume = volume_lookup(target, info->lun)))
- return -ENOENT;
-
- volume->l_state = IDEV_DEL;
- atomic_dec(&target->nr_volumes);
- if (!atomic_read(&volume->l_count))
- iscsi_volume_destroy(volume);
-
- return 0;
-}
-
-struct iet_volume *volume_get(struct iscsi_target *target, u32 lun)
-{
- struct iet_volume *volume;
-
- if ((volume = volume_lookup(target, lun))) {
- if (volume->l_state == IDEV_RUNNING)
- atomic_inc(&volume->l_count);
- else
- volume = NULL;
- }
- return volume;
-}
-
-void volume_put(struct iet_volume *volume)
-{
- if (atomic_dec_and_test(&volume->l_count) && volume->l_state == IDEV_DEL)
- iscsi_volume_destroy(volume);
-}
-
-int volume_reserve(struct iet_volume *volume, u64 sid)
-{
- int err = 0;
-
- if (!volume)
- return -ENOENT;
-
- spin_lock(&volume->reserve_lock);
- if (volume->reserve_sid && volume->reserve_sid != sid)
- err = -EBUSY;
- else
- volume->reserve_sid = sid;
-
- spin_unlock(&volume->reserve_lock);
- return err;
-}
-
-int is_volume_reserved(struct iet_volume *volume, u64 sid)
-{
- int err = 0;
-
- if (!volume)
- return -ENOENT;
-
- spin_lock(&volume->reserve_lock);
- if (!volume->reserve_sid || volume->reserve_sid == sid)
- err = 0;
- else
- err = -EBUSY;
-
- spin_unlock(&volume->reserve_lock);
- return err;
-}
-
-int volume_release(struct iet_volume *volume, u64 sid, int force)
-{
- int err = 0;
-
- if (!volume)
- return -ENOENT;
-
- spin_lock(&volume->reserve_lock);
-
- if (force || volume->reserve_sid == sid)
- volume->reserve_sid = 0;
- else
- err = -EBUSY;
-
- spin_unlock(&volume->reserve_lock);
- return err;
-}
-
-static void iet_volume_info_show(struct seq_file *seq, struct iscsi_target *target)
-{
- struct iet_volume *volume;
-
- list_for_each_entry(volume, &target->volumes, list) {
- seq_printf(seq, "\tlun:%u state:%x iotype:%s",
- volume->lun, volume->l_state, volume->iotype->name);
- if (LUReadonly(volume))
- seq_printf(seq, " iomode:ro");
- else if (LUWCache(volume))
- seq_printf(seq, " iomode:wb");
- else
- seq_printf(seq, " iomode:wt");
-
- seq_printf(seq, " blocks:%llu blocksize:%u",
- volume->blk_cnt, 1 << volume->blk_shift);
- if (volume->iotype->show)
- volume->iotype->show(volume, seq);
- else
- seq_printf(seq, "\n");
- }
-}
-
-static int iet_volume_seq_open(struct inode *inode, struct file *file)
-{
- int res;
- res = seq_open(file, &iet_seq_op);
- if (!res)
- ((struct seq_file *)file->private_data)->private =
- iet_volume_info_show;
- return res;
-}
-
-struct file_operations volume_seq_fops = {
- .owner = THIS_MODULE,
- .open = iet_volume_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
-};
deleted file mode 100644
@@ -1,258 +0,0 @@
-/*
- * Worker thread.
- * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
- * This code is licenced under the GPL.
- */
-
-#include <linux/kthread.h>
-
-#include "iscsi.h"
-#include "iscsi_dbg.h"
-
-struct worker_thread_info *worker_thread_pool;
-
-void wthread_queue(struct iscsi_cmnd *cmnd)
-{
- struct worker_thread_info *info = cmnd->conn->session->target->wthread_info;
-
- if (!list_empty(&cmnd->list)) {
- struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
- eprintk("%x %p %x %x %x %x %lx %x\n",
- cmnd_itt(cmnd), req, req->opcode, req->scb[0], cmnd->pdu.datasize,
- be32_to_cpu(req->data_length), cmnd->flags, req->flags);
-
- if (cmnd->lun)
- eprintk("%u\n", cmnd->lun->lun);
- assert(list_empty(&cmnd->list));
- }
-
- spin_lock(&info->wthread_lock);
- list_add_tail(&cmnd->list, &info->work_queue);
- spin_unlock(&info->wthread_lock);
-
- atomic_inc(&cmnd->conn->nr_busy_cmnds);
-
- wake_up(&info->wthread_sleep);
-}
-
-static struct iscsi_cmnd * get_ready_cmnd(struct worker_thread_info *info)
-{
- struct iscsi_cmnd *cmnd = NULL;
-
- spin_lock(&info->wthread_lock);
- if (!list_empty(&info->work_queue)) {
- cmnd = list_entry(info->work_queue.next, struct iscsi_cmnd, list);
- list_del_init(&cmnd->list);
-
- assert(cmnd->conn);
- }
- spin_unlock(&info->wthread_lock);
-
- return cmnd;
-}
-
-static int cmnd_execute(struct iscsi_cmnd *cmnd)
-{
- int type = cmnd->conn->session->target->trgt_param.target_type;
-
- assert(target_type_array[type]->execute_cmnd);
- return target_type_array[type]->execute_cmnd(cmnd);
-}
-
-static void copy_io_context(struct io_context **pdst, struct io_context **psrc)
-{
- struct io_context *src = *psrc;
- struct io_context *dst = *pdst;
-
- if (src) {
- BUG_ON(atomic_long_read(&src->refcount) == 0);
- atomic_long_inc(&src->refcount);
- put_io_context(dst);
- *pdst = src;
- }
-}
-
-static int worker_thread(void *arg)
-{
- struct worker_thread *wt = (struct worker_thread *) arg;
- struct worker_thread_info *info = wt->w_info;
- struct iscsi_cmnd *cmnd;
- struct iscsi_conn *conn;
- DECLARE_WAITQUEUE(wait, current);
-
- get_io_context(GFP_KERNEL, -1);
-
- if (!current->io_context)
- eprintk("%s\n", "Failed to get IO context");
- else if (info->wthread_ioc)
- copy_io_context(¤t->io_context, &info->wthread_ioc);
- else
- info->wthread_ioc = current->io_context;
-
- add_wait_queue(&info->wthread_sleep, &wait);
-
- __set_current_state(TASK_RUNNING);
- do {
- while (!list_empty(&info->work_queue) &&
- (cmnd = get_ready_cmnd(info))) {
- conn = cmnd->conn;
- if (cmnd_tmfabort(cmnd))
- cmnd_release(cmnd, 1);
- else
- cmnd_execute(cmnd);
- assert(conn);
- atomic_dec(&conn->nr_busy_cmnds);
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
- if (list_empty(&info->work_queue))
- schedule();
-
- __set_current_state(TASK_RUNNING);
- } while (!kthread_should_stop());
-
- remove_wait_queue(&info->wthread_sleep, &wait);
-
- if (current->io_context) {
- struct io_context *ioc = current->io_context;
-
- task_lock(current);
- current->io_context = NULL;
- task_unlock(current);
-
- put_io_context(ioc);
- }
-
- return 0;
-}
-
-static int start_one_worker_thread(struct worker_thread_info *info, u32 tid)
-{
- struct worker_thread *wt;
- struct task_struct *task;
-
- if (!(wt = kmalloc(sizeof(struct worker_thread), GFP_KERNEL)))
- return -ENOMEM;
-
- wt->w_info = info;
- task = kthread_create(worker_thread, wt, "istiod%d", tid);
- if (IS_ERR(task)) {
- kfree(wt);
- return PTR_ERR(task);
- }
-
- wt->w_task = task;
- list_add(&wt->w_list, &info->wthread_list);
- info->nr_running_wthreads++;
-
- wake_up_process(task);
-
- return 0;
-}
-
-static int stop_one_worker_thread(struct worker_thread *wt)
-{
- struct worker_thread_info *info = wt->w_info;
- int err;
-
- assert(wt->w_task);
- err = kthread_stop(wt->w_task);
-
- if (err < 0 && err != -EINTR)
- return err;
-
- list_del(&wt->w_list);
- kfree(wt);
- info->nr_running_wthreads--;
-
- return 0;
-}
-
-int wthread_init(struct worker_thread_info *info)
-{
- spin_lock_init(&info->wthread_lock);
-
- info->nr_running_wthreads = 0;
- info->wthread_ioc = NULL;
-
- INIT_LIST_HEAD(&info->work_queue);
- INIT_LIST_HEAD(&info->wthread_list);
-
- init_waitqueue_head(&info->wthread_sleep);
-
- return 0;
-}
-
-int wthread_start(struct worker_thread_info *info, int wthreads, u32 tid)
-{
- int err = 0;
-
- while (info->nr_running_wthreads < wthreads) {
- if ((err = start_one_worker_thread(info, tid)) < 0) {
- eprintk("Fail to create a worker thread %d\n", err);
- goto out;
- }
- }
-
- while (info->nr_running_wthreads > wthreads) {
- struct worker_thread *wt;
- wt = list_entry(info->wthread_list.next, struct worker_thread, w_list);
- if ((err = stop_one_worker_thread(wt)) < 0) {
- eprintk("Fail to stop a worker thread %d\n", err);
- break;
- }
- }
-out:
- return err;
-}
-
-int wthread_stop(struct worker_thread_info *info)
-{
- struct worker_thread *wt, *tmp;
- int err = 0;
-
- list_for_each_entry_safe(wt, tmp, &info->wthread_list, w_list) {
- if ((err = stop_one_worker_thread(wt)) < 0) {
- eprintk("Fail to stop a worker thread %d\n", err);
- return err;
- }
- }
-
- return err;
-}
-
-int wthread_module_init()
-{
- int err;
-
- if (!worker_thread_pool_size)
- return 0;
-
- worker_thread_pool = kmalloc(sizeof(struct worker_thread_info),
- GFP_KERNEL);
- if (!worker_thread_pool)
- return -ENOMEM;
-
- wthread_init(worker_thread_pool);
-
- err = wthread_start(worker_thread_pool, worker_thread_pool_size, 0);
- if (err) {
- kfree(worker_thread_pool);
- worker_thread_pool = NULL;
- return err;
- }
-
- iprintk("iscsi_trgt using worker thread pool; size = %ld\n",
- worker_thread_pool_size);
-
- return 0;
-}
-
-void wthread_module_exit()
-{
- if (!worker_thread_pool_size)
- return;
-
- wthread_stop(worker_thread_pool);
- kfree(worker_thread_pool);
-}
--
1.7.4.1