From: <vl...@us...> - 2007-10-25 16:20:03
|
Revision: 212 http://scst.svn.sourceforge.net/scst/?rev=212&view=rev Author: vlnb Date: 2007-10-25 09:19:40 -0700 (Thu, 25 Oct 2007) Log Message: ----------- - Fixed ignoring errors on the service start. Reported by Tomasz Chmielewski <ma...@wp...> - Minor fixes Modified Paths: -------------- trunk/iscsi-scst/usr/iscsi_scstd.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_main.c Modified: trunk/iscsi-scst/usr/iscsi_scstd.c =================================================================== --- trunk/iscsi-scst/usr/iscsi_scstd.c 2007-10-25 10:46:29 UTC (rev 211) +++ trunk/iscsi-scst/usr/iscsi_scstd.c 2007-10-25 16:19:40 UTC (rev 212) @@ -80,6 +80,8 @@ /* This will be comfigurable by command line options */ struct config_operations *cops = &plain_ops; +int init_report_pipe[2]; + static void usage(int status) { if (status != 0) @@ -149,38 +151,40 @@ hints.ai_flags = AI_PASSIVE; if (getaddrinfo(server_address, servname, &hints, &res0)) { - log_error("unable to get address info (%s)!", strerror(errno)); + log_error("Unable to get address info (%s)!", strerror(errno)); exit(1); } for (i = 0, res = res0; res && i < LISTEN_MAX; i++, res = res->ai_next) { sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) { - log_error("unable to create server socket (%s) %d %d %d!", + log_error("Unable to create server socket (%s) %d %d %d!", strerror(errno), res->ai_family, res->ai_socktype, res->ai_protocol); - continue; + exit(1); } sock_set_keepalive(sock, 50); opt = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) - log_warning("unable to set SO_REUSEADDR on server socket (%s)!", + log_warning("Unable to set SO_REUSEADDR on server socket (%s)!", strerror(errno)); opt = 1; if (res->ai_family == AF_INET6 && - setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))) - continue; + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))) { + log_error("Unable to restrict IPv6 socket (%s)", strerror(errno)); + exit(1); + } if (bind(sock, res->ai_addr, res->ai_addrlen)) { - log_error("unable to bind server socket (%s)!", strerror(errno)); - continue; + log_error("Unable to bind server socket (%s)!", strerror(errno)); + exit(1); } if (listen(sock, INCOMING_MAX)) { - log_error("unable to listen to server socket (%s)!", strerror(errno)); - continue; + log_error("Unable to listen to server socket (%s)!", strerror(errno)); + exit(1); } set_non_blocking(sock); @@ -439,6 +443,11 @@ incoming[i] = NULL; } + close(init_report_pipe[0]); + res = 0; + write(init_report_pipe[1], &res, sizeof(res)); + close(init_report_pipe[1]); + while (1) { res = poll(poll_array, POLL_MAX, timeout); if (res == 0) { @@ -506,6 +515,11 @@ char *isns = NULL; int isns_ac = 0; + if (pipe(init_report_pipe) == -1) { + perror("pipe"); + exit(-1); + } + while ((ch = getopt_long(argc, argv, "c:fd:s:u:g:a:p:vh", long_options, &longindex)) >= 0) { switch (ch) { case 'c': @@ -572,8 +586,14 @@ if (pid < 0) { log_error("starting daemon failed"); exit(1); - } else if (pid) - exit(0); + } else if (pid) { + int res = -1; + close(init_report_pipe[1]); + if (read(init_report_pipe[0], &res, sizeof(res)) < sizeof(res)) + exit(-1); + else + exit(res); + } chdir("/"); if (lockf(fd, F_TLOCK, 0) < 0) { Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-10-25 10:46:29 UTC (rev 211) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-10-25 16:19:40 UTC (rev 212) @@ -37,6 +37,7 @@ #include <linux/vmalloc.h> #include <asm/atomic.h> #include <linux/kthread.h> +#include <linux/sched.h> #define LOG_PREFIX "dev_vdisk" Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-10-25 10:46:29 UTC (rev 211) +++ trunk/scst/src/scst_main.c 2007-10-25 16:19:40 UTC (rev 212) @@ -139,7 +139,7 @@ struct scst_dev_type scst_null_devtype = { - name: "null_handler", + name: "none", }; int scst_register_target_template(struct scst_tgt_template *vtt) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-11-26 16:24:36
|
Revision: 225 http://scst.svn.sourceforge.net/scst/?rev=225&view=rev Author: vlnb Date: 2007-11-26 08:23:50 -0800 (Mon, 26 Nov 2007) Log Message: ----------- - Fixes build problem in perf mode - Switches between debug modes made as Makefile targets, thanks Tomasz Chmielewski <ma...@wp...> for idea Modified Paths: -------------- trunk/Makefile trunk/iscsi-scst/README trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/scst/README Removed Paths: ------------- trunk/debug2perf trunk/debug2release trunk/perf2debug trunk/release2debug Modified: trunk/Makefile =================================================================== --- trunk/Makefile 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/Makefile 2007-11-26 16:23:50 UTC (rev 225) @@ -64,6 +64,11 @@ @echo " usr_install : usr target: install" @echo " usr_uninstall : usr target: uninstall" @echo "" + @echo " debug2perf : changes debug state from full debug to full performance" + @echo " debug2release : changes debug state from full debug to release" + @echo " perf2debug : changes debug state from full performance to full debug" + @echo " release2debug : changes debug state from release to full debug" + @echo "" @echo " Note:" @echo " - install and uninstall may need root privileges" @@ -181,9 +186,38 @@ usr_extraclean: cd $(USR_DIR) && $(MAKE) extraclean +debug2perf: + echo "Changing current debug state from full debug to full performance" + patch -p0 <scst-full_perf.patch + patch -p0 <usr-full_perf.patch + patch -p0 <qla2x00t-full_perf.patch + patch -p0 <iscsi-full_perf.patch + +debug2release: + echo "Changing current debug state from full debug to release" + patch -p0 <scst-release.patch + patch -p0 <usr-release.patch + patch -p0 <qla2x00t-release.patch + patch -p0 <iscsi-release.patch + +perf2debug: + echo "Changing current debug state from full performance to full debug" + patch -p0 -R <scst-full_perf.patch + patch -p0 -R <usr-full_perf.patch + patch -p0 -R <qla2x00t-full_perf.patch + patch -p0 -R <iscsi-full_perf.patch + +release2debug: + echo "Changing current debug state from release to full debug" + patch -p0 -R <scst-release.patch + patch -p0 -R <usr-release.patch + patch -p0 -R <qla2x00t-release.patch + patch -p0 -R <iscsi-release.patch + .PHONY: all install uninstall clean extraclean help \ qla qla_install qla_uninstall qla_clean qla_extraclean \ lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \ iscsi iscsi_install iscsi_uninstall iscsi_clean iscsi_extraclean \ scst scst_install scst_uninstall scst_clean scst_extraclean \ - usr usr_install usr_uninstall usr_clean usr_extraclean + usr usr_install usr_uninstall usr_clean usr_extraclean \ + debug2perf, debug2release, perf2debug, release2debug Deleted: trunk/debug2perf =================================================================== --- trunk/debug2perf 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/debug2perf 2007-11-26 16:23:50 UTC (rev 225) @@ -1,8 +0,0 @@ -#!/bin/bash - -echo "Changing current debug state from full debug to full performance" - -patch -p0 <scst-full_perf.patch && \ -patch -p0 <usr-full_perf.patch && \ -patch -p0 <qla2x00t-full_perf.patch && \ -patch -p0 <iscsi-full_perf.patch Deleted: trunk/debug2release =================================================================== --- trunk/debug2release 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/debug2release 2007-11-26 16:23:50 UTC (rev 225) @@ -1,8 +0,0 @@ -#!/bin/bash - -echo "Changing current debug state from full debug to release" - -patch -p0 <scst-release.patch && \ -patch -p0 <usr-release.patch && \ -patch -p0 <qla2x00t-release.patch && \ -patch -p0 <iscsi-release.patch Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/iscsi-scst/README 2007-11-26 16:23:50 UTC (rev 225) @@ -153,5 +153,7 @@ * Alexey Kuznetsov <ku...@ms...> for comments and help in debugging + + * Tomasz Chmielewski <ma...@wp...> for testing and suggestions Vladislav Bolkhovitin <vs...@vl...>, http://scst.sourceforge.net Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2007-11-26 16:23:50 UTC (rev 225) @@ -99,6 +99,7 @@ #else /* defined(DEBUG) || defined(TRACING) */ #define TRACE_CONN_CLOSE(format, args...) {} +#define TRACE_CONN_CLOSE_DBG(format, args...) {} #define TRACE_NET_PAGE(format, args...) {} #endif Deleted: trunk/perf2debug =================================================================== --- trunk/perf2debug 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/perf2debug 2007-11-26 16:23:50 UTC (rev 225) @@ -1,8 +0,0 @@ -#!/bin/bash - -echo "Changing current debug state from full performance to full debug" - -patch -p0 -R <scst-full_perf.patch && \ -patch -p0 -R <usr-full_perf.patch && \ -patch -p0 -R <qla2x00t-full_perf.patch && \ -patch -p0 -R <iscsi-full_perf.patch Deleted: trunk/release2debug =================================================================== --- trunk/release2debug 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/release2debug 2007-11-26 16:23:50 UTC (rev 225) @@ -1,8 +0,0 @@ -#!/bin/bash - -echo "Changing current debug state from release to full debug" - -patch -p0 -R <scst-release.patch && \ -patch -p0 -R <usr-release.patch && \ -patch -p0 -R <qla2x00t-release.patch && \ -patch -p0 -R <iscsi-release.patch Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-11-16 18:46:02 UTC (rev 224) +++ trunk/scst/README 2007-11-26 16:23:50 UTC (rev 225) @@ -594,9 +594,9 @@ ========= is optimized currently rather for development and bug hunting, than for performance. -If you use SCST version taken directly from its SVN repository, you can +If you use SCST version taken directly from the SVN repository, you can set the above options, except ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ, using -debug2perf script file. +debug2perf Makefile target. 4. For kernel: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-10 12:09:12
|
Revision: 230 http://scst.svn.sourceforge.net/scst/?rev=230&view=rev Author: vlnb Date: 2007-12-10 04:09:07 -0800 (Mon, 10 Dec 2007) Log Message: ----------- Post r227 fixes and cleanups. Particulary, fixes brocken by it scst_user functionality and release/perf builds Modified Paths: -------------- trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_dev_handler.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_targ.c trunk/usr/fileio/fileio.c Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/include/scsi_tgt.h 2007-12-10 12:09:07 UTC (rev 230) @@ -385,7 +385,6 @@ struct scst_device; struct scst_tgt_dev; struct scst_dev_type; -struct scst_info_cdb; struct scst_acg; struct scst_acg_dev; struct scst_acn; @@ -394,6 +393,15 @@ typedef enum dma_data_direction scst_data_direction; +enum scst_cdb_flags +{ + SCST_TRANSFER_LEN_TYPE_FIXED = 0x01, /* must be equviv 1 (FIXED_BIT in cdb) */ + SCST_SMALL_TIMEOUT = 0x02, + SCST_LONG_TIMEOUT = 0x04, + SCST_UNKNOWN_LENGTH = 0x08, + SCST_INFO_INVALID = 0x10, +}; + /* * Scsi_Target_Template: defines what functions a target driver will * have to provide in order to work with the target mid-level. @@ -688,7 +696,7 @@ * * MUST HAVE */ - int (*parse) (struct scst_cmd *cmd, struct scst_info_cdb *cdb_info); + int (*parse) (struct scst_cmd *cmd); /* * Called to execute CDB. Useful, for instance, to implement @@ -1120,6 +1128,9 @@ uint8_t cdb[SCST_MAX_CDB_SIZE]; int cdb_len; + enum scst_cdb_flags op_flags; + const char *op_name; + enum scst_cmd_queue_type queue_type; int timeout; /* CDB execution timeout */ @@ -1505,24 +1516,6 @@ uint8_t UA_sense_buffer[SCST_SENSE_BUFFERSIZE]; }; -enum scst_cdb_flags -{ - SCST_TRANSFER_LEN_TYPE_FIXED = 0x01, /* must be equviv 1 (FIXED_BIT in cdb) */ - SCST_SMALL_TIMEOUT = 0x02, - SCST_LONG_TIMEOUT = 0x04, - SCST_UNKNOWN_LENGTH = 0x08, - SCST_INFO_INVALID = 0x10, -}; - -struct scst_info_cdb -{ - enum scst_cdb_flags flags; - scst_data_direction direction; - unsigned int transfer_len; - unsigned short cdb_len; - const char *op_name; -}; - #ifndef smp_mb__after_set_bit /* There is no smp_mb__after_set_bit() in the kernel */ #define smp_mb__after_set_bit() smp_mb(); @@ -1785,11 +1778,12 @@ * Parameters: * cdb_p - pointer to CDB * dev_type - SCSI device type - * info_p - the result structure (output) + * op_flags, direction, transfer_len, cdb_len, op_name - the result (output) * Returns 0 on success, -1 otherwise */ int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type, - struct scst_info_cdb *info_p); + enum scst_cdb_flags *op_flags, scst_data_direction *direction, + unsigned int *transfer_len, int *cdb_len, const char **op_name); /* * Set error SCSI status in the command and prepares it for returning it @@ -2470,37 +2464,30 @@ /* Generic parse() for SBC (disk) devices */ int scst_sbc_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)); /* Generic parse() for MMC (cdrom) devices */ int scst_cdrom_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)); /* Generic parse() for MO disk devices */ int scst_modisk_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)); /* Generic parse() for tape devices */ int scst_tape_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_size)(struct scst_cmd *cmd)); /* Generic parse() for changer devices */ int scst_changer_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)); /* Generic parse() for "processor" devices */ int scst_processor_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)); /* Generic parse() for RAID devices */ int scst_raid_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)); /** Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2007-12-10 12:09:07 UTC (rev 230) @@ -51,7 +51,7 @@ int cdrom_attach(struct scst_device *); void cdrom_detach(struct scst_device *); -int cdrom_parse(struct scst_cmd *, struct scst_info_cdb *); +int cdrom_parse(struct scst_cmd *); int cdrom_done(struct scst_cmd *); static struct scst_dev_type cdrom_devtype = CDROM_TYPE; @@ -205,21 +205,21 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int cdrom_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int cdrom_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_cdrom_generic_parse(cmd, info_cdb, cdrom_get_block_shift); + scst_cdrom_generic_parse(cmd, cdrom_get_block_shift); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_SMALL_TIMEOUT) { + if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0) + cmd->timeout = CDROM_REG_TIMEOUT; + else if (cmd->op_flags & SCST_SMALL_TIMEOUT) cmd->timeout = CDROM_SMALL_TIMEOUT; - } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { + else if (cmd->op_flags & SCST_LONG_TIMEOUT) cmd->timeout = CDROM_LONG_TIMEOUT; - } else { - cmd->timeout = CDROM_REG_TIMEOUT; - } + return res; } Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_changer.c 2007-12-10 12:09:07 UTC (rev 230) @@ -44,7 +44,7 @@ int changer_attach(struct scst_device *); void changer_detach(struct scst_device *); -int changer_parse(struct scst_cmd *, struct scst_info_cdb *); +int changer_parse(struct scst_cmd *); int changer_done(struct scst_cmd *); static struct scst_dev_type changer_devtype = CHANGER_TYPE; @@ -126,15 +126,15 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int changer_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int changer_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_changer_generic_parse(cmd, info_cdb, 0); + scst_changer_generic_parse(cmd, 0); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_LONG_TIMEOUT) { + if (cmd->op_flags & SCST_LONG_TIMEOUT) { cmd->timeout = CHANGER_LONG_TIMEOUT; } else { cmd->timeout = CHANGER_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_dev_handler.h =================================================================== --- trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_dev_handler.h 2007-12-10 12:09:07 UTC (rev 230) @@ -8,6 +8,7 @@ #include "scst_debug.h" #define SCST_DEV_UA_RETRIES 5 +#define SCST_PASSTHROUGH_RETRIES 0 #if defined(DEBUG) || defined(TRACING) @@ -29,8 +30,6 @@ #define trace_log_tbl NULL #endif -#define SCST_PASSTHROUGH_RETRIES 0 - static struct scst_proc_data dev_handler_log_proc_data; static int dev_handler_log_info_show(struct seq_file *seq, void *v) Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_disk.c 2007-12-10 12:09:07 UTC (rev 230) @@ -70,7 +70,7 @@ int disk_attach(struct scst_device *dev); void disk_detach(struct scst_device *dev); -int disk_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cmd); +int disk_parse(struct scst_cmd *cmd); int disk_done(struct scst_cmd *cmd); int disk_exec(struct scst_cmd *cmd); @@ -277,21 +277,20 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int disk_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int disk_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_sbc_generic_parse(cmd, info_cdb, disk_get_block_shift); + scst_sbc_generic_parse(cmd, disk_get_block_shift); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_SMALL_TIMEOUT) { + if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0) + cmd->timeout = DISK_REG_TIMEOUT; + else if (cmd->op_flags & SCST_SMALL_TIMEOUT) cmd->timeout = DISK_SMALL_TIMEOUT; - } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { + else if (cmd->op_flags & SCST_LONG_TIMEOUT) cmd->timeout = DISK_LONG_TIMEOUT; - } else { - cmd->timeout = DISK_REG_TIMEOUT; - } return res; } Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2007-12-10 12:09:07 UTC (rev 230) @@ -70,7 +70,7 @@ int modisk_attach(struct scst_device *); void modisk_detach(struct scst_device *); -int modisk_parse(struct scst_cmd *, struct scst_info_cdb *); +int modisk_parse(struct scst_cmd *); int modisk_done(struct scst_cmd *); int modisk_exec(struct scst_cmd *); @@ -292,21 +292,21 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int modisk_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int modisk_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_modisk_generic_parse(cmd, info_cdb, modisk_get_block_shift); + scst_modisk_generic_parse(cmd, modisk_get_block_shift); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_SMALL_TIMEOUT) { + if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0) + cmd->timeout = MODISK_REG_TIMEOUT; + else if (cmd->op_flags & SCST_SMALL_TIMEOUT) cmd->timeout = MODISK_SMALL_TIMEOUT; - } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { + else if (cmd->op_flags & SCST_LONG_TIMEOUT) cmd->timeout = MODISK_LONG_TIMEOUT; - } else { - cmd->timeout = MODISK_REG_TIMEOUT; - } + return res; } Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_processor.c 2007-12-10 12:09:07 UTC (rev 230) @@ -44,7 +44,7 @@ int processor_attach(struct scst_device *); void processor_detach(struct scst_device *); -int processor_parse(struct scst_cmd *, struct scst_info_cdb *); +int processor_parse(struct scst_cmd *); int processor_done(struct scst_cmd *); static struct scst_dev_type processor_devtype = PROCESSOR_TYPE; @@ -126,15 +126,15 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int processor_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int processor_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_processor_generic_parse(cmd, info_cdb, 0); + scst_processor_generic_parse(cmd, 0); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_LONG_TIMEOUT) { + if (cmd->op_flags & SCST_LONG_TIMEOUT) { cmd->timeout = PROCESSOR_LONG_TIMEOUT; } else { cmd->timeout = PROCESSOR_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_raid.c 2007-12-10 12:09:07 UTC (rev 230) @@ -44,7 +44,7 @@ int raid_attach(struct scst_device *); void raid_detach(struct scst_device *); -int raid_parse(struct scst_cmd *, struct scst_info_cdb *); +int raid_parse(struct scst_cmd *); int raid_done(struct scst_cmd *); static struct scst_dev_type raid_devtype = RAID_TYPE; @@ -126,15 +126,15 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int raid_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int raid_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_raid_generic_parse(cmd, info_cdb, 0); + scst_raid_generic_parse(cmd, 0); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_LONG_TIMEOUT) { + if (cmd->op_flags & SCST_LONG_TIMEOUT) { cmd->timeout = RAID_LONG_TIMEOUT; } else { cmd->timeout = RAID_TIMEOUT; Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_tape.c 2007-12-10 12:09:07 UTC (rev 230) @@ -75,7 +75,7 @@ int tape_attach(struct scst_device *); void tape_detach(struct scst_device *); -int tape_parse(struct scst_cmd *, struct scst_info_cdb *); +int tape_parse(struct scst_cmd *); int tape_done(struct scst_cmd *); int tape_exec(struct scst_cmd *); @@ -280,21 +280,21 @@ * * Note: Not all states are allowed on return ********************************************************************/ -int tape_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +int tape_parse(struct scst_cmd *cmd) { int res = SCST_CMD_STATE_DEFAULT; - scst_tape_generic_parse(cmd, info_cdb, tape_get_block_size); + scst_tape_generic_parse(cmd, tape_get_block_size); cmd->retries = SCST_PASSTHROUGH_RETRIES; - if (info_cdb->flags & SCST_SMALL_TIMEOUT) { + if ((cmd->op_flags & (SCST_SMALL_TIMEOUT | SCST_LONG_TIMEOUT)) == 0) + cmd->timeout = TAPE_REG_TIMEOUT; + else if (cmd->op_flags & SCST_SMALL_TIMEOUT) cmd->timeout = TAPE_SMALL_TIMEOUT; - } else if (info_cdb->flags & SCST_LONG_TIMEOUT) { + else if (cmd->op_flags & SCST_LONG_TIMEOUT) cmd->timeout = TAPE_LONG_TIMEOUT; - } else { - cmd->timeout = TAPE_REG_TIMEOUT; - } + return res; } Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-12-10 12:09:07 UTC (rev 230) @@ -67,7 +67,7 @@ unsigned short detach_cmd_count; - int (*generic_parse)(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb, + int (*generic_parse)(struct scst_cmd *cmd, int (*get_block)(struct scst_cmd *cmd)); int block; @@ -154,7 +154,7 @@ int gfp_mask); static void dev_user_free_ucmd(struct scst_user_cmd *ucmd); -static int dev_user_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb); +static int dev_user_parse(struct scst_cmd *cmd); static int dev_user_exec(struct scst_cmd *cmd); static void dev_user_on_free_cmd(struct scst_cmd *cmd); static int dev_user_task_mgmt_fn(struct scst_mgmt_cmd *mcmd, @@ -648,7 +648,7 @@ return dev->block; } -static int dev_user_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +static int dev_user_parse(struct scst_cmd *cmd) { int rc, res = SCST_CMD_STATE_DEFAULT; struct scst_user_cmd *ucmd; @@ -684,15 +684,15 @@ switch(dev->parse_type) { case SCST_USER_PARSE_STANDARD: TRACE_DBG("PARSE STANDARD: ucmd %p", ucmd); - rc = dev->generic_parse(cmd, info_cdb, dev_user_get_block); - if ((rc != 0) || (info_cdb->flags & SCST_INFO_INVALID)) + rc = dev->generic_parse(cmd, dev_user_get_block); + if ((rc != 0) || (cmd->op_flags & SCST_INFO_INVALID)) goto out_invalid; break; case SCST_USER_PARSE_EXCEPTION: TRACE_DBG("PARSE EXCEPTION: ucmd %p", ucmd); - rc = dev->generic_parse(cmd, info_cdb, dev_user_get_block); - if ((rc == 0) && (!(info_cdb->flags & SCST_INFO_INVALID))) + rc = dev->generic_parse(cmd, dev_user_get_block); + if ((rc == 0) && (!(cmd->op_flags & SCST_INFO_INVALID))) break; else if (rc == SCST_CMD_STATE_NEED_THREAD_CTX) { TRACE_MEM("Restarting PARSE to thread context " @@ -742,7 +742,7 @@ out_invalid: PRINT_ERROR("PARSE failed (ucmd %p, rc %d, invalid %d)", ucmd, rc, - info_cdb->flags & SCST_INFO_INVALID); + cmd->op_flags & SCST_INFO_INVALID); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_opcode)); out_error: @@ -2854,7 +2854,7 @@ return res; } -static int dev_usr_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +static int dev_usr_parse(struct scst_cmd *cmd) { sBUG(); return SCST_CMD_STATE_DEFAULT; Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2007-12-10 12:09:07 UTC (rev 230) @@ -219,9 +219,9 @@ static void vdisk_detach(struct scst_device *dev); static int vdisk_attach_tgt(struct scst_tgt_dev *tgt_dev); static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev); -static int vdisk_parse(struct scst_cmd *, struct scst_info_cdb *info_cdb); +static int vdisk_parse(struct scst_cmd *); static int vdisk_do_job(struct scst_cmd *cmd); -static int vcdrom_parse(struct scst_cmd *, struct scst_info_cdb *info_cdb); +static int vcdrom_parse(struct scst_cmd *); static int vcdrom_exec(struct scst_cmd *cmd); static void vdisk_exec_read(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, loff_t loff); @@ -971,10 +971,9 @@ * * Note: Not all states are allowed on return ********************************************************************/ -static int vdisk_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb) +static int vdisk_parse(struct scst_cmd *cmd) { - scst_sbc_generic_parse(cmd, info_cdb, vdisk_get_block_shift); + scst_sbc_generic_parse(cmd, vdisk_get_block_shift); return SCST_CMD_STATE_DEFAULT; } @@ -989,10 +988,9 @@ * * Note: Not all states are allowed on return ********************************************************************/ -static int vcdrom_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb) +static int vcdrom_parse(struct scst_cmd *cmd) { - scst_cdrom_generic_parse(cmd, info_cdb, vdisk_get_block_shift); + scst_cdrom_generic_parse(cmd, vdisk_get_block_shift); return SCST_CMD_STATE_DEFAULT; } Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/scst_lib.c 2007-12-10 12:09:07 UTC (rev 230) @@ -1681,7 +1681,8 @@ } int scst_get_cdb_info(const uint8_t *cdb_p, int dev_type, - struct scst_info_cdb *info_p) + enum scst_cdb_flags *op_flags, scst_data_direction *direction, + unsigned int *transfer_len, int *cdb_len, const char **op_name) { int i, res = 0; uint8_t op; @@ -1725,24 +1726,23 @@ TRACE(TRACE_SCSI, "Unknown opcode 0x%x for type %d", op, dev_type); res = -1; - memset(info_p, 0, sizeof(*info_p)); - info_p->flags = SCST_INFO_INVALID; + *op_flags = SCST_INFO_INVALID; goto out; } - info_p->cdb_len = SCST_GET_CDB_LEN(op); - info_p->op_name = ptr->op_name; - info_p->direction = ptr->direction; - info_p->flags = ptr->flags; - info_p->transfer_len = (*ptr->get_trans_len)(cdb_p, ptr->off); + *cdb_len = SCST_GET_CDB_LEN(op); + *op_name = ptr->op_name; + *direction = ptr->direction; + *op_flags = ptr->flags; + *transfer_len = (*ptr->get_trans_len)(cdb_p, ptr->off); #ifdef EXTRACHECKS - if (unlikely((info_p->transfer_len == 0) && - (info_p->direction != SCST_DATA_NONE) && - ((info_p->flags & SCST_UNKNOWN_LENGTH) == 0))) { + if (unlikely((*transfer_len == 0) && + (*direction != SCST_DATA_NONE) && + ((*op_flags & SCST_UNKNOWN_LENGTH) == 0))) { PRINT_ERROR("transfer_len 0, direction %d, flags %x, changing " - "direction on NONE", info_p->direction, info_p->flags); - info_p->direction = SCST_DATA_NONE; + "direction on NONE", *direction, *op_flags); + *direction = SCST_DATA_NONE; } #endif @@ -1871,7 +1871,6 @@ } int scst_sbc_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)) { int res = 0; @@ -1879,13 +1878,12 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->data_direction and cmd->bufflen - * based on info_cdb, therefore change them only if necessary + * SCST sets good defaults for cmd->data_direction and cmd->bufflen, + * therefore change them only if necessary */ TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d", - info_cdb->op_name, - info_cdb->direction, info_cdb->flags, info_cdb->transfer_len); + cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen); switch (cmd->cdb[0]) { case SERVICE_ACTION_IN: @@ -1899,11 +1897,10 @@ case VERIFY_12: case VERIFY_16: if ((cmd->cdb[1] & BYTCHK) == 0) { - cmd->data_len = - info_cdb->transfer_len << get_block_shift(cmd); + cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; cmd->data_direction = SCST_DATA_NONE; - info_cdb->flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; } else cmd->data_len = 0; break; @@ -1912,12 +1909,12 @@ break; } - if (info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED) { + if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) { /* * No need for locks here, since *_detach() can not be * called, when there are existing commands. */ - cmd->bufflen = info_cdb->transfer_len << get_block_shift(cmd); + cmd->bufflen = cmd->bufflen << get_block_shift(cmd); } TRACE_DBG("res %d, bufflen %d, data_len %d, direct %d", @@ -1928,7 +1925,6 @@ } int scst_cdrom_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)) { int res = 0; @@ -1936,15 +1932,12 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->data_direction and cmd->bufflen - * based on info_cdb, therefore change them only if necessary + * SCST sets good defaults for cmd->data_direction and cmd->bufflen, + * therefore change them only if necessary */ - TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d lun %Ld(%d)", - info_cdb->op_name, - info_cdb->direction, - info_cdb->flags, - info_cdb->transfer_len, cmd->lun, (cmd->cdb[1] >> 5) & 7); + TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d", + cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen); cmd->cdb[1] &= 0x1f; @@ -1954,11 +1947,10 @@ case VERIFY_12: case VERIFY_16: if ((cmd->cdb[1] & BYTCHK) == 0) { - cmd->data_len = - info_cdb->transfer_len << get_block_shift(cmd); + cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; cmd->data_direction = SCST_DATA_NONE; - info_cdb->flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; } break; default: @@ -1966,8 +1958,8 @@ break; } - if (info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED) - cmd->bufflen = info_cdb->transfer_len << get_block_shift(cmd); + if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) + cmd->bufflen = cmd->bufflen << get_block_shift(cmd); TRACE_DBG("res %d bufflen %d direct %d", res, cmd->bufflen, cmd->data_direction); @@ -1977,7 +1969,6 @@ } int scst_modisk_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_shift)(struct scst_cmd *cmd)) { int res = 0; @@ -1985,15 +1976,12 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->data_direction and cmd->bufflen - * based on info_cdb, therefore change them only if necessary + * SCST sets good defaults for cmd->data_direction and cmd->bufflen, + * therefore change them only if necessary */ - TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d lun %Ld(%d)", - info_cdb->op_name, - info_cdb->direction, - info_cdb->flags, - info_cdb->transfer_len, cmd->lun, (cmd->cdb[1] >> 5) & 7); + TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d", + cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen); cmd->cdb[1] &= 0x1f; @@ -2003,11 +1991,10 @@ case VERIFY_12: case VERIFY_16: if ((cmd->cdb[1] & BYTCHK) == 0) { - cmd->data_len = - info_cdb->transfer_len << get_block_shift(cmd); + cmd->data_len = cmd->bufflen << get_block_shift(cmd); cmd->bufflen = 0; cmd->data_direction = SCST_DATA_NONE; - info_cdb->flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; + cmd->op_flags &= ~SCST_TRANSFER_LEN_TYPE_FIXED; } break; default: @@ -2015,8 +2002,8 @@ break; } - if (info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED) - cmd->bufflen = info_cdb->transfer_len << get_block_shift(cmd); + if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED) + cmd->bufflen = cmd->bufflen << get_block_shift(cmd); TRACE_DBG("res %d bufflen %d direct %d", res, cmd->bufflen, cmd->data_direction); @@ -2026,7 +2013,6 @@ } int scst_tape_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*get_block_size)(struct scst_cmd *cmd)) { int res = 0; @@ -2034,13 +2020,12 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->data_direction and cmd->bufflen - * based on info_cdb, therefore change them only if necessary + * SCST sets good defaults for cmd->data_direction and cmd->bufflen, + * therefore change them only if necessary */ TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d", - info_cdb->op_name, - info_cdb->direction, info_cdb->flags, info_cdb->transfer_len); + cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen); if (cmd->cdb[0] == READ_POSITION) { int tclp = cmd->cdb[1] & TCLP_BIT; @@ -2057,27 +2042,26 @@ } } - if (info_cdb->flags & SCST_TRANSFER_LEN_TYPE_FIXED & cmd->cdb[1]) - cmd->bufflen = info_cdb->transfer_len * get_block_size(cmd); + if (cmd->op_flags & SCST_TRANSFER_LEN_TYPE_FIXED & cmd->cdb[1]) + cmd->bufflen = cmd->bufflen * get_block_size(cmd); TRACE_EXIT_RES(res); return res; } -static int scst_null_parse(struct scst_cmd *cmd, struct scst_info_cdb *info_cdb) +static int scst_null_parse(struct scst_cmd *cmd) { int res = 0; TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->data_direction and cmd->bufflen - * based on info_cdb, therefore change them only if necessary + * SCST sets good defaults for cmd->data_direction and cmd->bufflen, + * therefore change them only if necessary */ TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d", - info_cdb->op_name, - info_cdb->direction, info_cdb->flags, info_cdb->transfer_len); + cmd->op_name, cmd->data_direction, cmd->op_flags, cmd->bufflen); #if 0 switch (cmd->cdb[0]) { default: @@ -2093,24 +2077,21 @@ } int scst_changer_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)) { - return scst_null_parse(cmd, info_cdb); + return scst_null_parse(cmd); } int scst_processor_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)) { - return scst_null_parse(cmd, info_cdb); + return scst_null_parse(cmd); } int scst_raid_generic_parse(struct scst_cmd *cmd, - struct scst_info_cdb *info_cdb, int (*nothing)(struct scst_cmd *cmd)) { - return scst_null_parse(cmd, info_cdb); + return scst_null_parse(cmd); } int scst_block_generic_dev_done(struct scst_cmd *cmd, @@ -3020,7 +3001,12 @@ if (cmd->dev->tas) { scst_set_cmd_error_status(cmd, SAM_STAT_TASK_ABORTED); } else { - /* Abort without delivery or notification */ + /* + * Abort without delivery or notification. + * There is no need to check/requeue possible UA, + * because, if it exists, it will be delivered + * by the "completed" branch. + */ clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); } Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/scst_main.c 2007-12-10 12:09:07 UTC (rev 230) @@ -135,7 +135,7 @@ module_param_named(scst_max_cmd_mem, scst_max_cmd_mem, long, 0); MODULE_PARM_DESC(scst_max_cmd_mem, "Maximum memory allowed to be consumed by " - "the SCST commands at any given time in Mb"); + "the SCST commands at any given time in MB"); struct scst_dev_type scst_null_devtype = { @@ -1768,7 +1768,7 @@ module_init(init_scst); module_exit(exit_scst); -MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar"); +MODULE_AUTHOR("Vladislav Bolkhovitin"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SCSI target core"); MODULE_VERSION(SCST_VERSION_STRING); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/scst/src/scst_targ.c 2007-12-10 12:09:07 UTC (rev 230) @@ -284,7 +284,6 @@ { int res = SCST_CMD_STATE_RES_CONT_SAME; struct scst_device *dev = cmd->dev; - struct scst_info_cdb cdb_info; TRACE_ENTRY(); @@ -300,7 +299,8 @@ */ if (unlikely(scst_get_cdb_info(cmd->cdb, dev->handler->type, - &cdb_info) != 0)) { + &cmd->op_flags, &cmd->data_direction, + &cmd->bufflen, &cmd->cdb_len, &cmd->op_name) != 0)) { PRINT_ERROR("Unknown opcode 0x%02x for %s. " "Should you update scst_scsi_op_table?", cmd->cdb[0], dev->handler->name); @@ -339,15 +339,12 @@ } else { TRACE(TRACE_SCSI, "op_name <%s>, direction=%d (expected %d, " "set %s), transfer_len=%d (expected len %d), flags=%d", - cdb_info.op_name, cdb_info.direction, + cmd->op_name, cmd->data_direction, cmd->expected_data_direction, scst_cmd_is_expected_set(cmd) ? "yes" : "no", - cdb_info.transfer_len, cmd->expected_transfer_len, - cdb_info.flags); + cmd->bufflen, cmd->expected_transfer_len, cmd->op_flags); - cmd->data_direction = cdb_info.direction; - - if (unlikely((cdb_info.flags & SCST_UNKNOWN_LENGTH) != 0)) { + if (unlikely((cmd->op_flags & SCST_UNKNOWN_LENGTH) != 0)) { if (scst_cmd_is_expected_set(cmd)) { /* * Command data length can't be easily @@ -360,11 +357,7 @@ 15*1024*1024); } else cmd->bufflen = 0; - } else - cmd->bufflen = cdb_info.transfer_len; - - /* Restore (likely) lost CDB length */ - cmd->cdb_len = cdb_info.cdb_len; + } } if (unlikely(cmd->cdb[cmd->cdb_len - 1] & CONTROL_BYTE_NACA_BIT)) { @@ -400,9 +393,9 @@ int res = SCST_CMD_STATE_RES_CONT_SAME; int state; struct scst_device *dev = cmd->dev; - struct scst_info_cdb cdb_info; int atomic = scst_cmd_atomic(cmd); - int orig_bufflen; + int orig_bufflen = cmd->bufflen; + scst_data_direction orig_data_direction = cmd->data_direction; TRACE_ENTRY(); @@ -414,13 +407,11 @@ goto out; } - orig_bufflen = cmd->bufflen; - if (likely(!scst_is_cmd_local(cmd))) { TRACE_DBG("Calling dev handler %s parse(%p)", dev->handler->name, cmd); TRACE_BUFF_FLAG(TRACE_SEND_BOT, "Parsing: ", cmd->cdb, cmd->cdb_len); - state = dev->handler->parse(cmd, &cdb_info); + state = dev->handler->parse(cmd); /* Caution: cmd can be already dead here */ TRACE_DBG("Dev handler %s parse() returned %d", dev->handler->name, state); @@ -485,12 +476,12 @@ cmd->data_direction = cmd->expected_data_direction; cmd->bufflen = cmd->expected_transfer_len; #else - if (unlikely(cmd->data_direction != cdb_info.direction)) { + if (unlikely(cmd->data_direction != orig_data_direction)) { PRINT_ERROR("Expected data direction %d for opcode " "0x%02x (handler %s, target %s) doesn't match " "decoded value %d", cmd->data_direction, cmd->cdb[0], dev->handler->name, - cmd->tgtt->name, cdb_info.direction); + cmd->tgtt->name, orig_data_direction); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_message)); goto out_dev_done; Modified: trunk/usr/fileio/fileio.c =================================================================== --- trunk/usr/fileio/fileio.c 2007-12-10 11:53:05 UTC (rev 229) +++ trunk/usr/fileio/fileio.c 2007-12-10 12:09:07 UTC (rev 230) @@ -53,7 +53,7 @@ #else /* DEBUG */ # ifdef TRACING -#define DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_MGMT \ +#define DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_MGMT | \ TRACE_TIME | TRACE_SPECIAL) # else #define DEFAULT_LOG_FLAGS 0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-13 18:28:38
|
Revision: 233 http://scst.svn.sourceforge.net/scst/?rev=233&view=rev Author: vlnb Date: 2007-12-13 10:28:34 -0800 (Thu, 13 Dec 2007) Log Message: ----------- - Implement SN based iSCSI IO flow control - ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING compilation symbol added - TM fixes and cleanups - Fixes crash on modprobe with some real devices Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/config.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/usr/ctldev.c trunk/iscsi-scst/usr/iscsi_scstd.c trunk/iscsi-scst/usr/iscsid.c trunk/iscsi-scst/usr/iscsid.h trunk/iscsi-scst/usr/session.c trunk/qla2x00t/qla2x00-target/ChangeLog trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/src/Makefile trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/README 2007-12-13 18:28:34 UTC (rev 233) @@ -103,6 +103,14 @@ "Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz", and add there all necessary LUNs. Check SCST README file for details. +If under high load you experience I/O stalls or see in the kernel log +abort or reset messages then try to reduce QueuedCommands parameter in +iscsi-scstd.conf file for the corresponding target. Particularly, it is +known that the default value 32 sometimes too high if you do intensive +writes from VMware on a target disk, which use LVM in the snapshot mode. +In this case value like 16 or even 10 depending of your backstorage +speed could be more appropriate. + Compilation options ------------------- Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/include/iscsi_u.h 2007-12-13 18:28:34 UTC (rev 233) @@ -45,7 +45,6 @@ char initiator_name[ISCSI_NAME_LEN]; char user_name[ISCSI_NAME_LEN]; u32 exp_cmd_sn; - u32 max_cmd_sn; }; #define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C) Modified: trunk/iscsi-scst/kernel/config.c =================================================================== --- trunk/iscsi-scst/kernel/config.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/kernel/config.c 2007-12-13 18:28:34 UTC (rev 233) @@ -301,7 +301,6 @@ return -ENOENT; info.exp_cmd_sn = session->exp_cmd_sn; - info.max_cmd_sn = session->max_cmd_sn; if (copy_to_user((void *) ptr, &info, sizeof(info))) return -EFAULT; Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-13 18:28:34 UTC (rev 233) @@ -62,6 +62,7 @@ static void cmnd_remove_hash(struct iscsi_cmnd *cmnd); static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status); static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd); +static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force); static inline u32 cmnd_write_size(struct iscsi_cmnd *cmnd) { @@ -115,6 +116,7 @@ if (parent == NULL) { conn_get(conn); + #ifdef NET_PAGE_CALLBACKS_DEFINED atomic_set(&cmnd->net_ref_cnt, 0); #endif @@ -229,6 +231,14 @@ #endif } + if (cmnd->dec_active_cmnds) { + struct iscsi_session *sess = cmnd->conn->session; + TRACE_DBG("Decrementing active_cmds (cmd %p, sess %p, " + "new value %d)", cmnd, sess, + atomic_read(&sess->active_cmds)-1); + atomic_dec(&sess->active_cmds); + } + cmnd_free(cmnd); return; } @@ -333,6 +343,15 @@ if (req->hashed) cmnd_remove_hash(req); + if (req->dec_active_cmnds) { + struct iscsi_session *sess = req->conn->session; + TRACE_DBG("Decrementing active_cmds (cmd %p, sess %p, " + "new value %d)", req, sess, + atomic_read(&sess->active_cmds)-1); + atomic_dec(&sess->active_cmds); + req->dec_active_cmnds = 0; + } + cmnd_put(req); TRACE_EXIT(); @@ -629,6 +648,15 @@ req->pdu.bhs.opcode = ISCSI_OP_PDU_REJECT; } +static inline int iscsi_get_allowed_cmds(struct iscsi_session *sess) +{ + int res = max(-1, (int)sess->max_queued_cmnds - + atomic_read(&sess->active_cmds)-1); + TRACE_DBG("allowed cmds %d (sess %p, active_cmds %d)", res, + sess, atomic_read(&sess->active_cmds)); + return res; +} + static u32 cmnd_set_sn(struct iscsi_cmnd *cmnd, int set_stat_sn) { struct iscsi_conn *conn = cmnd->conn; @@ -640,7 +668,8 @@ 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); + cmnd->pdu.bhs.max_sn = cpu_to_be32(sess->exp_cmd_sn + + iscsi_get_allowed_cmds(sess)); res = cpu_to_be32(conn->stat_sn); @@ -738,6 +767,7 @@ TRACE_DBG("%p:%x", cmnd, itt); if (itt == ISCSI_RESERVED_TAG) { + PRINT_ERROR("%s", "ITT is RESERVED_TAG"); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; } @@ -1143,6 +1173,12 @@ TRACE_DBG("scsi command: %02x", req_hdr->scb[0]); + TRACE_DBG("Incrementing active_cmds (cmd %p, sess %p, " + "new value %d)", req, session, + atomic_read(&session->active_cmds)+1); + atomic_inc(&session->active_cmds); + req->dec_active_cmnds = 1; + scst_cmd = scst_rx_cmd(session->scst_sess, (uint8_t*)&req_hdr->lun, sizeof(req_hdr->lun), req_hdr->scb, sizeof(req_hdr->scb), SCST_NON_ATOMIC); @@ -1591,7 +1627,14 @@ memset(¶ms, 0, sizeof(params)); params.atomic = SCST_NON_ATOMIC; params.tgt_priv = req; - + + if (conn->session->tm_rsp != NULL) { + struct iscsi_task_rsp_hdr *rsp_hdr = + (struct iscsi_task_rsp_hdr *)&conn->session->tm_rsp->pdu.bhs; + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED; + iscsi_cond_send_tm_resp(conn->session->tm_rsp, 1); + } + if ((function != ISCSI_FUNCTION_ABORT_TASK) && (req_hdr->rtt != ISCSI_RESERVED_TAG)) { PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, @@ -1944,6 +1987,9 @@ spin_unlock(&session->sn_lock); + if (unlikely(session->tm_rsp != NULL)) + iscsi_cond_send_tm_resp(session->tm_rsp, 0); + iscsi_cmnd_exec(cmnd); if (list_empty(&session->pending_list)) @@ -1964,9 +2010,10 @@ session->exp_cmd_sn); } - if (after(cmd_sn, session->exp_cmd_sn + session->max_queued_cmnds)) { - PRINT_ERROR("too large cmd_sn (%u,%u)", cmd_sn, - session->exp_cmd_sn); + if (after(cmd_sn, session->exp_cmd_sn + iscsi_get_allowed_cmds(session))) { + PRINT_ERROR("too large cmd_sn %u (exp_cmd_sn %u, " + "max_sn %u)", cmd_sn, session->exp_cmd_sn, + iscsi_get_allowed_cmds(session)); } spin_unlock(&session->sn_lock); @@ -2061,14 +2108,8 @@ void cmnd_rx_end(struct iscsi_cmnd *cmnd) { - if (unlikely(cmnd->tmfabort)) { - TRACE_MGMT_DBG("cmnd %p (scst_cmd %p) aborted", cmnd, - cmnd->scst_cmd); - req_cmnd_release_force(cmnd, ISCSI_FORCE_RELEASE_WRITE); - return; - } + TRACE_DBG("%p:%x", cmnd, cmnd_opcode(cmnd)); - TRACE_DBG("%p:%x", cmnd, cmnd_opcode(cmnd)); switch (cmnd_opcode(cmnd)) { case ISCSI_OP_SCSI_REJECT: case ISCSI_OP_NOOP_OUT: @@ -2093,6 +2134,7 @@ req_cmnd_release(cmnd); break; } + return; } #ifndef NET_PAGE_CALLBACKS_DEFINED @@ -2313,6 +2355,50 @@ return SCST_TGT_RES_SUCCESS; } +static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force) +{ + struct iscsi_task_mgt_hdr *req_hdr = + (struct iscsi_task_mgt_hdr *)&rsp->parent_req->pdu.bhs; + int function = req_hdr->function & ISCSI_FUNCTION_MASK; + struct iscsi_session *sess = rsp->conn->session; + + TRACE_ENTRY(); + + if (!force) { + spin_lock(&sess->sn_lock); + switch(function) { + case ISCSI_FUNCTION_ABORT_TASK_SET: + case ISCSI_FUNCTION_CLEAR_TASK_SET: + case ISCSI_FUNCTION_CLEAR_ACA: + if (after(req_hdr->cmd_sn, sess->exp_cmd_sn)) { + TRACE_MGMT_DBG("Delaying TM fn %x response, " + "because not all affected commands " + "received (rsp %p, cmd sn %x, exp sn " + "%x)", function, rsp, req_hdr->cmd_sn, + sess->exp_cmd_sn); + sess->tm_rsp = rsp; + spin_unlock(&sess->sn_lock); + goto out; + } + break; + default: + break; + } + spin_unlock(&sess->sn_lock); + } + + if (rsp == sess->tm_rsp) { + TRACE_MGMT_DBG("Sending delayed rsp %p (fn %x)", rsp, function); + sess->tm_rsp = NULL; + } + iscsi_cmnd_init_write(rsp, + ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + +out: + TRACE_EXIT(); + return; +} + static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status) { struct iscsi_cmnd *rsp; @@ -2320,6 +2406,8 @@ (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; + TRACE_ENTRY(); + TRACE((req_hdr->function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, "TM req %p finished, status %d", req, status); @@ -2336,9 +2424,12 @@ ISCSI_FUNCTION_TARGET_COLD_RESET) rsp->should_close_conn = 1; - iscsi_cmnd_init_write(rsp, - ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + iscsi_cond_send_tm_resp(rsp, 0); + req_cmnd_release(req); + + TRACE_EXIT(); + return; } static inline int iscsi_get_mgmt_response(int status) Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/kernel/iscsi.h 2007-12-13 18:28:34 UTC (rev 233) @@ -92,13 +92,14 @@ struct list_head pending_list; u32 next_ttt; - /* Both unprotected, since read-only */ - u32 max_queued_cmnds; - u32 max_cmd_sn; /* Not used ??, ToDo */ + u32 max_queued_cmnds; /* unprotected, since read-only */ + atomic_t active_cmds; spinlock_t sn_lock; u32 exp_cmd_sn; /* protected by sn_lock */ + struct iscsi_cmnd *tm_rsp; + /* read only, if there are connection(s) */ struct iscsi_sess_param sess_param; @@ -238,6 +239,7 @@ unsigned int write_processing_started:1; unsigned int data_waiting:1; unsigned int force_cleanup_done:1; + unsigned int dec_active_cmnds:1; #ifdef EXTRACHECKS unsigned int release_called:1; #endif Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/kernel/session.c 2007-12-13 18:28:34 UTC (rev 233) @@ -48,9 +48,9 @@ memcpy(&session->sess_param, &target->trgt_sess_param, sizeof(session->sess_param)); session->max_queued_cmnds = target->trgt_param.queued_cmnds; + atomic_set(&session->active_cmds, 0); session->exp_cmd_sn = info->exp_cmd_sn; - session->max_cmd_sn = info->max_cmd_sn; session->initiator_name = kstrdup(info->initiator_name, GFP_KERNEL); if (!session->initiator_name) { @@ -127,6 +127,11 @@ (unsigned long long)session->sid); sBUG_ON(!list_empty(&session->conn_list)); + if (unlikely(atomic_read(&session->active_cmds) != 0)) { + PRINT_ERROR("active_cmds not 0 (%d)!!", + atomic_read(&session->active_cmds)); + sBUG(); + } for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) sBUG_ON(!list_empty(&session->cmnd_hash[i])); Modified: trunk/iscsi-scst/usr/ctldev.c =================================================================== --- trunk/iscsi-scst/usr/ctldev.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/usr/ctldev.c 2007-12-13 18:28:34 UTC (rev 233) @@ -377,7 +377,7 @@ } static int iscsi_session_create(u32 tid, u64 sid, u32 exp_cmd_sn, - u32 max_cmd_sn, char *name, char *user) + char *name, char *user) { struct session_info info; @@ -386,7 +386,6 @@ info.tid = tid; info.sid = sid; info.exp_cmd_sn = exp_cmd_sn; - info.max_cmd_sn = max_cmd_sn; strncpy(info.initiator_name, name, sizeof(info.initiator_name) - 1); strncpy(info.user_name, user, sizeof(info.user_name) - 1); Modified: trunk/iscsi-scst/usr/iscsi_scstd.c =================================================================== --- trunk/iscsi-scst/usr/iscsi_scstd.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/usr/iscsi_scstd.c 2007-12-13 18:28:34 UTC (rev 233) @@ -224,11 +224,11 @@ if (from.ss_family == AF_INET) { struct sockaddr_in *in = (struct sockaddr_in *)&from; - log_info("Connect from %s:%hd", inet_ntoa(in->sin_addr), + log_info("Connect from %s:%hu", inet_ntoa(in->sin_addr), ntohs(in->sin_port)); } else if (from.ss_family == AF_INET6) { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&from; - log_info("Connect from %x:%x:%x:%x:%x:%x:%x:%x.%hd", + log_info("Connect from %x:%x:%x:%x:%x:%x:%x:%x.%hu", in6->sin6_addr.s6_addr16[7], in6->sin6_addr.s6_addr16[6], in6->sin6_addr.s6_addr16[5], in6->sin6_addr.s6_addr16[4], in6->sin6_addr.s6_addr16[3], in6->sin6_addr.s6_addr16[2], Modified: trunk/iscsi-scst/usr/iscsid.c =================================================================== --- trunk/iscsi-scst/usr/iscsid.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/usr/iscsid.c 2007-12-13 18:28:34 UTC (rev 233) @@ -582,8 +582,7 @@ rsp->sid = conn->sid; rsp->stat_sn = cpu_to_be32(conn->stat_sn++); rsp->exp_cmd_sn = cpu_to_be32(conn->exp_cmd_sn); - conn->max_cmd_sn = conn->exp_cmd_sn + 1; - rsp->max_cmd_sn = cpu_to_be32(conn->max_cmd_sn); + rsp->max_cmd_sn = cpu_to_be32(conn->exp_cmd_sn + 1); return; init_err: rsp->flags = 0; @@ -690,8 +689,7 @@ rsp->stat_sn = cpu_to_be32(conn->stat_sn++); rsp->exp_cmd_sn = cpu_to_be32(conn->exp_cmd_sn); - conn->max_cmd_sn = conn->exp_cmd_sn + 1; - rsp->max_cmd_sn = cpu_to_be32(conn->max_cmd_sn); + rsp->max_cmd_sn = cpu_to_be32(conn->exp_cmd_sn + 1); } static void cmnd_exec_logout(struct connection *conn) @@ -709,8 +707,7 @@ rsp->stat_sn = cpu_to_be32(conn->stat_sn++); rsp->exp_cmd_sn = cpu_to_be32(conn->exp_cmd_sn); - conn->max_cmd_sn = conn->exp_cmd_sn + 1; - rsp->max_cmd_sn = cpu_to_be32(conn->max_cmd_sn); + rsp->max_cmd_sn = cpu_to_be32(conn->exp_cmd_sn + 1); } int cmnd_execute(struct connection *conn) Modified: trunk/iscsi-scst/usr/iscsid.h =================================================================== --- trunk/iscsi-scst/usr/iscsid.h 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/usr/iscsid.h 2007-12-13 18:28:34 UTC (rev 233) @@ -74,7 +74,6 @@ u32 cmd_sn; u32 exp_cmd_sn; - u32 max_cmd_sn; struct PDU req; void *req_buffer; @@ -216,7 +215,7 @@ int (*param_set) (u32, u64, int, u32, struct iscsi_param *, int); int (*target_create) (u32 *, char *); int (*target_destroy) (u32); - int (*session_create) (u32, u64, u32, u32, char *, char *); + int (*session_create) (u32, u64, u32, char *, char *); int (*session_destroy) (u32, u64); int (*conn_create) (u32, u64, u32, u32, u32, int, u32, u32); int (*conn_destroy) (u32 tid, u64 sid, u32 cid); Modified: trunk/iscsi-scst/usr/session.c =================================================================== --- trunk/iscsi-scst/usr/session.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/iscsi-scst/usr/session.c 2007-12-13 18:28:34 UTC (rev 233) @@ -161,7 +161,7 @@ user = ""; ki->session_create(conn->tid, session->sid.id64, conn->exp_cmd_sn, - conn->max_cmd_sn, session->initiator, user); + session->initiator, user); ki->param_set(conn->tid, session->sid.id64, key_session, 0, conn->session_param, 0); } Modified: trunk/qla2x00t/qla2x00-target/ChangeLog =================================================================== --- trunk/qla2x00t/qla2x00-target/ChangeLog 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/qla2x00t/qla2x00-target/ChangeLog 2007-12-13 18:28:34 UTC (rev 233) @@ -3,7 +3,7 @@ - Support for per-target default security groups added. - - Updateed to work on 2.6.22.x kernels. + - Updated to work on 2.6.22.x kernels. - Updated to work with SCST 0.9.6. Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/README 2007-12-13 18:28:34 UTC (rev 233) @@ -245,6 +245,17 @@ and eases CPU load, but could create a security hole (information leakage), so enable it, if you have strict security requirements. + - ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING - if defined, in case + when TASK MANAGEMENT function ABORT TASK is trying to abort a + command, which has already finished, remote initiator, which sent the + ABORT TASK request, will receive TASK NOT EXIST (or ABORT FAILED) + response for the ABORT TASK request. This is more logical response, + since, because the command finished, attempt to abort it failed, but + some initiators, particularly VMware iSCSI initiator, consider TASK + NOT EXIST response as if the target got crazy and try to RESET it. + Then sometimes get crazy itself. So, this option is disabled by + default. + HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons, except for scst_user, where they are not supported, because this module deals with user supplied memory on a Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/include/scsi_tgt.h 2007-12-13 18:28:34 UTC (rev 233) @@ -2504,4 +2504,10 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd, void (*set_block_size)(struct scst_cmd *cmd, int block_size)); +/* + * Issues a MODE SENSE for control mode page data and sets the corresponding + * dev's parameter from it. Returns 0 on success and not 0 otherwise. + */ +int scst_obtain_device_parameters(struct scst_device *dev); + #endif /* __SCST_H */ Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/Makefile 2007-12-13 18:28:34 UTC (rev 233) @@ -118,6 +118,7 @@ #EXTRA_CFLAGS += -DUSE_EXPECTED_VALUES #EXTRA_CFLAGS += -DALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ +#EXTRA_CFLAGS += -DABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING #EXTRA_CFLAGS += -fno-inline Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2007-12-13 18:28:34 UTC (rev 233) @@ -147,6 +147,10 @@ goto out_free_buf; } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out_free_buf; + out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_changer.c 2007-12-13 18:28:34 UTC (rev 233) @@ -90,9 +90,15 @@ CHANGER_RETRIES); TRACE_DBG("TEST_UNIT_READY done: %x", res); } while ((--retries > 0) && res); - if (res) + if (res) { res = -ENODEV; + goto out; + } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out; + out: TRACE_EXIT_HRES(res); return res; Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_disk.c 2007-12-13 18:28:34 UTC (rev 233) @@ -219,6 +219,10 @@ goto out_free_buf; } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out_free_buf; + out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2007-12-13 18:28:34 UTC (rev 233) @@ -234,6 +234,10 @@ goto out_free_buf; } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out_free_buf; + out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_processor.c 2007-12-13 18:28:34 UTC (rev 233) @@ -90,9 +90,15 @@ PROCESSOR_RETRIES); TRACE_DBG("TEST_UNIT_READY done: %x", res); } while ((--retries > 0) && res); - if (res) + if (res) { res = -ENODEV; + goto out; + } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out; + out: TRACE_EXIT(); return res; Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_raid.c 2007-12-13 18:28:34 UTC (rev 233) @@ -90,9 +90,15 @@ RAID_RETRIES); TRACE_DBG("TEST_UNIT_READY done: %x", res); } while ((--retries > 0) && res); - if (res) + if (res) { res = -ENODEV; + goto out; + } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out; + out: TRACE_EXIT(); return res; Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/dev_handlers/scst_tape.c 2007-12-13 18:28:34 UTC (rev 233) @@ -222,6 +222,10 @@ goto out_free_buf; } + res = scst_obtain_device_parameters(dev); + if (res != 0) + goto out_free_buf; + out_free_buf: kfree(buffer); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/scst_lib.c 2007-12-13 18:28:34 UTC (rev 233) @@ -38,7 +38,7 @@ #include "scst_cdbprobe.h" static void scst_free_tgt_dev(struct scst_tgt_dev *tgt_dev); -int scst_check_internal_sense(struct scst_device *dev, int result, +static void scst_check_internal_sense(struct scst_device *dev, int result, uint8_t *sense, int sense_len); void scst_set_cmd_error_status(struct scst_cmd *cmd, int status) @@ -189,6 +189,7 @@ init_waitqueue_head(&dev->on_dev_waitQ); dev->dev_double_ua_possible = 1; dev->dev_serialized = 1; + dev->queue_alg = SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER; dev->dev_num = dev_num++; *out_dev = dev; @@ -1048,9 +1049,8 @@ PRINT_ERROR("RELEASE failed: %d", rc); TRACE_BUFFER("RELEASE sense", sense, SCST_SENSE_BUFFERSIZE); - if (scst_check_internal_sense(tgt_dev->dev, rc, - sense, SCST_SENSE_BUFFERSIZE) != 0) - break; + scst_check_internal_sense(tgt_dev->dev, rc, + sense, SCST_SENSE_BUFFERSIZE); } } @@ -2214,20 +2214,23 @@ return res; } -int scst_check_internal_sense(struct scst_device *dev, int result, +static void scst_check_internal_sense(struct scst_device *dev, int result, uint8_t *sense, int sense_len) { TRACE_ENTRY(); if (host_byte(result) == DID_RESET) { + TRACE(TRACE_MGMT_MINOR, "%s", "DID_RESET received, triggering " + "reset UA"); scst_set_sense(sense, sense_len, SCST_LOAD_SENSE(scst_sense_reset_UA)); scst_dev_check_set_UA(dev, NULL, sense, sense_len); - } else if (SCST_SENSE_VALID(sense) && scst_is_ua_sense(sense)) + } else if ((status_byte(result) == CHECK_CONDITION) && + SCST_SENSE_VALID(sense) && scst_is_ua_sense(sense)) scst_dev_check_set_UA(dev, NULL, sense, sense_len); TRACE_EXIT(); - return 0; + return; } int scst_obtain_device_parameters(struct scst_device *dev) @@ -2294,12 +2297,20 @@ goto out; } else { - PRINT_ERROR("Internal MODE_SENSE failed: %d", res); - TRACE_BUFFER("MODE_SENSE sense", sense_buffer, - sizeof(sense_buffer)); - if (scst_check_internal_sense(dev, res, sense_buffer, - sizeof(sense_buffer)) != 0) - break; + TRACE(TRACE_MGMT_MINOR, "Internal MODE SENSE to device " + "%d:%d:%d:%d failed: %x", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, res); + TRACE_BUFF_FLAG(TRACE_MGMT_MINOR, "MODE SENSE sense", + sense_buffer, sizeof(sense_buffer)); + if ((status_byte(res) == CHECK_CONDITION) && + SCST_SENSE_VALID(sense_buffer) && + (sense_buffer[2] == ILLEGAL_REQUEST)) { + res = 0; + goto out; + } + scst_check_internal_sense(dev, res, sense_buffer, + sizeof(sense_buffer)); } } res = -ENODEV; Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/scst_main.c 2007-12-13 18:28:34 UTC (rev 233) @@ -510,10 +510,6 @@ list_add_tail(&dev->dev_list_entry, &scst_dev_list); - res = scst_obtain_device_parameters(dev); - if (res != 0) - goto out_free; - list_for_each_entry(dt, &scst_dev_type_list, dev_type_list_entry) { if (dt->type == scsidp->type) { res = scst_assign_dev_handler(dev, dt); @@ -1760,6 +1756,7 @@ EXPORT_SYMBOL(scst_get_cdb_info); EXPORT_SYMBOL(scst_cmd_get_tgt_priv_lock); EXPORT_SYMBOL(scst_cmd_set_tgt_priv_lock); +EXPORT_SYMBOL(scst_obtain_device_parameters); #ifdef DEBUG EXPORT_SYMBOL(scst_random); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/scst_priv.h 2007-12-13 18:28:34 UTC (rev 233) @@ -354,8 +354,6 @@ int scst_get_cdb_len(const uint8_t *cdb); -int scst_obtain_device_parameters(struct scst_device *dev); - void __scst_dev_check_set_UA(struct scst_device *dev, struct scst_cmd *exclude, const uint8_t *sense, int sense_len); static inline void scst_dev_check_set_UA(struct scst_device *dev, Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-12 16:06:47 UTC (rev 232) +++ trunk/scst/src/scst_targ.c 2007-12-13 18:28:34 UTC (rev 233) @@ -3225,7 +3225,9 @@ static inline int scst_is_strict_mgmt_fn(int mgmt_fn) { switch(mgmt_fn) { +#ifdef ABORT_CONSIDER_FINISHED_TASKS_AS_NOT_EXISTING case SCST_ABORT_TASK: +#endif #if 0 case SCST_ABORT_TASK_SET: case SCST_CLEAR_TASK_SET: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-21 19:10:45
|
Revision: 237 http://scst.svn.sourceforge.net/scst/?rev=237&view=rev Author: vlnb Date: 2007-12-21 11:10:40 -0800 (Fri, 21 Dec 2007) Log Message: ----------- - Update to the latest IET r145 - TM fixes and improvements, particularly, TARGET RESET now resets only visible to the initiator devices - Logs improvements Modified Paths: -------------- trunk/doc/scst_user_spec.txt trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/usr/iscsid.c trunk/scst/include/scst_user.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/doc/scst_user_spec.txt =================================================================== --- trunk/doc/scst_user_spec.txt 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/doc/scst_user_spec.txt 2007-12-21 19:10:40 UTC (rev 237) @@ -2,7 +2,7 @@ USER SPACE INTERFACE DESCRIPTION. - Version 0.9.6/2 + Version 0.9.6/3 I. Description. @@ -335,6 +335,8 @@ uint8_t expected_values_set; uint8_t expected_data_direction; int32_t expected_transfer_len; + + uint32_t sn; }, where: @@ -362,6 +364,8 @@ - expected_transfer_len - remote initiator supplied transfer length + - sn - command's SN, which might be used for task management + In the PARSE state of SCSI commands processing the user space device handler shall check and provide SCST values for command data buffer length, data flow direction and timeout, which it shall reply using the @@ -401,6 +405,8 @@ uint8_t queue_type; uint8_t data_direction; + + uint32_t sn; }, where: @@ -418,6 +424,8 @@ - data_direction - command's data flow direction, one of SCST_DATA_* constants + - sn - command's SN, which might be used for task management + Memory allocation, preparation and freeing are ones of the most complicated and expensive operations during SCSI commands processing. Module scst_user provides a way to almost completely eliminate those @@ -507,6 +515,8 @@ uint8_t partial; uint32_t timeout; + uint32_t sn; + uint32_t parent_cmd_h; int32_t parent_cmd_data_len; uint32_t partial_offset; @@ -546,6 +556,8 @@ - timeout - CDB execution timeout + - sn - command's SN, which might be used for task management + - parent_cmd_h - has the same unique value for all partial data transfers subcommands of one original (parent) command @@ -641,6 +653,8 @@ uint64_t sess_h; uint32_t fn; uint32_t cmd_h_to_abort; + uint32_t cmd_sn; + uint8_t cmd_sn_set; }, where: @@ -651,6 +665,12 @@ - cmd_h_to_abort - handle of command to abort. Valid only if fn is SCST_ABORT_TASK + + - cmd_sn - if cmd_sn_set is set, contains maximum commands SN, which + this task management function affects. See iSCSI RFC 3720 10.5.1 for + more details. + + - cmd_sn_set - specifies if cmd_sn is valid After TM function is completed, the user space device handler shall reply using "result" field of the corresponding reply command. It isn't Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/include/iscsi_u.h 2007-12-21 19:10:40 UTC (rev 237) @@ -20,7 +20,7 @@ #include <sys/uio.h> #endif -#define ISCSI_VERSION_STRING "0.9.6/0.4.15r137" +#define ISCSI_VERSION_STRING "0.9.6/0.4.15r145" /* The maximum length of 223 bytes in the RFC. */ #define ISCSI_NAME_LEN 256 Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-21 19:10:40 UTC (rev 237) @@ -62,7 +62,7 @@ static void cmnd_remove_hash(struct iscsi_cmnd *cmnd); static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status); static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd); -static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force); +static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess); static inline u32 cmnd_write_size(struct iscsi_cmnd *cmnd) { @@ -780,8 +780,10 @@ if (!tmp) { list_add_tail(&cmnd->hash_list_entry, head); cmnd->hashed = 1; - } else + } else { + PRINT_ERROR("Task %x in progress, cmnd %p", itt, cmnd); err = -ISCSI_REASON_TASK_IN_PROGRESS; + } spin_unlock(&session->cmnd_hash_lock); @@ -965,6 +967,13 @@ u32 length, offset, burst; LIST_HEAD(send); + if (unlikely(req->tmfabort)) { + TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted on R2T", req, + req->scst_cmd); + req_cmnd_release_force(req, ISCSI_FORCE_RELEASE_WRITE); + goto out; + } + /* * There is no race with data_out_start() and __cmnd_abort(), since * all functions called from single read thread @@ -1009,6 +1018,9 @@ iscsi_cmnds_init_write(&send, ISCSI_INIT_WRITE_WAKE); req->data_waiting = 1; + +out: + return; } static int iscsi_pre_exec(struct scst_cmd *scst_cmd) @@ -1333,7 +1345,8 @@ cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); if (!req) { - PRINT_ERROR("Unable to find scsi task %x %x", + /* It might happen if req was aborted and then freed */ + TRACE(TRACE_MGMT_MINOR, "Unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); goto skip_pdu; } @@ -1447,12 +1460,12 @@ goto out; TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " - "ref_cnt %d, itt %x, op %x, r2t_len %x, CDB op %x, " + "ref_cnt %d, itt %x, sn %d, op %x, r2t_len %x, CDB op %x, " "size to write %u, is_unsolicited_data %u, " "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, cmnd->scst_state, atomic_read(&cmnd->ref_cnt), - cmnd_itt(cmnd), cmnd_opcode(cmnd), cmnd->r2t_length, - cmnd_scsicode(cmnd), cmnd_write_size(cmnd), + cmnd_itt(cmnd), cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), + cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->is_unsolicited_data, cmnd->outstanding_r2t); #ifdef NET_PAGE_CALLBACKS_DEFINED @@ -1615,26 +1628,32 @@ static void execute_task_management(struct iscsi_cmnd *req) { struct iscsi_conn *conn = req->conn; + struct iscsi_session *sess = conn->session; struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; int err = 0, function = req_hdr->function & ISCSI_FUNCTION_MASK; struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM cmd: req %p, itt %x, fn %d, rtt %x", req, cmnd_itt(req), - function, req_hdr->rtt); + "TM cmd: req %p, itt %x, fn %d, rtt %x, sn %d", req, cmnd_itt(req), + function, req_hdr->rtt, req_hdr->cmd_sn); + spin_lock(&sess->sn_lock); + sess->tm_active = 1; + sess->tm_sn = req_hdr->cmd_sn; + if (sess->tm_rsp != NULL) { + struct iscsi_cmnd *tm_rsp = sess->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); + sess->tm_rsp = NULL; + spin_unlock(&sess->sn_lock); + rsp_cmnd_release(tm_rsp); + } else + spin_unlock(&sess->sn_lock); + memset(¶ms, 0, sizeof(params)); params.atomic = SCST_NON_ATOMIC; params.tgt_priv = req; - if (conn->session->tm_rsp != NULL) { - struct iscsi_task_rsp_hdr *rsp_hdr = - (struct iscsi_task_rsp_hdr *)&conn->session->tm_rsp->pdu.bhs; - rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED; - iscsi_cond_send_tm_resp(conn->session->tm_rsp, 1); - } - if ((function != ISCSI_FUNCTION_ABORT_TASK) && (req_hdr->rtt != ISCSI_RESERVED_TAG)) { PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, @@ -1697,6 +1716,8 @@ case ISCSI_FUNCTION_TARGET_WARM_RESET: target_abort(req, 1); params.fn = SCST_TARGET_RESET; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; err = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); break; @@ -1706,6 +1727,8 @@ params.lun = (uint8_t *)&req_hdr->lun; params.lun_len = sizeof(req_hdr->lun); params.lun_set = 1; + params.cmd_sn = req_hdr->cmd_sn; + params.cmd_sn_set = 1; err = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); break; @@ -1985,16 +2008,23 @@ while (1) { session->exp_cmd_sn = ++cmd_sn; - spin_unlock(&session->sn_lock); + if (unlikely(session->tm_active)) { + if (before(cmd_sn, session->tm_sn)) { + struct iscsi_conn *conn = cmnd->conn; - if (unlikely(session->tm_rsp != NULL)) { - struct iscsi_conn *conn = cmnd->conn; - spin_lock_bh(&conn->cmd_list_lock); - __cmnd_abort(cmnd); - spin_unlock_bh(&conn->cmd_list_lock); - iscsi_cond_send_tm_resp(session->tm_rsp, 0); + spin_unlock(&session->sn_lock); + + spin_lock_bh(&conn->cmd_list_lock); + __cmnd_abort(cmnd); + spin_unlock_bh(&conn->cmd_list_lock); + + spin_lock(&session->sn_lock); + } + iscsi_check_send_delayed_tm_resp(session); } + spin_unlock(&session->sn_lock); + iscsi_cmnd_exec(cmnd); if (list_empty(&session->pending_list)) @@ -2010,13 +2040,13 @@ } } else { cmnd->pending = 1; - if (before(cmd_sn, session->exp_cmd_sn)) { /* close the conn */ + if (before(cmd_sn, session->exp_cmd_sn)) { PRINT_ERROR("unexpected cmd_sn (%u,%u)", cmd_sn, session->exp_cmd_sn); } if (after(cmd_sn, session->exp_cmd_sn + iscsi_get_allowed_cmds(session))) { - PRINT_ERROR("too large cmd_sn %u (exp_cmd_sn %u, " + PRINT_INFO("Suspicious: too large cmd_sn %u (exp_cmd_sn %u, " "max_sn %u)", cmd_sn, session->exp_cmd_sn, iscsi_get_allowed_cmds(session)); } @@ -2360,45 +2390,53 @@ return SCST_TGT_RES_SUCCESS; } -static void iscsi_cond_send_tm_resp(struct iscsi_cmnd *rsp, int force) +/* Called under sn_lock */ +static bool iscsi_is_delay_tm_resp(struct iscsi_cmnd *rsp) { + bool res = 0; struct iscsi_task_mgt_hdr *req_hdr = - (struct iscsi_task_mgt_hdr *)&rsp->parent_req->pdu.bhs; + (struct iscsi_task_mgt_hdr *)&rsp->parent_req->pdu.bhs; int function = req_hdr->function & ISCSI_FUNCTION_MASK; struct iscsi_session *sess = rsp->conn->session; TRACE_ENTRY(); - if (!force) { - spin_lock(&sess->sn_lock); - switch(function) { - case ISCSI_FUNCTION_ABORT_TASK_SET: - case ISCSI_FUNCTION_CLEAR_TASK_SET: - case ISCSI_FUNCTION_CLEAR_ACA: - if (before(sess->exp_cmd_sn, req_hdr->cmd_sn)) { - TRACE_MGMT_DBG("Delaying TM fn %x response, " - "because not all affected commands " - "received (rsp %p, cmd sn %x, exp sn " - "%x)", function, rsp, req_hdr->cmd_sn, - sess->exp_cmd_sn); - sess->tm_rsp = rsp; - spin_unlock(&sess->sn_lock); - goto out; - } - break; - default: - break; - } - spin_unlock(&sess->sn_lock); + switch(function) { + default: + if (before(sess->exp_cmd_sn, req_hdr->cmd_sn)) + res = 1; + break; } - if (rsp == sess->tm_rsp) { - TRACE_MGMT_DBG("Sending delayed rsp %p (fn %x)", rsp, function); - sess->tm_rsp = NULL; - } - iscsi_cmnd_init_write(rsp, + TRACE_EXIT_RES(res); + return res; +} + +/* Called under sn_lock, but might drop it inside, then reaquire */ +static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess) +{ + struct iscsi_cmnd *tm_rsp = sess->tm_rsp; + + TRACE_ENTRY(); + + if (tm_rsp == NULL) + goto out; + + if (iscsi_is_delay_tm_resp(tm_rsp)) + goto out; + + TRACE(TRACE_MGMT_MINOR, "Sending delayed rsp %p", tm_rsp); + + sess->tm_rsp = NULL; + sess->tm_active = 0; + + spin_unlock(&sess->sn_lock); + + iscsi_cmnd_init_write(tm_rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + spin_lock(&sess->sn_lock); + out: TRACE_EXIT(); return; @@ -2410,6 +2448,7 @@ struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; + struct iscsi_session *sess = req->conn->session; TRACE_ENTRY(); @@ -2429,8 +2468,26 @@ ISCSI_FUNCTION_TARGET_COLD_RESET) rsp->should_close_conn = 1; - iscsi_cond_send_tm_resp(rsp, 0); + sBUG_ON(sess->tm_rsp != NULL); + spin_lock(&sess->sn_lock); + if (iscsi_is_delay_tm_resp(rsp)) { + TRACE(TRACE_MGMT_MINOR, "Delaying TM fn %x response %p " + "(req %p), because not all affected commands received " + "(cmd sn %d, exp sn %d)", + req_hdr->function & ISCSI_FUNCTION_MASK, rsp, req, + req_hdr->cmd_sn, sess->exp_cmd_sn); + sess->tm_rsp = rsp; + spin_unlock(&sess->sn_lock); + goto out_release; + } + sess->tm_active = 0; + spin_unlock(&sess->sn_lock); + + iscsi_cmnd_init_write(rsp, + ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); + +out_release: req_cmnd_release(req); TRACE_EXIT(); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/iscsi.h 2007-12-21 19:10:40 UTC (rev 237) @@ -88,7 +88,7 @@ struct iscsi_target *target; struct scst_session *scst_sess; - /* All 2 unprotected, since accessed only from a single read thread */ + /* Both unprotected, since accessed only from a single read thread */ struct list_head pending_list; u32 next_ttt; @@ -98,6 +98,9 @@ spinlock_t sn_lock; u32 exp_cmd_sn; /* protected by sn_lock */ + /* All 3 protected by sn_lock */ + unsigned int tm_active:1; + u32 tm_sn; struct iscsi_cmnd *tm_rsp; /* read only, if there are connection(s) */ Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/kernel/nthread.c 2007-12-21 19:10:40 UTC (rev 237) @@ -136,6 +136,22 @@ conn_abort(conn); + mutex_lock(&target->target_mutex); + spin_lock(&session->sn_lock); + if ((session->tm_rsp != NULL) && (session->tm_rsp->conn == conn)) { + struct iscsi_cmnd *tm_rsp = session->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); + session->tm_rsp = NULL; + session->tm_active = 0; + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + + rsp_cmnd_release(tm_rsp); + } else { + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + } + if (conn->read_state != RX_INIT_BHS) { req_cmnd_release_force(conn->read_cmnd, 0); conn->read_cmnd = NULL; @@ -181,10 +197,12 @@ spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { - TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, data_waiting " - "%d, ref_cnt %d, parent_req %p", cmnd, - cmnd->scst_state, cmnd->data_waiting, - atomic_read(&cmnd->ref_cnt), cmnd->parent_req); + TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, scst_cmd " + "state %d, data_waiting %d, ref_cnt %d, " + "parent_req %p", cmnd, cmnd->scst_state, + (cmnd->scst_cmd != NULL) ? cmnd->scst_cmd->state : -1, + cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), + cmnd->parent_req); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", atomic_read(&cmnd->net_ref_cnt), cmnd->sg); @@ -568,6 +586,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Read thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock_bh(&iscsi_rd_lock); @@ -598,6 +618,8 @@ */ sBUG_ON(!list_empty(&iscsi_rd_list)); + PRINT_INFO("Read thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -1072,6 +1094,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Write thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock_bh(&iscsi_wr_lock); @@ -1102,6 +1126,8 @@ */ sBUG_ON(!list_empty(&iscsi_wr_list)); + PRINT_INFO("Write thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } Modified: trunk/iscsi-scst/usr/iscsid.c =================================================================== --- trunk/iscsi-scst/usr/iscsid.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/iscsi-scst/usr/iscsid.c 2007-12-21 19:10:40 UTC (rev 237) @@ -108,7 +108,7 @@ } conn->rsp.data = conn->rsp_buffer; } - if (conn->rwsize + len > INCOMING_BUFSIZE) { + if (conn->rsp.datasize + len > INCOMING_BUFSIZE) { log_warning("Dropping key (%s=%s)", key, value); return; } Modified: trunk/scst/include/scst_user.h =================================================================== --- trunk/scst/include/scst_user.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/include/scst_user.h 2007-12-21 19:10:40 UTC (rev 237) @@ -23,9 +23,9 @@ #include <scst_const.h> -#define DEV_USER_NAME "scst_user" +#define DEV_USER_NAME "scst_user" #define DEV_USER_PATH "/dev/" -#define DEV_USER_VERSION 962 +#define DEV_USER_VERSION 963 /* * Chosen so sizeof(scst_user_sess) <= sizeof(scst_user_scsi_cmd_exec) @@ -137,6 +137,8 @@ uint8_t expected_values_set; uint8_t expected_data_direction; int32_t expected_transfer_len; + + uint32_t sn; }; struct scst_user_scsi_cmd_alloc_mem @@ -150,6 +152,8 @@ uint8_t queue_type; uint8_t data_direction; + + uint32_t sn; }; struct scst_user_scsi_cmd_exec @@ -168,6 +172,8 @@ uint8_t partial; uint32_t timeout; + uint32_t sn; + uint32_t parent_cmd_h; int32_t parent_cmd_data_len; uint32_t partial_offset; @@ -193,6 +199,8 @@ aligned_u64 sess_h; uint32_t fn; uint32_t cmd_h_to_abort; + uint32_t cmd_sn; + uint8_t cmd_sn_set; }; struct scst_user_get_cmd Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/dev_handlers/scst_user.c 2007-12-21 19:10:40 UTC (rev 237) @@ -596,6 +596,7 @@ (cmd->sg_cnt << PAGE_SHIFT) : cmd->bufflen; ucmd->user_cmd.alloc_cmd.queue_type = cmd->queue_type; ucmd->user_cmd.alloc_cmd.data_direction = cmd->data_direction; + ucmd->user_cmd.alloc_cmd.sn = cmd->tgt_sn; dev_user_add_to_ready(ucmd); @@ -722,6 +723,7 @@ cmd->expected_data_direction; ucmd->user_cmd.parse_cmd.expected_transfer_len = cmd->expected_transfer_len; + ucmd->user_cmd.parse_cmd.sn = cmd->tgt_sn; ucmd->state = UCMD_STATE_PARSING; dev_user_add_to_ready(ucmd); res = SCST_CMD_STATE_STOP; @@ -809,6 +811,7 @@ ucmd->user_cmd.exec_cmd.data_direction = cmd->data_direction; ucmd->user_cmd.exec_cmd.partial = 0; ucmd->user_cmd.exec_cmd.timeout = cmd->timeout; + ucmd->user_cmd.exec_cmd.sn = cmd->tgt_sn; ucmd->state = UCMD_STATE_EXECING; @@ -2126,6 +2129,8 @@ ucmd->user_cmd.subcode = SCST_USER_TASK_MGMT; ucmd->user_cmd.tm_cmd.sess_h = (unsigned long)tgt_dev; ucmd->user_cmd.tm_cmd.fn = mcmd->fn; + ucmd->user_cmd.tm_cmd.cmd_sn = mcmd->cmd_sn; + ucmd->user_cmd.tm_cmd.cmd_sn_set = mcmd->cmd_sn_set; if (mcmd->cmd_to_abort != NULL) { ucmd_to_abort = (struct scst_user_cmd*)mcmd->cmd_to_abort->dh_priv; @@ -2990,6 +2995,8 @@ TRACE_ENTRY(); + PRINT_INFO("Cleanup thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; spin_lock(&cleanup_lock); @@ -3027,6 +3034,8 @@ */ sBUG_ON(!list_empty(&cleanup_list)); + PRINT_INFO("Cleanup thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_lib.c 2007-12-21 19:10:40 UTC (rev 237) @@ -3322,13 +3322,17 @@ } /* No locks */ -void tm_dbg_task_mgmt(const char *fn, int force) +void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, int force) { unsigned long flags; if (!tm_dbg_flags.tm_dbg_active) goto out; + if ((tgt_dev != NULL) && !test_bit(SCST_TGT_DEV_UNDER_TM_DBG, + &tgt_dev->tgt_dev_flags)) + goto out; + spin_lock_irqsave(&scst_tm_dbg_lock, flags); if ((tm_dbg_state != TM_DBG_STATE_OFFLINE) || force) { TRACE_MGMT_DBG("%s: freeing %d delayed cmds", fn, Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_priv.h 2007-12-21 19:10:40 UTC (rev 237) @@ -512,7 +512,8 @@ extern void tm_dbg_check_released_cmds(void); extern int tm_dbg_check_cmd(struct scst_cmd *cmd); extern void tm_dbg_release_cmd(struct scst_cmd *cmd); -extern void tm_dbg_task_mgmt(const char *fn, int force); +extern void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, + int force); extern int tm_dbg_is_release(void); #else static inline void tm_dbg_init_tgt_dev(struct scst_tgt_dev *tgt_dev, @@ -524,7 +525,8 @@ return 0; } static inline void tm_dbg_release_cmd(struct scst_cmd *cmd) {} -static inline void tm_dbg_task_mgmt(const char *fn, int force) {} +static inline void tm_dbg_task_mgmt(struct scst_tgt_dev *tgt_dev, const char *fn, + int force) {} static inline int tm_dbg_is_release(void) { return 0; Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-14 16:51:36 UTC (rev 236) +++ trunk/scst/src/scst_targ.c 2007-12-21 19:10:40 UTC (rev 237) @@ -448,6 +448,14 @@ if (unlikely(state == SCST_CMD_STATE_PRE_XMIT_RESP)) goto set_res; + if (unlikely((cmd->bufflen == 0) && + (cmd->op_flags & SCST_UNKNOWN_LENGTH))) { + PRINT_ERROR("Unknown data transfer length for opcode 0x%x " + "(handler %s, target %s)", cmd->cdb[0], + dev->handler->name, cmd->tgtt->name); + goto out_error; + } + #ifdef EXTRACHECKS if ((cmd->bufflen != 0) && ((cmd->data_direction == SCST_DATA_NONE) || @@ -2854,6 +2862,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Init thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -2887,6 +2897,8 @@ */ sBUG_ON(!list_empty(&scst_init_cmd_list)); + PRINT_INFO("Init thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -3053,6 +3065,8 @@ TRACE_ENTRY(); + PRINT_INFO("Processing thread started, PID %d", current->pid); + #if 0 set_user_nice(current, 10); #endif @@ -3101,6 +3115,8 @@ } #endif + PRINT_INFO("Processing thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -3659,8 +3675,9 @@ static int scst_target_reset(struct scst_mgmt_cmd *mcmd) { int res, rc; - struct scst_device *dev, *d; - struct scst_tgt_dev *tgt_dev; + struct scst_device *dev; + struct scst_acg *acg = mcmd->sess->acg; + struct scst_acg_dev *acg_dev; int cont, c; LIST_HEAD(host_devs); @@ -3673,20 +3690,12 @@ mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + struct scst_device *d; + struct scst_tgt_dev *tgt_dev; int found = 0; - /* Skip local SCSI devices */ - if (dev->handler == &scst_null_devtype) { - /* - * Generally we shouldn't reset not exported devices, - * but what if a backstorage SCSI disk hung? Let's - * reset it too. - */ - if ((dev->scsi_dev != NULL) && - (dev->scsi_dev->type != TYPE_DISK)) - continue; - } + dev = acg_dev->dev; spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); @@ -3744,14 +3753,15 @@ #endif } - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + dev = acg_dev->dev; if (dev->scsi_dev != NULL) dev->scsi_dev->was_reset = 0; } mutex_unlock(&scst_mutex); - tm_dbg_task_mgmt("TARGET RESET", 0); + tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "TARGET RESET", 0); res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); @@ -3792,7 +3802,7 @@ } out_tm_dbg: - tm_dbg_task_mgmt("LUN RESET", 0); + tm_dbg_task_mgmt(mcmd->mcmd_tgt_dev, "LUN RESET", 0); res = scst_set_mcmd_next_state(mcmd); TRACE_EXIT_RES(res); @@ -3857,9 +3867,9 @@ int res; int i; struct scst_tgt *tgt = mcmd->sess->tgt; + struct scst_acg *acg = mcmd->sess->acg; struct scst_session *sess; - struct scst_device *dev; - struct scst_tgt_dev *tgt_dev; + struct scst_acg_dev *acg_dev; TRACE_ENTRY(); @@ -3875,7 +3885,9 @@ mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, acg_dev_list_entry) { + struct scst_device *dev = acg_dev->dev; + spin_lock_bh(&dev->dev_lock); __scst_block_dev(dev); spin_unlock_bh(&dev->dev_lock); @@ -3885,6 +3897,7 @@ for(i = 0; i < TGT_DEV_HASH_SIZE; i++) { struct list_head *sess_tgt_dev_list_head = &sess->sess_tgt_dev_list_hash[i]; + struct scst_tgt_dev *tgt_dev; list_for_each_entry(tgt_dev, sess_tgt_dev_list_head, sess_tgt_dev_list_entry) { int rc; @@ -4020,12 +4033,19 @@ case SCST_TARGET_RESET: case SCST_ABORT_ALL_TASKS: case SCST_NEXUS_LOSS: + { + struct scst_acg *acg = mcmd->sess->acg; + struct scst_acg_dev *acg_dev; + mutex_lock(&scst_mutex); - list_for_each_entry(dev, &scst_dev_list, dev_list_entry) { + list_for_each_entry(acg_dev, &acg->acg_dev_list, + acg_dev_list_entry) { + dev = acg_dev->dev; scst_unblock_dev(dev); } mutex_unlock(&scst_mutex); break; + } case SCST_NEXUS_LOSS_SESS: case SCST_ABORT_ALL_TASKS_SESS: @@ -4115,6 +4135,8 @@ { TRACE_ENTRY(); + PRINT_INFO("Task management thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -4174,6 +4196,8 @@ */ sBUG_ON(!list_empty(&scst_active_mgmt_cmd_list)); + PRINT_INFO("Task management thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } @@ -4311,7 +4335,7 @@ TRACE((params->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, "sess=%p, fn %x, tag_set %d, tag %Ld, lun_set %d, " - "lun=%Ld, cmd_sn_set %d, cmd_sn %x", sess, params->fn, + "lun=%Ld, cmd_sn_set %d, cmd_sn %d", sess, params->fn, params->tag_set, params->tag, params->lun_set, (uint64_t)mcmd->lun, params->cmd_sn_set, params->cmd_sn); @@ -4551,7 +4575,7 @@ spin_unlock_irqrestore(&scst_mgmt_lock, flags); - tm_dbg_task_mgmt("UNREGISTER SESSION", 1); + tm_dbg_task_mgmt(NULL, "UNREGISTER SESSION", 1); scst_sess_put(sess); @@ -4619,6 +4643,8 @@ TRACE_ENTRY(); + PRINT_INFO("Management thread started, PID %d", current->pid); + current->flags |= PF_NOFREEZE; set_user_nice(current, -20); @@ -4700,6 +4726,8 @@ sBUG_ON(!list_empty(&scst_sess_init_list)); sBUG_ON(!list_empty(&scst_sess_shut_list)); + PRINT_INFO("Management thread PID %d finished", current->pid); + TRACE_EXIT(); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-29 17:04:19
|
Revision: 240 http://scst.svn.sourceforge.net/scst/?rev=240&view=rev Author: vlnb Date: 2007-12-29 09:04:13 -0800 (Sat, 29 Dec 2007) Log Message: ----------- - Fixed huge iSCSI RFC violation, inherited from IET: incorrect commands ordering. - TM fixes related to new commands serialization - Other TM improvements - Minor changes: likely/unlikely and priority of mgmt threads Work not fully completed, still there are some rare issues. Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/qla2x00t/qla_os.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/iscsi-scst/kernel/conn.c 2007-12-29 17:04:13 UTC (rev 240) @@ -173,7 +173,7 @@ TRACE_ENTRY(); - if (sk->sk_state != TCP_ESTABLISHED) { + if (unlikely(sk->sk_state != TCP_ESTABLISHED)) { if (!conn->closing) { PRINT_ERROR("Connection with initiator %s (%p) " "unexpectedly closed!", @@ -392,3 +392,33 @@ return 0; } + +#ifdef EXTRACHECKS + +void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) +{ + if (unlikely(current != conn->rd_task)) { + while(in_softirq()) + local_bh_enable(); + printk(KERN_EMERG "conn %p rd_task != current (%p)", conn, current); + printk(KERN_EMERG "rd_task %p", conn->rd_task); + printk(KERN_EMERG "current->pid %d, rd_task->pid %d", current->pid, + conn->rd_task->pid); + sBUG(); + } +} + +void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn) +{ + if (unlikely(current != conn->wr_task)) { + while(in_softirq()) + local_bh_enable(); + printk(KERN_EMERG "conn %p wr_task != current (%p)", conn, current); + printk(KERN_EMERG "wr_task %p", conn->wr_task); + printk(KERN_EMERG "current->pid %d, wr_task->pid %d", current->pid, + conn->wr_task->pid); + sBUG(); + } +} + +#endif /* EXTRACHECKS */ Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/iscsi-scst/kernel/digest.c 2007-12-29 17:04:13 UTC (rev 240) @@ -142,7 +142,7 @@ u32 crc; crc = digest_header(&cmnd->pdu); - if (crc != cmnd->hdigest) { + if (unlikely(crc != cmnd->hdigest)) { PRINT_ERROR("%s", "RX header digest failed"); return -EIO; } else @@ -183,7 +183,7 @@ crc = digest_data(req, cmnd->pdu.datasize, offset); - if (crc != cmnd->ddigest) { + if (unlikely(crc != cmnd->ddigest)) { PRINT_ERROR("%s", "RX data digest failed"); res = -EIO; } else Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-29 17:04:13 UTC (rev 240) @@ -63,6 +63,7 @@ static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status); static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd); static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess); +static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd); static inline u32 cmnd_write_size(struct iscsi_cmnd *cmnd) { @@ -152,7 +153,7 @@ be32_to_cpu(req->data_length), req->cmd_sn, be32_to_cpu(cmnd->pdu.datasize)); - if (cmnd->parent_req) { + if (unlikely(cmnd->parent_req)) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->parent_req); PRINT_ERROR("%p %x %u", req, req->opcode, req->scb[0]); @@ -169,8 +170,9 @@ TRACE_DBG("%p", cmnd); if (unlikely(cmnd->tmfabort)) { - TRACE_MGMT_DBG("Done aborted cmd %p (scst cmd %p, state %d)", - cmnd, cmnd->scst_cmd, cmnd->scst_state); + TRACE_MGMT_DBG("Done aborted cmd %p (scst cmd %p, state %d, " + "parent_req %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, + cmnd->parent_req); } if (cmnd->parent_req == NULL) { @@ -245,56 +247,54 @@ /* * Corresponding conn may also gets destroyed atfer this function, except only - * if it's called from the read thread! + * if it's called from the read thread! + * + * It can't be called in parallel with iscsi_cmnds_init_write()! */ void req_cmnd_release_force(struct iscsi_cmnd *req, int flags) { - struct iscsi_cmnd *rsp; + struct iscsi_cmnd *rsp, *t; struct iscsi_conn *conn = req->conn; + LIST_HEAD(cmds_list); TRACE_ENTRY(); TRACE_DBG("%p", req); if (flags & ISCSI_FORCE_RELEASE_WRITE) { -again_write: spin_lock(&conn->write_list_lock); - list_for_each_entry(rsp, &conn->write_list, write_list_entry) { + list_for_each_entry_safe(rsp, t, &conn->write_list, + write_list_entry) { if (rsp->parent_req != req) continue; cmd_del_from_write_list(rsp); - spin_unlock(&conn->write_list_lock); + list_add_tail(&rsp->write_list_entry, &cmds_list); + } + spin_unlock(&conn->write_list_lock); + list_for_each_entry_safe(rsp, t, &cmds_list, write_list_entry) { + list_del(&rsp->write_list_entry); cmnd_put(rsp); - goto again_write; } - spin_unlock(&conn->write_list_lock); } again_rsp: spin_lock_bh(&req->rsp_cmd_lock); - list_for_each_entry(rsp, &req->rsp_cmd_list, rsp_cmd_list_entry) { - int f; - + list_for_each_entry_reverse(rsp, &req->rsp_cmd_list, rsp_cmd_list_entry) { + /* + * It's OK to check not under write_list_lock, since + * iscsi_cmnds_init_write() can't be called in parallel with us + * and once on_write_list or write_processing_started get set, + * rsp gets out of this function responsibility. + */ if (rsp->on_write_list || rsp->write_processing_started || rsp->force_cleanup_done) continue; spin_unlock_bh(&req->rsp_cmd_lock); - /* - * Recheck is necessary to not take write_list_lock under - * rsp_cmd_lock. - */ - spin_lock(&conn->write_list_lock); - f = rsp->on_write_list || rsp->write_processing_started || - rsp->force_cleanup_done; - spin_unlock(&conn->write_list_lock); - if (f) - goto again_rsp; - rsp->force_cleanup_done = 1; cmnd_put(rsp); @@ -374,13 +374,6 @@ sBUG_ON(cmnd->hashed); sBUG_ON(cmnd->parent_req == NULL); - if (unlikely(cmnd->tmfabort)) { - TRACE_MGMT_DBG("Release aborted rsp cmd %p (parent req %p, " - "scst cmd %p, state %d)", cmnd, cmnd->parent_req, - cmnd->parent_req->scst_cmd, - cmnd->parent_req->scst_state); - } - cmnd_put(cmnd); return; } @@ -453,7 +446,6 @@ cmd_add_on_write_list(conn, rsp); spin_unlock(&conn->write_list_lock); } - if (flags & ISCSI_INIT_WRITE_WAKE) iscsi_make_conn_wr_active(conn); @@ -707,7 +699,7 @@ cmnd->pdu.bhs.sn = cmd_sn = be32_to_cpu(cmnd->pdu.bhs.sn); TRACE_DBG("%d(%d)", cmd_sn, session->exp_cmd_sn); - if ((s32)(cmd_sn - session->exp_cmd_sn) >= 0) + if (likely((s32)(cmd_sn - session->exp_cmd_sn) >= 0)) return 0; PRINT_ERROR("sequence error (%x,%x)", cmd_sn, session->exp_cmd_sn); return -ISCSI_REASON_PROTOCOL_ERROR; @@ -766,7 +758,7 @@ u32 itt = cmnd->pdu.bhs.itt; TRACE_DBG("%p:%x", cmnd, itt); - if (itt == ISCSI_RESERVED_TAG) { + if (unlikely(itt == ISCSI_RESERVED_TAG)) { PRINT_ERROR("%s", "ITT is RESERVED_TAG"); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; @@ -777,7 +769,7 @@ head = &session->cmnd_hash[cmnd_hashfn(cmnd->pdu.bhs.itt)]; tmp = __cmnd_find_hash(session, itt, ISCSI_RESERVED_TAG); - if (!tmp) { + if (likely(!tmp)) { list_add_tail(&cmnd->hash_list_entry, head); cmnd->hashed = 1; } else { @@ -787,7 +779,7 @@ spin_unlock(&session->cmnd_hash_lock); - if (!err) { + if (likely(!err)) { spin_lock(&session->sn_lock); __update_stat_sn(cmnd); err = check_cmd_sn(cmnd); @@ -807,7 +799,7 @@ tmp = __cmnd_find_hash(session, cmnd->pdu.bhs.itt, ISCSI_RESERVED_TAG); - if (tmp && tmp == cmnd) { + if (likely(tmp && tmp == cmnd)) { list_del(&cmnd->hash_list_entry); cmnd->hashed = 0; } else { @@ -870,8 +862,8 @@ rsp = get_rsp_cmnd(req); rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; - if (cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP) { - PRINT_ERROR("unexpected response command %u", cmnd_opcode(rsp)); + if (unlikely(cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP)) { + PRINT_ERROR("Unexpected response command %u", cmnd_opcode(rsp)); return; } @@ -909,8 +901,8 @@ iscsi_extracheck_is_rd_thread(conn); - if ((offset >= bufflen) || - (offset + size > bufflen)) { + if (unlikely((offset >= bufflen) || + (offset + size > bufflen))) { PRINT_ERROR("Wrong ltn (%u %u %u)", offset, size, bufflen); mark_conn_closed(conn); res = -EIO; @@ -942,7 +934,7 @@ idx, offset, size, conn->read_iov[i].iov_len, addr); size -= conn->read_iov[i].iov_len; offset = 0; - if (++i >= ISCSI_CONN_IOV_MAX) { + if (unlikely(++i >= ISCSI_CONN_IOV_MAX)) { PRINT_ERROR("Initiator %s violated negotiated " "parameters by sending too much data (size " "left %d)", conn->session->initiator_name, size); @@ -964,13 +956,15 @@ struct iscsi_session *session = req->conn->session; struct iscsi_cmnd *rsp; struct iscsi_r2t_hdr *rsp_hdr; - u32 length, offset, burst; + u32 offset, burst; LIST_HEAD(send); if (unlikely(req->tmfabort)) { - TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted on R2T", req, - req->scst_cmd); - req_cmnd_release_force(req, ISCSI_FORCE_RELEASE_WRITE); + TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted on R2T " + "(r2t_length %d, outstanding_r2t %d)", req, + req->scst_cmd, req->r2t_length, req->outstanding_r2t); + if (req->outstanding_r2t == 0) + iscsi_session_push_cmnd(req); goto out; } @@ -980,9 +974,8 @@ */ iscsi_extracheck_is_rd_thread(req->conn); - length = req->r2t_length; burst = session->sess_param.max_burst_length; - offset = be32_to_cpu(cmnd_hdr(req)->data_length) - length; + offset = be32_to_cpu(cmnd_hdr(req)->data_length) - req->r2t_length; do { rsp = iscsi_cmnd_create_rsp_cmnd(req); @@ -994,13 +987,13 @@ 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) { + if (req->r2t_length > burst) { rsp_hdr->data_length = cpu_to_be32(burst); - length -= burst; + req->r2t_length -= burst; offset += burst; } else { - rsp_hdr->data_length = cpu_to_be32(length); - length = 0; + rsp_hdr->data_length = cpu_to_be32(req->r2t_length); + req->r2t_length = 0; } TRACE(TRACE_D_WRITE, "%x %u %u %u %u", cmnd_itt(req), @@ -1013,12 +1006,10 @@ if (++req->outstanding_r2t >= session->sess_param.max_outstanding_r2t) break; - } while (length); + } while(req->r2t_length != 0); iscsi_cmnds_init_write(&send, ISCSI_INIT_WRITE_WAKE); - req->data_waiting = 1; - out: return; } @@ -1058,22 +1049,6 @@ return res; } - -static void scsi_cmnd_exec(struct iscsi_cmnd *cmnd) -{ - if (cmnd->r2t_length) { - if (!cmnd->is_unsolicited_data) - send_r2t(cmnd); - } else { - /* - * There is no race with send_r2t() and __cmnd_abort(), - * since all functions called from single read thread - */ - cmnd->data_waiting = 0; - iscsi_restart_cmnd(cmnd); - } -} - static int noop_out_start(struct iscsi_cmnd *cmnd) { struct iscsi_conn *conn = cmnd->conn; @@ -1084,26 +1059,28 @@ iscsi_extracheck_is_rd_thread(conn); - if (cmnd_ttt(cmnd) != cpu_to_be32(ISCSI_RESERVED_TAG)) { + if (unlikely(cmnd_ttt(cmnd) != cpu_to_be32(ISCSI_RESERVED_TAG))) { /* * We don't request a NOP-Out by sending a NOP-In. * See 10.18.2 in the draft 20. */ - PRINT_ERROR("initiator bug %x", cmnd_itt(cmnd)); + PRINT_ERROR("Initiator sent command with not RESERVED tag and " + "TTT %x", cmnd_itt(cmnd)); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; } if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) { - if (!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)) - PRINT_ERROR("%s","initiator bug!"); + if (unlikely(!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE))) + PRINT_ERROR("%s", "Initiator sent RESERVED tag for " + "non-immediate command"); spin_lock(&conn->session->sn_lock); __update_stat_sn(cmnd); err = check_cmd_sn(cmnd); spin_unlock(&conn->session->sn_lock); - if (err) + if (unlikely(err)) goto out; - } else if ((err = cmnd_insert_hash(cmnd)) < 0) { + } else if (unlikely((err = cmnd_insert_hash(cmnd)) < 0)) { PRINT_ERROR("Can't insert in hash: ignore this request %x", cmnd_itt(cmnd)); goto out; @@ -1266,7 +1243,8 @@ dir = scst_cmd_get_data_direction(scst_cmd); if (dir != SCST_DATA_WRITE) { - if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { + if (unlikely(!(req_hdr->flags & ISCSI_CMD_FINAL) || + req->pdu.datasize)) { PRINT_ERROR("Unexpected unsolicited data (ITT %x " "CDB %x", cmnd_itt(req), req_hdr->scb[0]); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); @@ -1278,11 +1256,12 @@ if (dir == SCST_DATA_WRITE) { req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL); req->r2t_length = be32_to_cpu(req_hdr->data_length) - req->pdu.datasize; + req->data_waiting = 1; } req->target_task_tag = get_next_ttt(conn); req->sg = scst_cmd_get_sg(scst_cmd); req->bufflen = scst_cmd_get_bufflen(scst_cmd); - if (req->r2t_length > req->bufflen) { + if (unlikely(req->r2t_length > req->bufflen)) { PRINT_ERROR("req->r2t_length %d > req->bufflen %d", req->r2t_length, req->bufflen); req->r2t_length = req->bufflen; @@ -1292,8 +1271,8 @@ "r2t_length=%d, bufflen=%d", req, dir, req->is_unsolicited_data, req->r2t_length, req->bufflen); - if (!session->sess_param.immediate_data && - req->pdu.datasize) { + if (unlikely(!session->sess_param.immediate_data && + req->pdu.datasize)) { PRINT_ERROR("Initiator %s violated negotiated paremeters: " "forbidden immediate data sent (ITT %x, op %x)", session->initiator_name, cmnd_itt(req), req_hdr->scb[0]); @@ -1301,8 +1280,8 @@ goto out; } - if (session->sess_param.initial_r2t && - !(req_hdr->flags & ISCSI_CMD_FINAL)) { + if (unlikely(session->sess_param.initial_r2t && + !(req_hdr->flags & ISCSI_CMD_FINAL))) { PRINT_ERROR("Initiator %s violated negotiated paremeters: " "initial R2T is required (ITT %x, op %x)", session->initiator_name, cmnd_itt(req), req_hdr->scb[0]); @@ -1311,7 +1290,7 @@ } if (req->pdu.datasize) { - if (dir != SCST_DATA_WRITE) { + if (unlikely(dir != SCST_DATA_WRITE)) { PRINT_ERROR("pdu.datasize(%d) >0, but dir(%x) isn't WRITE", req->pdu.datasize, dir); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); @@ -1344,36 +1323,28 @@ cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); - if (!req) { + if (unlikely(req == NULL)) { /* It might happen if req was aborted and then freed */ TRACE(TRACE_MGMT_MINOR, "Unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); goto skip_pdu; } - if (req->r2t_length < cmnd->pdu.datasize) { - PRINT_ERROR("Invalid data len %x %u %u", cmnd_itt(req), - cmnd->pdu.datasize, req->r2t_length); - mark_conn_closed(conn); - res = -EINVAL; - goto out; + if (req->is_unsolicited_data) { + if (unlikely(req->r2t_length < cmnd->pdu.datasize)) { + PRINT_ERROR("Data size (%d) > R2T length (%d)", + cmnd->pdu.datasize, req->r2t_length); + mark_conn_closed(conn); + res = -EINVAL; + goto out; + } + req->r2t_length -= cmnd->pdu.datasize; } - if (req->r2t_length + offset != cmnd_write_size(req)) { - PRINT_ERROR("Wrong cmd lengths (%x %u %u %u)", - cmnd_itt(req), req->r2t_length, - offset, cmnd_write_size(req)); - mark_conn_closed(conn); - res = -EINVAL; - goto out; - } - - req->r2t_length -= cmnd->pdu.datasize; - /* Check unsolicited burst data */ - if ((req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) && - (req->pdu.bhs.flags & ISCSI_FLG_FINAL)) { - PRINT_ERROR("unexpected data from %x %x", + if (unlikely((req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) && + (req->pdu.bhs.flags & ISCSI_FLG_FINAL))) { + PRINT_ERROR("Unexpected data from %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); mark_conn_closed(conn); res = -EINVAL; @@ -1419,28 +1390,36 @@ if (req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { TRACE_DBG("ISCSI_RESERVED_TAG, FINAL %x", req_hdr->flags & ISCSI_FLG_FINAL); - if (req_hdr->flags & ISCSI_FLG_FINAL) { + + if (req_hdr->flags & ISCSI_FLG_FINAL) req->is_unsolicited_data = 0; - if (!req->pending) - scsi_cmnd_exec(req); - } + else + goto out_put; } else { - TRACE_DBG("FINAL %x, outstanding_r2t %d, " - "r2t_length %d", req_hdr->flags & ISCSI_FLG_FINAL, + TRACE_DBG("FINAL %x, outstanding_r2t %d, r2t_length %d", + req_hdr->flags & ISCSI_FLG_FINAL, req->outstanding_r2t, req->r2t_length); - /* ToDo : proper error handling */ - if (!(req_hdr->flags & ISCSI_FLG_FINAL) && (req->r2t_length == 0)) - PRINT_ERROR("initiator error %x", cmnd_itt(req)); - if (!(req_hdr->flags & ISCSI_FLG_FINAL)) - goto out; + if (req_hdr->flags & ISCSI_FLG_FINAL) { + if (unlikely(req->is_unsolicited_data)) { + PRINT_ERROR("Unexpected unsolicited data " + "(r2t_length %u, outstanding_r2t %d)", + req->r2t_length, req->is_unsolicited_data); + mark_conn_closed(req->conn); + goto out_put; + } + req->outstanding_r2t--; + } else + goto out_put; + } - req->outstanding_r2t--; + if (req->r2t_length != 0) { + if (!req->is_unsolicited_data) + send_r2t(req); + } else + iscsi_session_push_cmnd(req); - scsi_cmnd_exec(req); - } - -out: +out_put: cmnd_put(cmnd); return; } @@ -1451,37 +1430,39 @@ * * Returns >0 if cmd_list_lock was dropped inside, 0 otherwise. */ -static inline int __cmnd_abort(struct iscsi_cmnd *cmnd) +static int __cmnd_abort(struct iscsi_cmnd *cmnd) { int res = 0; + struct iscsi_conn *conn = cmnd->conn; - /* Check to avoid double release */ - if (cmnd->tmfabort) - goto out; - TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " - "ref_cnt %d, itt %x, sn %d, op %x, r2t_len %x, CDB op %x, " - "size to write %u, is_unsolicited_data %u, " - "outstanding_r2t %u)", cmnd, cmnd->scst_cmd, - cmnd->scst_state, atomic_read(&cmnd->ref_cnt), - cmnd_itt(cmnd), cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), - cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), - cmnd->is_unsolicited_data, cmnd->outstanding_r2t); + "ref_cnt %d, itt %x, sn %u, op %x, r2t_len %x, CDB op %x, " + "size to write %u, is_unsolicited_data %d, " + "outstanding_r2t %d, data_waiting %d, sess->exp_cmd_sn %u)", + cmnd, cmnd->scst_cmd, cmnd->scst_state, + atomic_read(&cmnd->ref_cnt), cmnd_itt(cmnd), cmnd->pdu.bhs.sn, + cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), + cmnd_write_size(cmnd), cmnd->is_unsolicited_data, + cmnd->outstanding_r2t, cmnd->data_waiting, + conn->session->exp_cmd_sn); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); #endif - iscsi_extracheck_is_rd_thread(cmnd->conn); + iscsi_extracheck_is_rd_thread(conn); cmnd->tmfabort = 1; - if (cmnd->data_waiting) { - struct iscsi_conn *conn = cmnd->conn; + if (cmnd->data_waiting && conn->closing) { + spin_unlock_bh(&conn->cmd_list_lock); + res = 1; - spin_unlock_bh(&conn->cmd_list_lock); - TRACE_MGMT_DBG("Releasing data waiting cmd %p", cmnd); - req_cmnd_release_force(cmnd, ISCSI_FORCE_RELEASE_WRITE); + + /* ToDo: this is racy for MC/S */ + TRACE_MGMT_DBG("Pushing data waiting cmd %p", cmnd); + iscsi_session_push_cmnd(cmnd); + /* * We are in the read thread, so we may not worry that after * cmnd release conn gets released as well. @@ -1489,7 +1470,6 @@ spin_lock_bh(&conn->cmd_list_lock); } -out: return res; } @@ -1502,6 +1482,15 @@ struct iscsi_cmnd *cmnd; int err; + req_hdr->ref_cmd_sn = be32_to_cpu(req_hdr->ref_cmd_sn); + + if (after(req_hdr->ref_cmd_sn, req_hdr->cmd_sn)) { + PRINT_ERROR("ABORT TASK: RefCmdSN(%u) > CmdSN(%u)", + req_hdr->ref_cmd_sn, req_hdr->cmd_sn); + err = ISCSI_RESPONSE_FUNCTION_REJECTED; + goto out; + } + if ((cmnd = cmnd_find_hash_get(session, req_hdr->rtt, ISCSI_RESERVED_TAG))) { struct iscsi_conn *conn = cmnd->conn; struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); @@ -1514,6 +1503,26 @@ goto out_put; } + if (cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE) { + if (req_hdr->ref_cmd_sn != req_hdr->cmd_sn) { + PRINT_ERROR("ABORT TASK: RefCmdSN(%u) != TM cmd " + "CmdSN(%u) for immediate command %p", + req_hdr->ref_cmd_sn, req_hdr->cmd_sn, + cmnd); + err = ISCSI_RESPONSE_FUNCTION_REJECTED; + goto out_put; + } + } else { + if (req_hdr->ref_cmd_sn != hdr->cmd_sn) { + PRINT_ERROR("ABORT TASK: RefCmdSN(%u) != " + "CmdSN(%u) for command %p", + req_hdr->ref_cmd_sn, req_hdr->cmd_sn, + cmnd); + err = ISCSI_RESPONSE_FUNCTION_REJECTED; + goto out_put; + } + } + if (before(req_hdr->cmd_sn, hdr->cmd_sn) || (req_hdr->cmd_sn == hdr->cmd_sn)) { PRINT_ERROR("ABORT TASK: SN mismatch: req SN %x, " @@ -1635,7 +1644,7 @@ struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM cmd: req %p, itt %x, fn %d, rtt %x, sn %d", req, cmnd_itt(req), + "TM cmd: req %p, itt %x, fn %d, rtt %x, sn %u", req, cmnd_itt(req), function, req_hdr->rtt, req_hdr->cmd_sn); spin_lock(&sess->sn_lock); @@ -1822,7 +1831,7 @@ noop_out_exec(cmnd); break; case ISCSI_OP_SCSI_CMD: - scsi_cmnd_exec(cmnd); + iscsi_restart_cmnd(cmnd); break; case ISCSI_OP_SCSI_TASK_MGT_MSG: execute_task_management(cmnd); @@ -1996,9 +2005,19 @@ iscsi_extracheck_is_rd_thread(cmnd->conn); + sBUG_ON(cmnd->parent_req != NULL); + + /* + * There is no race with __cmnd_abort(), since all functions + * called from single read thread + */ + cmnd->data_waiting = 0; + if (cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE) { + TRACE_DBG("Immediate cmd %p (cmd_sn %u)", cmnd, + cmnd->pdu.bhs.sn); iscsi_cmnd_exec(cmnd); - return; + goto out; } spin_lock(&session->sn_lock); @@ -2033,26 +2052,73 @@ pending_list_entry); if (cmnd->pdu.bhs.sn != cmd_sn) break; + list_del(&cmnd->pending_list_entry); - cmnd->pending = 0; + TRACE_DBG("Processing pending cmd %p (cmd_sn %u)", + cmnd, cmd_sn); + spin_lock(&session->sn_lock); } } else { - cmnd->pending = 1; - if (before(cmd_sn, session->exp_cmd_sn)) { - PRINT_ERROR("unexpected cmd_sn (%u,%u)", cmd_sn, + int drop = 0; + + TRACE_DBG("Pending cmd %p (cmd_sn %u, exp_cmd_sn %u)", + cmnd, cmd_sn, session->exp_cmd_sn); + + /* + * iSCSI RFC 3720: "The target MUST silently ignore any + * non-immediate command outside of [from ExpCmdSN to MaxCmdSN + * inclusive] range". But we won't honor the MaxCmdSN + * requirement, because, since we adjust MaxCmdSN from the + * separate write thread, rarery it is possible that initiator + * can legally send command with CmdSN>MaxSN. But it won't + * hurt anything, in the worst case it will lead to + * additional QUEUE FULL status. + */ + + if (unlikely(before(cmd_sn, session->exp_cmd_sn))) { + PRINT_ERROR("Unexpected cmd_sn (%u,%u)", cmd_sn, session->exp_cmd_sn); + drop = 1; } - if (after(cmd_sn, session->exp_cmd_sn + iscsi_get_allowed_cmds(session))) { - PRINT_INFO("Suspicious: too large cmd_sn %u (exp_cmd_sn %u, " +#if 0 + if (unlikely(after(cmd_sn, session->exp_cmd_sn + + iscsi_get_allowed_cmds(session)))) { + TRACE_MGMT_DBG("Too large cmd_sn %u (exp_cmd_sn %u, " "max_sn %u)", cmd_sn, session->exp_cmd_sn, iscsi_get_allowed_cmds(session)); } +#endif spin_unlock(&session->sn_lock); + if (unlikely(drop)) { + req_cmnd_release_force(cmnd, ISCSI_FORCE_RELEASE_WRITE); + goto out; + } + + if (unlikely(cmnd->tmfabort)) { + struct iscsi_cmnd *tm_clone; + + TRACE_MGMT_DBG("Pending aborted cmnd %p, creating TM " + "clone (scst cmd %p, state %d)", cmnd, + cmnd->scst_cmd, cmnd->scst_state); + + tm_clone = cmnd_alloc(cmnd->conn, NULL); + if (tm_clone != NULL) { + tm_clone->tmfabort = 1; + tm_clone->pdu = cmnd->pdu; + + TRACE_MGMT_DBG("TM clone %p created", tm_clone); + + iscsi_cmnd_exec(cmnd); + cmnd = tm_clone; + } else + PRINT_ERROR("%s", "Unable to create TM clone"); + } + list_for_each(entry, &session->pending_list) { struct iscsi_cmnd *tmp = list_entry(entry, struct iscsi_cmnd, pending_list_entry); @@ -2062,7 +2128,7 @@ list_add_tail(&cmnd->pending_list_entry, entry); } - +out: return; } @@ -2071,7 +2137,7 @@ struct iscsi_conn *conn = cmnd->conn; struct iscsi_session *session = conn->session; - if (cmnd->pdu.datasize > session->sess_param.max_recv_data_length) { + if (unlikely(cmnd->pdu.datasize > session->sess_param.max_recv_data_length)) { PRINT_ERROR("Initiator %s violated negotiated parameters: " "data too long (ITT %x, datasize %u, " "max_recv_data_length %u", session->initiator_name, @@ -2143,12 +2209,20 @@ void cmnd_rx_end(struct iscsi_cmnd *cmnd) { + TRACE_ENTRY(); + TRACE_DBG("%p:%x", cmnd, cmnd_opcode(cmnd)); switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_CMD: + if (cmnd->r2t_length != 0) { + if (!cmnd->is_unsolicited_data) + send_r2t(cmnd); + break; + } + /* else go through */ case ISCSI_OP_SCSI_REJECT: case ISCSI_OP_NOOP_OUT: - case ISCSI_OP_SCSI_CMD: case ISCSI_OP_SCSI_TASK_MGT_MSG: case ISCSI_OP_LOGOUT_CMD: iscsi_session_push_cmnd(cmnd); @@ -2169,6 +2243,8 @@ req_cmnd_release(cmnd); break; } + + TRACE_EXIT(); return; } @@ -2323,7 +2399,8 @@ TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p", req, resp_flags, req->bufflen, req->sg); - if ((req->bufflen != 0) && !(resp_flags & SCST_TSC_FLAG_STATUS)) { + if (unlikely((req->bufflen != 0) && + !(resp_flags & SCST_TSC_FLAG_STATUS))) { PRINT_ERROR("%s", "Sending DATA without STATUS is unsupported"); scst_set_cmd_error(scst_cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); @@ -2474,7 +2551,7 @@ if (iscsi_is_delay_tm_resp(rsp)) { TRACE(TRACE_MGMT_MINOR, "Delaying TM fn %x response %p " "(req %p), because not all affected commands received " - "(cmd sn %d, exp sn %d)", + "(TM cmd sn %u, exp sn %u)", req_hdr->function & ISCSI_FUNCTION_MASK, rsp, req, req_hdr->cmd_sn, sess->exp_cmd_sn); sess->tm_rsp = rsp; Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/iscsi-scst/kernel/iscsi.h 2007-12-29 17:04:13 UTC (rev 240) @@ -236,7 +236,6 @@ /* Some flags protected by conn->write_list_lock */ unsigned int hashed:1; unsigned int should_close_conn:1; - unsigned int pending:1; unsigned int own_sg:1; unsigned int on_write_list:1; unsigned int write_processing_started:1; @@ -490,8 +489,8 @@ } #ifdef EXTRACHECKS -#define iscsi_extracheck_is_rd_thread(conn) sBUG_ON(current != (conn)->rd_task) -#define iscsi_extracheck_is_wr_thread(conn) sBUG_ON(current != (conn)->wr_task) +extern void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn); +extern void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn); #else static inline void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) {} static inline void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn) {} Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/iscsi-scst/kernel/nthread.c 2007-12-29 17:04:13 UTC (rev 240) @@ -120,9 +120,7 @@ { struct iscsi_session *session = conn->session; struct iscsi_target *target = conn->target; -#ifdef DEBUG unsigned long start_waiting = jiffies; -#endif TRACE_ENTRY(); @@ -131,27 +129,13 @@ iscsi_extracheck_is_rd_thread(conn); + sBUG_ON(!conn->closing); + /* We want all our already send operations to complete */ conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); conn_abort(conn); - mutex_lock(&target->target_mutex); - spin_lock(&session->sn_lock); - if ((session->tm_rsp != NULL) && (session->tm_rsp->conn == conn)) { - struct iscsi_cmnd *tm_rsp = session->tm_rsp; - TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); - session->tm_rsp = NULL; - session->tm_active = 0; - spin_unlock(&session->sn_lock); - mutex_unlock(&target->target_mutex); - - rsp_cmnd_release(tm_rsp); - } else { - spin_unlock(&session->sn_lock); - mutex_unlock(&target->target_mutex); - } - if (conn->read_state != RX_INIT_BHS) { req_cmnd_release_force(conn->read_cmnd, 0); conn->read_cmnd = NULL; @@ -162,31 +146,108 @@ while(atomic_read(&conn->conn_ref_cnt) != 0) { struct iscsi_cmnd *cmnd; + mutex_lock(&target->target_mutex); + spin_lock(&session->sn_lock); + if ((session->tm_rsp != NULL) && (session->tm_rsp->conn == conn)) { + struct iscsi_cmnd *tm_rsp = session->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", + tm_rsp); + session->tm_rsp = NULL; + session->tm_active = 0; + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + + rsp_cmnd_release(tm_rsp); + } else { + spin_unlock(&session->sn_lock); + mutex_unlock(&target->target_mutex); + } + if (!list_empty(&session->pending_list)) { struct list_head *pending_list = &session->pending_list; - struct iscsi_cmnd *tmp; + int req_freed; TRACE_CONN_CLOSE("Disposing pending commands on " "connection %p (conn_ref_cnt=%d)", conn, atomic_read(&conn->conn_ref_cnt)); - - list_for_each_entry_safe(cmnd, tmp, pending_list, - pending_list_entry) { - if (cmnd->conn == conn) { - TRACE_CONN_CLOSE("Freeing pending cmd %p", - cmnd); - list_del(&cmnd->pending_list_entry); - cmnd->pending = 0; - req_cmnd_release_force(cmnd, 0); + + /* + * Such complicated approach currently isn't necessary, + * but it will be necessary for MC/S, if we won't want + * to reestablish the whole session on a connection + * failure. + */ + + spin_lock(&session->sn_lock); + do { + req_freed = 0; + list_for_each_entry(cmnd, pending_list, + pending_list_entry) { + TRACE_CONN_CLOSE("Pending cmd %p" + "(conn %p, cmd_sn %u, exp_cmd_sn %u)", + cmnd, conn, cmnd->pdu.bhs.sn, + session->exp_cmd_sn); + if ((cmnd->conn == conn) && + (session->exp_cmd_sn == cmnd->pdu.bhs.sn)) { + TRACE_CONN_CLOSE("Freeing pending cmd %p", + cmnd); + + list_del(&cmnd->pending_list_entry); + + session->exp_cmd_sn++; + + spin_unlock(&session->sn_lock); + + req_cmnd_release_force(cmnd, 0); + + req_freed = 1; + spin_lock(&session->sn_lock); + break; + } } + } while(req_freed); + spin_unlock(&session->sn_lock); + + if (time_after(jiffies, start_waiting + 5*HZ)) { + TRACE_CONN_CLOSE("%s", "Wait time expired"); + spin_lock(&session->sn_lock); + do { + req_freed = 0; + list_for_each_entry(cmnd, pending_list, + pending_list_entry) { + TRACE_CONN_CLOSE("Pending cmd %p" + "(conn %p, cmd_sn %u, exp_cmd_sn %u)", + cmnd, conn, cmnd->pdu.bhs.sn, + session->exp_cmd_sn); + if (cmnd->conn == conn) { + PRINT_ERROR("Freeing orphaned " + "pending cmd %p", cmnd); + + list_del(&cmnd->pending_list_entry); + + if (session->exp_cmd_sn == cmnd->pdu.bhs.sn) + session->exp_cmd_sn++; + + spin_unlock(&session->sn_lock); + + req_cmnd_release_force(cmnd, 0); + + req_freed = 1; + spin_lock(&session->sn_lock); + break; + } + } + } while(req_freed); + spin_unlock(&session->sn_lock); } } iscsi_make_conn_wr_active(conn); msleep(50); - TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d", - conn, atomic_read(&conn->conn_ref_cnt), conn->wr_state); + TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " + "exp_cmd_sn %u", conn, atomic_read(&conn->conn_ref_cnt), + conn->wr_state, session->exp_cmd_sn); #ifdef DEBUG { #ifdef NET_PAGE_CALLBACKS_DEFINED @@ -198,11 +259,11 @@ spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, scst_cmd " - "state %d, data_waiting %d, ref_cnt %d, " + "state %d, data_waiting %d, ref_cnt %d, sn %u, " "parent_req %p", cmnd, cmnd->scst_state, (cmnd->scst_cmd != NULL) ? cmnd->scst_cmd->state : -1, cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), - cmnd->parent_req); + cmnd->pdu.bhs.sn, cmnd->parent_req); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", atomic_read(&cmnd->net_ref_cnt), cmnd->sg); @@ -493,7 +554,7 @@ if (conn->read_state != RX_END) goto out; - if (conn->read_size) { + if (unlikely(conn->read_size)) { PRINT_ERROR("%d %x %d", res, cmnd_opcode(cmnd), conn->read_size); sBUG(); } @@ -742,7 +803,7 @@ } sg = write_cmnd->sg; - if (sg == NULL) { + if (unlikely(sg == NULL)) { PRINT_ERROR("%s", "warning data missing!"); return 0; } @@ -990,7 +1051,7 @@ if (conn->write_state != TX_END) goto out; - if (conn->write_size) { + if (unlikely(conn->write_size)) { PRINT_ERROR("%d %x %u", res, cmnd_opcode(cmnd), conn->write_size); sBUG(); Modified: trunk/qla2x00t/qla_os.c =================================================================== --- trunk/qla2x00t/qla_os.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/qla2x00t/qla_os.c 2007-12-29 17:04:13 UTC (rev 240) @@ -2230,7 +2230,7 @@ ha = (scsi_qla_host_t *)data; - set_user_nice(current, -20); + set_user_nice(current, -10); while (!kthread_should_stop()) { DEBUG3(printk("qla2x00: DPC handler sleeping\n")); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-24 19:22:02 UTC (rev 239) +++ trunk/scst/src/scst_targ.c 2007-12-29 17:04:13 UTC (rev 240) @@ -2866,7 +2866,7 @@ current->flags |= PF_NOFREEZE; - set_user_nice(current, -20); + set_user_nice(current, -10); spin_lock_irq(&scst_init_lock); while(!kthread_should_stop()) { @@ -4141,7 +4141,7 @@ current->flags |= PF_NOFREEZE; - set_user_nice(current, -20); + set_user_nice(current, -10); spin_lock_irq(&scst_mcmd_lock); while(!kthread_should_stop()) { @@ -4649,7 +4649,7 @@ current->flags |= PF_NOFREEZE; - set_user_nice(current, -20); + set_user_nice(current, -10); spin_lock_irq(&scst_mgmt_lock); while(!kthread_should_stop()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2007-12-31 11:42:32
|
Revision: 241 http://scst.svn.sourceforge.net/scst/?rev=241&view=rev Author: vlnb Date: 2007-12-31 03:42:23 -0800 (Mon, 31 Dec 2007) Log Message: ----------- Minor logging changes Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2007-12-29 17:04:13 UTC (rev 240) +++ trunk/iscsi-scst/kernel/conn.c 2007-12-31 11:42:23 UTC (rev 241) @@ -400,10 +400,11 @@ if (unlikely(current != conn->rd_task)) { while(in_softirq()) local_bh_enable(); - printk(KERN_EMERG "conn %p rd_task != current (%p)", conn, current); - printk(KERN_EMERG "rd_task %p", conn->rd_task); - printk(KERN_EMERG "current->pid %d, rd_task->pid %d", current->pid, - conn->rd_task->pid); + printk(KERN_EMERG "conn %p rd_task != current %p (pid %d)\n", conn, + current, current->pid); + printk(KERN_EMERG "wr_state %x\n", conn->rd_state); + printk(KERN_EMERG "rd_task %p\n", conn->rd_task); + printk(KERN_EMERG "rd_task->pid %d\n", conn->rd_task->pid); sBUG(); } } @@ -413,10 +414,11 @@ if (unlikely(current != conn->wr_task)) { while(in_softirq()) local_bh_enable(); - printk(KERN_EMERG "conn %p wr_task != current (%p)", conn, current); - printk(KERN_EMERG "wr_task %p", conn->wr_task); - printk(KERN_EMERG "current->pid %d, wr_task->pid %d", current->pid, - conn->wr_task->pid); + printk(KERN_EMERG "conn %p wr_task != current %p (pid %d)\n", conn, + current, current->pid); + printk(KERN_EMERG "wr_state %x\n", conn->wr_state); + printk(KERN_EMERG "wr_task %p\n", conn->wr_task); + printk(KERN_EMERG "wr_task->pid %d\n", conn->wr_task->pid); sBUG(); } } Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-29 17:04:13 UTC (rev 240) +++ trunk/iscsi-scst/kernel/iscsi.c 2007-12-31 11:42:23 UTC (rev 241) @@ -1438,13 +1438,13 @@ TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " "ref_cnt %d, itt %x, sn %u, op %x, r2t_len %x, CDB op %x, " "size to write %u, is_unsolicited_data %d, " - "outstanding_r2t %d, data_waiting %d, sess->exp_cmd_sn %u)", - cmnd, cmnd->scst_cmd, cmnd->scst_state, + "outstanding_r2t %d, data_waiting %d, sess->exp_cmd_sn %u, " + "conn %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, atomic_read(&cmnd->ref_cnt), cmnd_itt(cmnd), cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->is_unsolicited_data, cmnd->outstanding_r2t, cmnd->data_waiting, - conn->session->exp_cmd_sn); + conn->session->exp_cmd_sn, conn); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-29 17:04:13 UTC (rev 240) +++ trunk/scst/src/scst_lib.c 2007-12-31 11:42:23 UTC (rev 241) @@ -3013,6 +3013,7 @@ if ((cmd->tgt_dev != NULL) && scst_is_ua_sense(cmd->sense_buffer)) { /* This UA delivery is going to fail, so requeue it */ + TRACE_MGMT_DBG("Requeuing UA for aborted cmd %p", cmd); scst_check_set_UA(cmd->tgt_dev, cmd->sense_buffer, sizeof(cmd->sense_buffer), 1); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2007-12-29 17:04:13 UTC (rev 240) +++ trunk/scst/src/scst_targ.c 2007-12-31 11:42:23 UTC (rev 241) @@ -2558,6 +2558,8 @@ if ((cmd->tgt_dev != NULL) && scst_is_ua_sense(cmd->sense_buffer)) { /* This UA delivery failed, so requeue it */ + TRACE_MGMT_DBG("Requeuing UA for delivery failed cmd " + "%p", cmd); scst_check_set_UA(cmd->tgt_dev, cmd->sense_buffer, sizeof(cmd->sense_buffer), 1); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-04 17:30:03
|
Revision: 242 http://scst.svn.sourceforge.net/scst/?rev=242&view=rev Author: vlnb Date: 2008-01-04 09:29:58 -0800 (Fri, 04 Jan 2008) Log Message: ----------- - Fixes two problems on connection closing, leading to crashes and memory corruptions - Small logging improvements Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/nthread.c trunk/scst/src/scst_lib.c Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2007-12-31 11:42:23 UTC (rev 241) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-04 17:29:58 UTC (rev 242) @@ -261,6 +261,8 @@ TRACE_DBG("%p", req); + sBUG_ON(req == conn->read_cmnd); + if (flags & ISCSI_FORCE_RELEASE_WRITE) { spin_lock(&conn->write_list_lock); list_for_each_entry_safe(rsp, t, &conn->write_list, @@ -921,7 +923,7 @@ sBUG_ON(sg[idx].page == NULL); addr = page_address(sg[idx].page); sBUG_ON(addr == NULL); - conn->read_iov[i].iov_base = addr + offset; + conn->read_iov[i].iov_base = addr + offset; if (offset + size <= PAGE_SIZE) { TRACE_DBG("idx=%d, offset=%u, size=%d, addr=%p", idx, offset, size, addr); @@ -2478,6 +2480,8 @@ TRACE_ENTRY(); + /* This should be checked for immediate TM commands as well */ + switch(function) { default: if (before(sess->exp_cmd_sn, req_hdr->cmd_sn)) Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2007-12-31 11:42:23 UTC (rev 241) +++ trunk/iscsi-scst/kernel/nthread.c 2008-01-04 17:29:58 UTC (rev 242) @@ -134,14 +134,15 @@ /* We want all our already send operations to complete */ conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); - conn_abort(conn); - if (conn->read_state != RX_INIT_BHS) { - req_cmnd_release_force(conn->read_cmnd, 0); + struct iscsi_cmnd *cmnd = conn->read_cmnd; conn->read_cmnd = NULL; conn->read_state = RX_INIT_BHS; + req_cmnd_release_force(cmnd, 0); } + conn_abort(conn); + /* ToDo: not the best way to wait */ while(atomic_read(&conn->conn_ref_cnt) != 0) { struct iscsi_cmnd *cmnd; @@ -372,6 +373,8 @@ struct msghdr msg; int res, first_len; + sBUG_ON(conn->read_cmnd == NULL); + if (unlikely(conn->closing)) { res = -EIO; goto out; @@ -559,12 +562,13 @@ sBUG(); } + conn->read_cmnd = NULL; + conn->read_state = RX_INIT_BHS; + cmnd_rx_end(cmnd); sBUG_ON(conn->read_size != 0); - conn->read_cmnd = NULL; - conn->read_state = RX_INIT_BHS; res = 0; out: Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2007-12-31 11:42:23 UTC (rev 241) +++ trunk/scst/src/scst_lib.c 2008-01-04 17:29:58 UTC (rev 242) @@ -2291,17 +2291,27 @@ goto out; } else { - TRACE(TRACE_MGMT_MINOR, "Internal MODE SENSE to device " - "%d:%d:%d:%d failed: %x", dev->scsi_dev->host->host_no, - dev->scsi_dev->channel, dev->scsi_dev->id, - dev->scsi_dev->lun, res); - TRACE_BUFF_FLAG(TRACE_MGMT_MINOR, "MODE SENSE sense", - sense_buffer, sizeof(sense_buffer)); if ((status_byte(res) == CHECK_CONDITION) && SCST_SENSE_VALID(sense_buffer) && (sense_buffer[2] == ILLEGAL_REQUEST)) { + TRACE(TRACE_MGMT_MINOR, "Device %d:%d:%d:%d " + "doesn't support control mode page, using " + "defaults: TST %x, QUEUE ALG %x, SWP %x, " + "TAS %x, has_own_order_mgmt %d", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, dev->tst, dev->queue_alg, + dev->swp, dev->tas, dev->has_own_order_mgmt); res = 0; goto out; + } else { + TRACE(TRACE_MGMT_MINOR, "Internal MODE SENSE to " + "device %d:%d:%d:%d failed: %x", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, res); + TRACE_BUFF_FLAG(TRACE_MGMT_MINOR, "MODE SENSE sense", + sense_buffer, sizeof(sense_buffer)); } scst_check_internal_sense(dev, res, sense_buffer, sizeof(sense_buffer)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-11 10:03:55
|
Revision: 243 http://scst.svn.sourceforge.net/scst/?rev=243&view=rev Author: vlnb Date: 2008-01-11 02:03:48 -0800 (Fri, 11 Jan 2008) Log Message: ----------- - Fixed possible crash on SN slots overflow - Docs updates - Other minor changes Modified Paths: -------------- trunk/iscsi-scst/README trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/README trunk/scst/ToDo trunk/scst/include/scsi_tgt.h trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/iscsi-scst/README 2008-01-11 10:03:48 UTC (rev 243) @@ -32,6 +32,10 @@ Basically as in README-IET, where file names are changed as specified above. +If you experience problems during kernel module load or running, check +your system and/or kernel logs (or run dmesg command for the few most +recent kernel messages). + To use full power of TCP zero-copy transmit functions, especially dealing with user space supplied via scst_user module memory, iSCSI-SCST needs to be notified when Linux networking finished data transmission. @@ -46,7 +50,7 @@ handlers) usage of SGV cache on transmit path (READ-type commands) will be disabled. The performance hit will be not big, but performance will still remain better, than for IET, because SGV cache will remain - used on receive path and IET doesn't have such feature. + used on receive path while IET doesn't have such feature. - For user space allocated memory (scst_user handler) all transmitted data will be additionally copied into temporary TCP buffers. The @@ -103,13 +107,12 @@ "Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz", and add there all necessary LUNs. Check SCST README file for details. +Check SCST README file how to tune for the best performance. + If under high load you experience I/O stalls or see in the kernel log -abort or reset messages then try to reduce QueuedCommands parameter in -iscsi-scstd.conf file for the corresponding target. Particularly, it is -known that the default value 32 sometimes too high if you do intensive -writes from VMware on a target disk, which use LVM in the snapshot mode. -In this case value like 16 or even 10 depending of your backstorage -speed could be more appropriate. +abort or reset messages, then try to reduce QueuedCommands parameter in +iscsi-scstd.conf file for the corresponding target. See also SCST README +file for more details about that issue. CAUTION: Working of target and initiator on the same host isn't ======== supported. See SCST README file for details. Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-11 10:03:48 UTC (rev 243) @@ -1613,8 +1613,7 @@ TRACE_ENTRY(); - TRACE((scst_mcmd->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "scst_mcmd (%p) status %#x state %#x", scst_mcmd, + TRACE_MGMT_DBG("scst_mcmd (%p) status %#x state %#x", scst_mcmd, scst_mcmd->status, scst_mcmd->state); mcmd = scst_mgmt_cmd_get_tgt_priv(scst_mcmd); Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/README 2008-01-11 10:03:48 UTC (rev 243) @@ -87,6 +87,9 @@ are seen remotely. There must be LUN 0 in each security group, i.e. LUs numeration must not start from, e.g., 1. +If you experience problems during modules load or running, check your +kernel logs (or run dmesg command for the few most recent messages). + IMPORTANT: Without loading appropriate device handler, corresponding devices ========= will be invisible for remote initiators, which could lead to holes in the LUN addressing, so automatic device scanning by remote SCSI @@ -713,6 +716,47 @@ See also important notes about setting block sizes >512 bytes for VDISK FILEIO devices above. +What if target's backstorage is too slow +---------------------------------------- + +If under high load you experience I/O stalls or see in the kernel log on +the target abort or reset messages, then your backstorage is too slow +for your target link speed and amount of simultaneously queued commands. +Simply processing of one or more commands takes too long, so initiator +decides that they are stuck on the target and tries to recover. +Particularly, it is known that the default amount of simultaneously +queued commands (48) is sometimes too high if you do intensive writes +from VMware on a target disk, which uses LVM in the snapshot mode. In +this case value like 16 or even 10 depending of your backstorage speed +could be more appropriate. + +Unfortunately, currently SCST lacks dynamic I/O flow control, when the +queue depth on the target is dynamically decreased/increased based on +how slow/fast the backstorage speed comparing to the target link. So, +there are only 4 possible actions, which you can do to workaround or fix +this issue: + +1. Ignore incoming task management (TM) commands. It's fine if there are +not too many of them, i.e. if the backstorage isn't too slow. + +2. Decrease /sys/block/sdX/device/queue_depth on the initiator in case +if it's Linux (see below how) and/or SCST_MAX_TGT_DEV_COMMANDS constant +in scst_priv.h file until you stop seeing incoming TM commands. + +3. Insrease speed of the target's backstorage. + +4. Implement in SCST the dynamic I/O flow control. + +To decrease device queue depth on Linux initiators run command: + +# echo Y >/sys/block/sdX/device/queue_depth + +where Y is the new number of simultaneously queued commands, X - your +imported device letter, like 'a' for sda device. There are no special +limitations for Y value, it can be any value from 1 to possible maximum +(usually, 32), so start from dividing the current value on 2, i.e. set +16, if /sys/block/sdX/device/queue_depth contains 32. + Credits ------- Modified: trunk/scst/ToDo =================================================================== --- trunk/scst/ToDo 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/ToDo 2008-01-11 10:03:48 UTC (rev 243) @@ -8,6 +8,11 @@ the page cache (in order to avoid data copy between it and internal buffers). Requires modifications of the kernel. + - Dynamic I/O flow control, when the device queue depth on the target + will be dynamically decreased/increased based on how slow/fast the + backstorage speed comparing to the target link for current IO + pattern. + - Fix in-kernel O_DIRECT mode. - Close integration with Linux initiator SCSI mil-level, including Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/include/scsi_tgt.h 2008-01-11 10:03:48 UTC (rev 243) @@ -1427,11 +1427,11 @@ * Set if the prev cmd was ORDERED. Size must allow unprotected * modifications */ - unsigned long prev_cmd_ordered; + unsigned long prev_cmd_ordered; - int num_free_sn_slots; + int num_free_sn_slots; /* if it's <0, then all slots are busy */ atomic_t *cur_sn_slot; - atomic_t sn_slots[10]; + atomic_t sn_slots[15]; /* Used for storage of dev handler private stuff */ void *dh_priv; Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/src/scst_lib.c 2008-01-11 10:03:48 UTC (rev 243) @@ -415,7 +415,7 @@ INIT_LIST_HEAD(&tgt_dev->deferred_cmd_list); INIT_LIST_HEAD(&tgt_dev->skipped_sn_list); tgt_dev->expected_sn = 1; - tgt_dev->num_free_sn_slots = ARRAY_SIZE(tgt_dev->sn_slots); + tgt_dev->num_free_sn_slots = ARRAY_SIZE(tgt_dev->sn_slots)-1; tgt_dev->cur_sn_slot = &tgt_dev->sn_slots[0]; for(i = 0; i < (int)ARRAY_SIZE(tgt_dev->sn_slots); i++) atomic_set(&tgt_dev->sn_slots[i], 0); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/src/scst_priv.h 2008-01-11 10:03:48 UTC (rev 243) @@ -103,7 +103,7 @@ ** Maximum count of uncompleted commands that an initiator could ** queue on any device. Then it will start getting TASK QUEUE FULL status. **/ -#define SCST_MAX_TGT_DEV_COMMANDS 32 +#define SCST_MAX_TGT_DEV_COMMANDS 48 /** ** Maximum count of uncompleted commands that could be queued on any device. Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-04 17:29:58 UTC (rev 242) +++ trunk/scst/src/scst_targ.c 2008-01-11 10:03:48 UTC (rev 243) @@ -1772,14 +1772,16 @@ TRACE_SN("Slot is 0 (num_free_sn_slots=%d)", tgt_dev->num_free_sn_slots); - if (tgt_dev->num_free_sn_slots != ARRAY_SIZE(tgt_dev->sn_slots)) { + if (tgt_dev->num_free_sn_slots < (int)ARRAY_SIZE(tgt_dev->sn_slots)-1) { spin_lock_irq(&tgt_dev->sn_lock); - if (tgt_dev->num_free_sn_slots != ARRAY_SIZE(tgt_dev->sn_slots)) { + if (likely(tgt_dev->num_free_sn_slots < (int)ARRAY_SIZE(tgt_dev->sn_slots)-1)) { + if (tgt_dev->num_free_sn_slots < 0) + tgt_dev->cur_sn_slot = slot; + smp_mb(); /* to be in-sync with SIMPLE case in scst_cmd_set_sn() */ tgt_dev->num_free_sn_slots++; TRACE_SN("Incremented num_free_sn_slots (%d)", tgt_dev->num_free_sn_slots); - if (tgt_dev->num_free_sn_slots == 0) - tgt_dev->cur_sn_slot = slot; + } spin_unlock_irq(&tgt_dev->sn_lock); } @@ -2615,7 +2617,8 @@ tgt_dev->prev_cmd_ordered = 0; } else { - TRACE(TRACE_MINOR, "%s", "Not enough SN slots"); + TRACE(TRACE_MINOR, "***WARNING*** Not enough SN slots " + "%d", ARRAY_SIZE(tgt_dev->sn_slots)); goto ordered; } break; @@ -2626,21 +2629,30 @@ ordered: if (!tgt_dev->prev_cmd_ordered) { spin_lock_irqsave(&tgt_dev->sn_lock, flags); - tgt_dev->num_free_sn_slots--; - smp_mb(); - if ((tgt_dev->num_free_sn_slots >= 0) && - (atomic_read(tgt_dev->cur_sn_slot) > 0)) { - do { - tgt_dev->cur_sn_slot++; - if (tgt_dev->cur_sn_slot == - tgt_dev->sn_slots + - ARRAY_SIZE(tgt_dev->sn_slots)) - tgt_dev->cur_sn_slot = tgt_dev->sn_slots; - } while(atomic_read(tgt_dev->cur_sn_slot) != 0); - TRACE_SN("New cur SN slot %zd", - tgt_dev->cur_sn_slot-tgt_dev->sn_slots); - } else - tgt_dev->num_free_sn_slots++; + if (tgt_dev->num_free_sn_slots >= 0) { + tgt_dev->num_free_sn_slots--; + if (tgt_dev->num_free_sn_slots >= 0) { + int i = 0; + /* + * Commands can finish in any order, so we don't + * know, which slot is empty. + */ + while(1) { + tgt_dev->cur_sn_slot++; + if (tgt_dev->cur_sn_slot == tgt_dev->sn_slots + + ARRAY_SIZE(tgt_dev->sn_slots)) + tgt_dev->cur_sn_slot = tgt_dev->sn_slots; + + if (atomic_read(tgt_dev->cur_sn_slot) == 0) + break; + + i++; + sBUG_ON(i == ARRAY_SIZE(tgt_dev->sn_slots)); + } + TRACE_SN("New cur SN slot %zd", + tgt_dev->cur_sn_slot-tgt_dev->sn_slots); + } + } spin_unlock_irqrestore(&tgt_dev->sn_lock, flags); } tgt_dev->prev_cmd_ordered = 1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-11 18:09:40
|
Revision: 244 http://scst.svn.sourceforge.net/scst/?rev=244&view=rev Author: vlnb Date: 2008-01-11 10:09:38 -0800 (Fri, 11 Jan 2008) Log Message: ----------- Logging improvements Modified Paths: -------------- trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c trunk/usr/fileio/debug.h Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-11 18:09:38 UTC (rev 244) @@ -998,7 +998,7 @@ req->r2t_length = 0; } - TRACE(TRACE_D_WRITE, "%x %u %u %u %u", cmnd_itt(req), + TRACE_WRITE("%x %u %u %u %u", 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); @@ -1353,7 +1353,7 @@ goto out; } - TRACE(TRACE_D_WRITE, "%u %p %p %u %u", req_hdr->ttt, cmnd, req, + TRACE_WRITE("%u %p %p %u %u", req_hdr->ttt, cmnd, req, offset, cmnd->pdu.datasize); res = cmnd_prepare_recv_pdu(conn, req, offset, cmnd->pdu.datasize); Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-01-11 18:09:38 UTC (rev 244) @@ -54,53 +54,22 @@ #if defined(DEBUG) || defined(TRACING) extern unsigned long iscsi_trace_flag; #define trace_flag iscsi_trace_flag +#endif -#define TRACE_CONN_CLOSE(format, args...) \ -do { \ - if (trace_flag & TRACE_CONN_OC) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ -} while(0) +#ifdef DEBUG -#define TRACE_CONN_CLOSE_DBG(format, args...) \ -do { \ - if (trace_flag & TRACE_CONN_OC_DBG) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ -} while(0) +#define TRACE_CONN_CLOSE(args...) TRACE(TRACE_CONN_OC, args) +#define TRACE_CONN_CLOSE_DBG(args...) TRACE(TRACE_CONN_OC_DBG, args) +#define TRACE_NET_PAGE(args...) TRACE(TRACE_NET_PG, args) +#define TRACE_WRITE(args...) TRACE(TRACE_D_WRITE, args) +#define TRACE_READ(args...) TRACE(TRACE_D_READ, args) -#define TRACE_NET_PAGE(format, args...) \ -do { \ - if (trace_flag & TRACE_NET_PG) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ -} while(0) - -#else /* defined(DEBUG) || defined(TRACING) */ +#else /* DEBUG */ #define TRACE_CONN_CLOSE(format, args...) {} #define TRACE_CONN_CLOSE_DBG(format, args...) {} #define TRACE_NET_PAGE(format, args...) {} +#define TRACE_WRITE(args...) {} +#define TRACE_READ(args...) {} #endif #endif Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/iscsi-scst/kernel/nthread.c 2008-01-11 18:09:38 UTC (rev 244) @@ -773,8 +773,8 @@ set_fs(KERNEL_DS); res = vfs_writev(file, (struct iovec __user *)iop, count, &off); set_fs(oldfs); - TRACE(TRACE_D_WRITE, "%#Lx:%u: %d(%ld)", - (unsigned long long) conn->session->sid, conn->cid, + TRACE_WRITE("%#Lx:%u: %d(%ld)", + (unsigned long long)conn->session->sid, conn->cid, res, (long) iop->iov_len); if (unlikely(res <= 0)) { if (res == -EAGAIN) { @@ -845,7 +845,7 @@ if (size <= sendsize) { retry2: res = sendpage(sock, sg[idx].page, offset, size, flags); - TRACE(TRACE_D_WRITE, "%s %#Lx:%u: %d(%lu,%u,%u)", + TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long)conn->session->sid, conn->cid, res, sg[idx].page->index, offset, size); @@ -868,7 +868,7 @@ retry1: res = sendpage(sock, sg[idx].page, offset, sendsize, flags | MSG_MORE); - TRACE(TRACE_D_WRITE, "%s %#Lx:%u: %d(%lu,%u,%u)", + TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", (unsigned long long ) conn->session->sid, conn->cid, res, sg[idx].page->index, offset, sendsize); Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-01-11 18:09:38 UTC (rev 244) @@ -545,7 +545,7 @@ prm->pkt->dseg_count = cpu_to_le16(prm->seg_cnt); /* If scatter gather */ - TRACE(TRACE_SG, "%s", "Building S/G data segments..."); + TRACE_SG("%s", "Building S/G data segments..."); /* Load command entry data segments */ for (cnt = 0; (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt; @@ -560,7 +560,7 @@ } *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); - TRACE(TRACE_SG, "S/G Segment phys_addr=%llx:%llx, len=%d", + TRACE_SG("S/G Segment phys_addr=%llx:%llx, len=%d", (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)), (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)), (int)sg_dma_len(prm->sg)); @@ -615,9 +615,7 @@ } *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); - TRACE(TRACE_SG, - "S/G Segment Cont. phys_addr=%llx:%llx, " - "len=%d", + TRACE_SG("S/G Segment Cont. phys_addr=%llx:%llx, len=%d", (long long unsigned int)pci_dma_hi32(sg_dma_address(prm->sg)), (long long unsigned int)pci_dma_lo32(sg_dma_address(prm->sg)), (int)sg_dma_len(prm->sg)); @@ -1781,7 +1779,7 @@ le16_to_cpu(atio->status)); break; } - TRACE_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb, + PRINT_BUFF_FLAG(TRACE_SCSI, "CDB", atio->cdb, sizeof(atio->cdb)); rc = q2t_send_cmd_to_scst(ha, atio); if (unlikely(rc != 0)) { Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/include/scst_debug.h 2008-01-11 18:09:38 UTC (rev 244) @@ -112,7 +112,7 @@ #define TRACE_ENTRYEXIT 0x00000010 #define TRACE_BUFF 0x00000020 #define TRACE_MEMORY 0x00000040 -#define TRACE_SG 0x00000080 +#define TRACE_SG_OP 0x00000080 #define TRACE_OUT_OF_MEM 0x00000100 #define TRACE_MINOR 0x00000200 /* less important events */ #define TRACE_MGMT 0x00000400 @@ -134,13 +134,19 @@ #if defined(DEBUG) || defined(TRACING) +#ifndef DEBUG +#define ___unlikely(a) (a) +#else +#define ___unlikely(a) unlikely(a) +#endif + extern int debug_print_prefix(unsigned long trace_flag, const char *prefix, const char *func, int line); extern void debug_print_buffer(const void *data, int len); #define TRACE(trace, format, args...) \ do { \ - if (trace_flag & (trace)) \ + if (___unlikely(trace_flag & (trace))) \ { \ char *__tflag = LOG_FLAG; \ if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ @@ -152,24 +158,15 @@ } \ } while(0) -#define TRACE_BUFFER(message, buff, len) \ +#define PRINT_BUFFER(message, buff, len) \ do { \ - if (trace_flag & TRACE_BUFF) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ - } \ + PRINT(NO_FLAG, "%s:", message); \ + debug_print_buffer(buff, len); \ } while(0) -#define TRACE_BUFF_FLAG(flag, message, buff, len) \ +#define PRINT_BUFF_FLAG(flag, message, buff, len) \ do { \ - if (trace_flag & (flag)) \ + if (___unlikely(trace_flag & (flag))) \ { \ char *__tflag = LOG_FLAG; \ if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ @@ -182,26 +179,19 @@ } \ } while(0) -#define PRINT_BUFFER(message, buff, len) \ -do { \ - PRINT(NO_FLAG, "%s:", message); \ - debug_print_buffer(buff, len); \ -} while(0) - #else /* DEBUG || TRACING */ #define TRACE(trace, args...) {} -#define TRACE_BUFFER(message, buff, len) {} -#define TRACE_BUFF_FLAG(flag, message, buff, len) {} #define PRINT_BUFFER(message, buff, len) {} +#define PRINT_BUFF_FLAG(flag, message, buff, len) {} #endif /* DEBUG || TRACING */ #ifdef DEBUG -#define TRACE_MEM(format, args...) \ +#define __TRACE(trace, format, args...) \ do { \ - if (trace_flag & TRACE_MEMORY) \ + if (trace_flag & (trace)) \ { \ char *__tflag = LOG_FLAG; \ if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ @@ -213,23 +203,16 @@ } \ } while(0) -#define TRACE_DBG(format, args...) \ -do { \ - if (trace_flag & TRACE_DEBUG) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ -} while(0) +#define TRACE_MEM(args...) __TRACE(TRACE_MEMORY, args) +#define TRACE_SG(args...) __TRACE(TRACE_SG_OP, args) +#define TRACE_DBG(args...) __TRACE(TRACE_DEBUG, args) +#define TRACE_DBG_SPECIAL(args...) __TRACE((TRACE_DEBUG|TRACE_SPECIAL, args) +#define TRACE_MGMT_DBG(args...) __TRACE(TRACE_MGMT_DEBUG, args) +#define TRACE_MGMT_DBG_SPECIAL(args...) __TRACE(TRACE_MGMT_DEBUG|TRACE_SPECIAL, args) -#define TRACE_DBG_SPECIAL(format, args...) \ +#define TRACE_BUFFER(message, buff, len) \ do { \ - if (trace_flag & (TRACE_DEBUG|TRACE_SPECIAL)) \ + if (trace_flag & TRACE_BUFF) \ { \ char *__tflag = LOG_FLAG; \ if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ @@ -237,13 +220,14 @@ { \ __tflag = NO_FLAG; \ } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ + PRINT(NO_FLAG, "%s%s:", __tflag, message); \ + debug_print_buffer(buff, len); \ } \ } while(0) -#define TRACE_MGMT_DBG(format, args...) \ +#define TRACE_BUFF_FLAG(flag, message, buff, len) \ do { \ - if (trace_flag & TRACE_MGMT_DEBUG) \ + if (trace_flag & (flag)) \ { \ char *__tflag = LOG_FLAG; \ if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ @@ -251,24 +235,11 @@ { \ __tflag = NO_FLAG; \ } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ + PRINT(NO_FLAG, "%s%s:", __tflag, message); \ + debug_print_buffer(buff, len); \ } \ } while(0) -#define TRACE_MGMT_DBG_SPECIAL(format, args...) \ -do { \ - if (trace_flag & (TRACE_MGMT_DEBUG|TRACE_SPECIAL)) \ - { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ - __LINE__) > 0) \ - { \ - __tflag = NO_FLAG; \ - } \ - PRINT(NO_FLAG, "%s" format, __tflag, args); \ - } \ -} while(0) - #define PRINT_LOG_FLAG(log_flag, format, args...) \ do { \ char *__tflag = log_flag; \ @@ -365,10 +336,13 @@ #else /* DEBUG */ #define TRACE_MEM(format, args...) {} +#define TRACE_SG(format, args...) {} #define TRACE_DBG(format, args...) {} #define TRACE_DBG_SPECIAL(format, args...) {} #define TRACE_MGMT_DBG(format, args...) {} #define TRACE_MGMT_DBG_SPECIAL(format, args...) {} +#define TRACE_BUFFER(message, buff, len) {} +#define TRACE_BUFF_FLAG(flag, message, buff, len) {} #define TRACE_ENTRY() {} #define TRACE_EXIT() {} #define TRACE_EXIT_RES(res) {} Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-11 18:09:38 UTC (rev 244) @@ -43,15 +43,17 @@ #include "scsi_tgt.h" +#if defined(DEBUG) || defined(TRACING) + #define TRACE_ORDER 0x80000000 -#if defined(DEBUG) || defined(TRACING) static struct scst_proc_log vdisk_proc_local_trace_tbl[] = { { TRACE_ORDER, "order" }, { 0, NULL } }; #define trace_log_tbl vdisk_proc_local_trace_tbl + #endif #include "scst_dev_handler.h" Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/src/scst_lib.c 2008-01-11 18:09:38 UTC (rev 244) @@ -141,10 +141,12 @@ l += cmd->sg[i].length; if (l >= resp_data_len) { int left = resp_data_len - (l - cmd->sg[i].length); - TRACE(TRACE_SG|TRACE_MEMORY, "cmd %p (tag %llu), " +#ifdef DEBUG + TRACE(TRACE_SG_OP|TRACE_MEMORY, "cmd %p (tag %llu), " "resp_data_len %d, i %d, cmd->sg[i].length %d, " "left %d", cmd, cmd->tag, resp_data_len, i, cmd->sg[i].length, left); +#endif cmd->orig_sg_cnt = cmd->sg_cnt; cmd->orig_sg_entry = i; cmd->orig_entry_len = cmd->sg[i].length; @@ -919,7 +921,7 @@ if (scsi_status_is_good(cmd->status) && (len > 0) && SCST_SENSE_VALID(buf) && (!SCST_NO_SENSE(buf))) { - TRACE_BUFF_FLAG(TRACE_SCSI, "REQUEST SENSE returned", + PRINT_BUFF_FLAG(TRACE_SCSI, "REQUEST SENSE returned", buf, len); memcpy(orig_cmd->sense_buffer, buf, ((int)sizeof(orig_cmd->sense_buffer) > len) ? @@ -1039,7 +1041,7 @@ break; } else { PRINT_ERROR("RELEASE failed: %d", rc); - TRACE_BUFFER("RELEASE sense", sense, + PRINT_BUFFER("RELEASE sense", sense, SCST_SENSE_BUFFERSIZE); scst_check_internal_sense(tgt_dev->dev, rc, sense, SCST_SENSE_BUFFERSIZE); @@ -1363,7 +1365,7 @@ struct scst_cmd *c, *tc; unsigned long flags; - TRACE(TRACE_RETRY, "Checking retry cmd list (retry_cmds %d)", + TRACE_RETRY("Checking retry cmd list (retry_cmds %d)", tgt->retry_cmds); spin_lock_irqsave(&tgt->tgt_lock, flags); @@ -1372,7 +1374,7 @@ { tgt->retry_cmds--; - TRACE(TRACE_RETRY, "Moving retry cmd %p to head of active " + TRACE_RETRY("Moving retry cmd %p to head of active " "cmd list (retry_cmds left %d)", c, tgt->retry_cmds); spin_lock(&c->cmd_lists->cmd_list_lock); list_move(&c->cmd_list_entry, &c->cmd_lists->active_cmd_list); @@ -1395,8 +1397,7 @@ struct scst_tgt *tgt = (struct scst_tgt*)arg; unsigned long flags; - TRACE(TRACE_RETRY, "Retry timer expired (retry_cmds %d)", - tgt->retry_cmds); + TRACE_RETRY("Retry timer expired (retry_cmds %d)", tgt->retry_cmds); spin_lock_irqsave(&tgt->tgt_lock, flags); tgt->retry_timer_active = 0; @@ -2127,7 +2128,7 @@ else sh = 0; set_block_shift(cmd, sh); - TRACE(TRACE_SCSI, "block_shift %d", sh); + TRACE_DBG("block_shift %d", sh); break; } default: @@ -2250,7 +2251,7 @@ memset(buffer, 0, sizeof(buffer)); memset(sense_buffer, 0, sizeof(sense_buffer)); - TRACE_DBG("%s", "Doing MODE_SENSE"); + TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE"); res = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer, sizeof(buffer), sense_buffer, SCST_DEFAULT_TIMEOUT, 0, GFP_KERNEL); @@ -2260,8 +2261,8 @@ if (scsi_status_is_good(res)) { int q; - TRACE_BUFFER("Returned control mode page data", buffer, - sizeof(buffer)); + PRINT_BUFF_FLAG(TRACE_SCSI, "Returned control mode page data", + buffer, sizeof(buffer)); dev->tst = buffer[4+2] >> 5; q = buffer[4+3] >> 4; @@ -2282,7 +2283,7 @@ */ dev->has_own_order_mgmt = !dev->queue_alg; - TRACE(TRACE_MGMT_MINOR, "Device %d:%d:%d:%d: TST %x, " + TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d: TST %x, " "QUEUE ALG %x, SWP %x, TAS %x, has_own_order_mgmt " "%d", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, @@ -2294,7 +2295,7 @@ if ((status_byte(res) == CHECK_CONDITION) && SCST_SENSE_VALID(sense_buffer) && (sense_buffer[2] == ILLEGAL_REQUEST)) { - TRACE(TRACE_MGMT_MINOR, "Device %d:%d:%d:%d " + TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d " "doesn't support control mode page, using " "defaults: TST %x, QUEUE ALG %x, SWP %x, " "TAS %x, has_own_order_mgmt %d", @@ -2305,13 +2306,13 @@ res = 0; goto out; } else { - TRACE(TRACE_MGMT_MINOR, "Internal MODE SENSE to " + TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Internal MODE SENSE to " "device %d:%d:%d:%d failed: %x", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, dev->scsi_dev->lun, res); - TRACE_BUFF_FLAG(TRACE_MGMT_MINOR, "MODE SENSE sense", - sense_buffer, sizeof(sense_buffer)); + PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_MGMT_MINOR, "MODE SENSE " + "sense", sense_buffer, sizeof(sense_buffer)); } scst_check_internal_sense(dev, res, sense_buffer, sizeof(sense_buffer)); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/src/scst_priv.h 2008-01-11 18:09:38 UTC (rev 244) @@ -36,12 +36,12 @@ #define SCST_MAJOR 177 -#define TRACE_RETRY 0x80000000 +#define TRACE_RTRY 0x80000000 #define TRACE_SCSI_SERIALIZING 0x40000000 -#define TRACE_SEND_TOP 0x20000000 /** top being the edge away from the interupt */ -#define TRACE_RECV_TOP 0x01000000 -#define TRACE_SEND_BOT 0x08000000 /** bottom being the edge toward the interupt */ -#define TRACE_RECV_BOT 0x04000000 +#define TRACE_SND_TOP 0x20000000 /** top being the edge away from the interupt */ +#define TRACE_RCV_TOP 0x01000000 +#define TRACE_SND_BOT 0x08000000 /** bottom being the edge toward the interupt */ +#define TRACE_RCV_BOT 0x04000000 #if defined(DEBUG) || defined(TRACING) #define trace_flag scst_trace_flag @@ -56,9 +56,14 @@ */ #define SCST_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MINOR | TRACE_PID | \ TRACE_LINE | TRACE_FUNCTION | TRACE_SPECIAL | TRACE_MGMT | \ - TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | TRACE_RETRY) + TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | TRACE_RTRY) -#define TRACE_SN(args...) TRACE(TRACE_SCSI_SERIALIZING, args) +#define TRACE_RETRY(args...) __TRACE(TRACE_RTRY, args) +#define TRACE_SN(args...) __TRACE(TRACE_SCSI_SERIALIZING, args) +#define TRACE_SEND_TOP(args...) __TRACE(TRACE_SND_TOP, args) +#define TRACE_RECV_TOP(args...) __TRACE(TRACE_RCV_TOP, args) +#define TRACE_SEND_BOT(args...) __TRACE(TRACE_SND_BOT, args) +#define TRACE_RECV_BOT(args...) __TRACE(TRACE_RCV_BOT, args) #else /* DEBUG */ @@ -68,7 +73,12 @@ #define SCST_DEFAULT_LOG_FLAGS 0 # endif +#define TRACE_RETRY(args...) #define TRACE_SN(args...) +#define TRACE_SEND_TOP(args...) +#define TRACE_RECV_TOP(args...) +#define TRACE_SEND_BOT(args...) +#define TRACE_RECV_BOT(args...) #endif Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/src/scst_proc.c 2008-01-11 18:09:38 UTC (rev 244) @@ -90,7 +90,7 @@ { { TRACE_OUT_OF_MEM, "out_of_mem" }, { TRACE_MINOR, "minor" }, - { TRACE_SG, "sg" }, + { TRACE_SG_OP, "sg" }, { TRACE_MEMORY, "mem" }, { TRACE_BUFF, "buff" }, { TRACE_ENTRYEXIT, "entryexit" }, @@ -108,12 +108,12 @@ static struct scst_proc_log scst_proc_local_trace_tbl[] = { - { TRACE_RETRY, "retry" }, + { TRACE_RTRY, "retry" }, { TRACE_SCSI_SERIALIZING, "scsi_serializing" }, - { TRACE_RECV_BOT, "recv_bot" }, - { TRACE_SEND_BOT, "send_bot" }, - { TRACE_RECV_TOP, "recv_top" }, - { TRACE_SEND_TOP, "send_top" }, + { TRACE_RCV_BOT, "recv_bot" }, + { TRACE_SND_BOT, "send_bot" }, + { TRACE_RCV_TOP, "recv_top" }, + { TRACE_SND_TOP, "send_top" }, { 0, NULL } }; #endif Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/scst/src/scst_targ.c 2008-01-11 18:09:38 UTC (rev 244) @@ -172,7 +172,7 @@ TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd); TRACE(TRACE_SCSI, "tag=%llu, lun=%Ld, CDB len=%d", cmd->tag, (uint64_t)cmd->lun, cmd->cdb_len); - TRACE_BUFF_FLAG(TRACE_SCSI|TRACE_RECV_BOT, "Recieving CDB", + PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_RCV_BOT, "Recieving CDB", cmd->cdb, cmd->cdb_len); #ifdef EXTRACHECKS @@ -410,7 +410,7 @@ if (likely(!scst_is_cmd_local(cmd))) { TRACE_DBG("Calling dev handler %s parse(%p)", dev->handler->name, cmd); - TRACE_BUFF_FLAG(TRACE_SEND_BOT, "Parsing: ", cmd->cdb, cmd->cdb_len); + TRACE_BUFF_FLAG(TRACE_SND_BOT, "Parsing: ", cmd->cdb, cmd->cdb_len); state = dev->handler->parse(cmd); /* Caution: cmd can be already dead here */ TRACE_DBG("Dev handler %s parse() returned %d", @@ -759,12 +759,12 @@ spin_lock_irqsave(&tgt->tgt_lock, flags); tgt->retry_cmds++; smp_mb(); - TRACE(TRACE_RETRY, "TGT QUEUE FULL: incrementing retry_cmds %d", + TRACE_RETRY("TGT QUEUE FULL: incrementing retry_cmds %d", tgt->retry_cmds); if (finished_cmds != atomic_read(&tgt->finished_cmds)) { /* At least one cmd finished, so try again */ tgt->retry_cmds--; - TRACE(TRACE_RETRY, "Some command(s) finished, direct retry " + TRACE_RETRY("Some command(s) finished, direct retry " "(finished_cmds=%d, tgt->finished_cmds=%d, " "retry_cmds=%d)", finished_cmds, atomic_read(&tgt->finished_cmds), tgt->retry_cmds); @@ -772,7 +772,7 @@ goto out_unlock_tgt; } - TRACE(TRACE_RETRY, "Adding cmd %p to retry cmd list", cmd); + TRACE_RETRY("Adding cmd %p to retry cmd list", cmd); list_add_tail(&cmd->cmd_list_entry, &tgt->retry_cmd_list); if (!tgt->retry_timer_active) { @@ -1157,16 +1157,15 @@ if (next_state == SCST_CMD_STATE_DEFAULT) next_state = SCST_CMD_STATE_PRE_DEV_DONE; -#if defined(DEBUG) || defined(TRACING) +#if defined(DEBUG) if (next_state == SCST_CMD_STATE_PRE_DEV_DONE) { if (cmd->sg) { int i; struct scatterlist *sg = cmd->sg; - TRACE(TRACE_RECV_TOP, - "Exec'd %d S/G(s) at %p sg[0].page at %p", - cmd->sg_cnt, sg, (void*)sg[0].page); + TRACE_RECV_TOP("Exec'd %d S/G(s) at %p sg[0].page at " + "%p", cmd->sg_cnt, sg, (void*)sg[0].page); for(i = 0; i < cmd->sg_cnt; ++i) { - TRACE_BUFF_FLAG(TRACE_RECV_TOP, + TRACE_BUFF_FLAG(TRACE_RCV_TOP, "Exec'd sg", page_address(sg[i].page), sg[i].length); } @@ -1664,7 +1663,7 @@ struct scst_device *dev = cmd->dev; TRACE_DBG("Calling dev handler %s exec(%p)", dev->handler->name, cmd); - TRACE_BUFF_FLAG(TRACE_SEND_TOP, "Execing: ", cmd->cdb, cmd->cdb_len); + TRACE_BUFF_FLAG(TRACE_SND_TOP, "Execing: ", cmd->cdb, cmd->cdb_len); cmd->scst_cmd_done = scst_cmd_done_local; rc = dev->handler->exec(cmd); /* !! At this point cmd, sess & tgt_dev can be already freed !! */ @@ -1955,7 +1954,7 @@ if (unlikely(cmd->status == SAM_STAT_CHECK_CONDITION) && SCST_SENSE_VALID(cmd->sense_buffer)) { - TRACE_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer, + PRINT_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer, sizeof(cmd->sense_buffer)); /* Check Unit Attention Sense Key */ if (scst_is_ua_sense(cmd->sense_buffer)) { @@ -2153,8 +2152,8 @@ TRACE(TRACE_SCSI, "Real RESERVE failed lun=%Ld, status=%x", (uint64_t)cmd->lun, cmd->status); - TRACE_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer, - sizeof(cmd->sense_buffer)); + PRINT_BUFF_FLAG(TRACE_SCSI, "Sense", cmd->sense_buffer, + sizeof(cmd->sense_buffer)); /* Clearing the reservation */ spin_lock_bh(&dev->dev_lock); @@ -2461,15 +2460,14 @@ TRACE_DBG("Calling xmit_response(%p)", cmd); -#if defined(DEBUG) || defined(TRACING) +#if defined(DEBUG) if (cmd->sg) { int i; struct scatterlist *sg = cmd->sg; - TRACE(TRACE_SEND_BOT, - "Xmitting %d S/G(s) at %p sg[0].page at %p", + TRACE_SEND_BOT("Xmitting %d S/G(s) at %p sg[0].page at %p", cmd->sg_cnt, sg, (void*)sg[0].page); for(i = 0; i < cmd->sg_cnt; ++i) { - TRACE_BUFF_FLAG(TRACE_SEND_BOT, + TRACE_BUFF_FLAG(TRACE_SND_BOT, "Xmitting sg", page_address(sg[i].page), sg[i].length); } Modified: trunk/usr/fileio/debug.h =================================================================== --- trunk/usr/fileio/debug.h 2008-01-11 10:03:48 UTC (rev 243) +++ trunk/usr/fileio/debug.h 2008-01-11 18:09:38 UTC (rev 244) @@ -88,28 +88,6 @@ } \ } while(0) -#define TRACE_BUFFER(message, buff, len) \ -do { \ - if (trace_flag & TRACE_BUFF) \ - { \ - debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ - __LINE__); \ - PRINT("%s:", message); \ - debug_print_buffer(buff, len); \ - } \ -} while(0) - -#define TRACE_BUFF_FLAG(flag, message, buff, len) \ -do { \ - if (trace_flag & (flag)) \ - { \ - debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ - __LINE__); \ - PRINT("%s:", message); \ - debug_print_buffer(buff, len); \ - } \ -} while(0) - #define PRINT_BUFFER(message, buff, len) \ do { \ PRINT("%s:", message); \ @@ -119,8 +97,6 @@ #else /* DEBUG || TRACING */ #define TRACE(trace, args...) {} -#define TRACE_BUFFER(message, buff, len) {} -#define TRACE_BUFF_FLAG(flag, message, buff, len) {} #define PRINT_BUFFER(message, buff, len) {} static inline int debug_init(void) { return 0; } @@ -162,6 +138,28 @@ } \ } while(0) +#define TRACE_BUFFER(message, buff, len) \ +do { \ + if (trace_flag & TRACE_BUFF) \ + { \ + debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + __LINE__); \ + PRINT("%s:", message); \ + debug_print_buffer(buff, len); \ + } \ +} while(0) + +#define TRACE_BUFF_FLAG(flag, message, buff, len) \ +do { \ + if (trace_flag & (flag)) \ + { \ + debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + __LINE__); \ + PRINT("%s:", message); \ + debug_print_buffer(buff, len); \ + } \ +} while(0) + #define PRINT_ERROR(format, args...) \ do { \ debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ @@ -248,6 +246,8 @@ #define TRACE_MEM(format, args...) {} #define TRACE_DBG(format, args...) {} #define TRACE_MGMT_DBG(format, args...) {} +#define TRACE_BUFFER(message, buff, len) {} +#define TRACE_BUFF_FLAG(flag, message, buff, len) {} #define TRACE_ENTRY() {} #define TRACE_EXIT() {} #define TRACE_EXIT_RES(res) {} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-14 18:21:06
|
Revision: 245 http://scst.svn.sourceforge.net/scst/?rev=245&view=rev Author: vlnb Date: 2008-01-14 10:21:01 -0800 (Mon, 14 Jan 2008) Log Message: ----------- - Processing latency measurement facility added - README updated - Minor fixes Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_debug.h trunk/scst/src/Makefile trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/iscsi-scst/kernel/conn.c 2008-01-14 18:21:01 UTC (rev 245) @@ -402,7 +402,7 @@ local_bh_enable(); printk(KERN_EMERG "conn %p rd_task != current %p (pid %d)\n", conn, current, current->pid); - printk(KERN_EMERG "wr_state %x\n", conn->rd_state); + printk(KERN_EMERG "rd_state %x\n", conn->rd_state); printk(KERN_EMERG "rd_task %p\n", conn->rd_task); printk(KERN_EMERG "rd_task->pid %d\n", conn->rd_task->pid); sBUG(); Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/README 2008-01-14 18:21:01 UTC (rev 245) @@ -267,6 +267,10 @@ Then sometimes get crazy itself. So, this option is disabled by default. + - MEASURE_LATENCY - if defined, provides in /proc/scsi_tgt/latency file + average commands processing latency. You can clear already measured + results by writing 0 in this file. + HIGHMEM kernel configurations are fully supported, but not recommended for performance reasons, except for scst_user, where they are not supported, because this module deals with user supplied memory on a Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/include/scsi_tgt.h 2008-01-14 18:21:01 UTC (rev 245) @@ -946,6 +946,12 @@ void (*init_result_fn) (struct scst_session *sess, void *data, int result); void (*unreg_done_fn) (struct scst_session *sess); + +#ifdef MEASURE_LATENCY + spinlock_t meas_lock; + uint64_t processing_time; + int processed_cmds; +#endif }; struct scst_cmd_lists @@ -1201,6 +1207,10 @@ struct list_head blocked_cmd_list_entry; struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */ + +#ifdef MEASURE_LATENCY + uint64_t start, pre_exec_finish, post_exec_start; +#endif }; struct scst_rx_mgmt_params Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/include/scst_debug.h 2008-01-14 18:21:01 UTC (rev 245) @@ -206,7 +206,7 @@ #define TRACE_MEM(args...) __TRACE(TRACE_MEMORY, args) #define TRACE_SG(args...) __TRACE(TRACE_SG_OP, args) #define TRACE_DBG(args...) __TRACE(TRACE_DEBUG, args) -#define TRACE_DBG_SPECIAL(args...) __TRACE((TRACE_DEBUG|TRACE_SPECIAL, args) +#define TRACE_DBG_SPECIAL(args...) __TRACE(TRACE_DEBUG|TRACE_SPECIAL, args) #define TRACE_MGMT_DBG(args...) __TRACE(TRACE_MGMT_DEBUG, args) #define TRACE_MGMT_DBG_SPECIAL(args...) __TRACE(TRACE_MGMT_DEBUG|TRACE_SPECIAL, args) Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/src/Makefile 2008-01-14 18:21:01 UTC (rev 245) @@ -130,6 +130,8 @@ #EXTRA_CFLAGS += -DDEBUG_OOM #EXTRA_CFLAGS += -DDEBUG_SN +#EXTRA_CFLAGS += -DMEASURE_LATENCY + # If defined, makes SCST zero allocated data buffers. # Undefining it considerably improves performance and eases CPU load, # but could create a security hole (information leakage), so Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-14 18:21:01 UTC (rev 245) @@ -1007,6 +1007,7 @@ ********************************************************************/ static int vcdrom_exec(struct scst_cmd *cmd) { + int res = SCST_EXEC_COMPLETED; int opcode = cmd->cdb[0]; struct scst_vdisk_dev *virt_dev = (struct scst_vdisk_dev *)cmd->dev->dh_priv; @@ -1039,11 +1040,11 @@ spin_unlock(&virt_dev->flags_lock); } - vdisk_do_job(cmd); + res = vdisk_do_job(cmd); out: - TRACE_EXIT(); - return SCST_EXEC_COMPLETED; + TRACE_EXIT_RES(res); + return res; out_done: cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/src/scst_lib.c 2008-01-14 18:21:01 UTC (rev 245) @@ -1123,6 +1123,10 @@ INIT_LIST_HEAD(&sess->init_deferred_cmd_list); INIT_LIST_HEAD(&sess->init_deferred_mcmd_list); +#ifdef MEASURE_LATENCY + spin_lock_init(&sess->meas_lock); +#endif + len = strlen(initiator_name); nm = kmalloc(len + 1, gfp_mask); if (nm == NULL) { Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/src/scst_proc.c 2008-01-14 18:21:01 UTC (rev 245) @@ -68,6 +68,10 @@ #define SCST_PROC_GROUPS_DEVICES_ENTRY_NAME "devices" #define SCST_PROC_GROUPS_USERS_ENTRY_NAME "names" +#ifdef MEASURE_LATENCY +#define SCST_PROC_LAT_ENTRY_NAME "latency" +#endif + #define SCST_PROC_ACTION_ALL 1 #define SCST_PROC_ACTION_NONE 2 #define SCST_PROC_ACTION_DEFAULT 3 @@ -376,14 +380,118 @@ #endif /* defined(DEBUG) || defined(TRACING) */ +#ifdef MEASURE_LATENCY + +static int lat_info_show(struct seq_file *seq, void *v) +{ + int res = 0; + struct scst_acg *acg; + struct scst_session *sess; + + TRACE_ENTRY(); + + if (mutex_lock_interruptible(&scst_mutex) != 0) { + res = -EINTR; + goto out; + } + + seq_printf(seq, "%-20s %-45s %-35s\n", "Target name", "Initiator name", + "Processing latency (us)"); + + list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) { + list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { + unsigned long lat = 0; + uint64_t processing_time; + uint64_t processed_cmds; + + spin_lock_bh(&sess->meas_lock); + processing_time = sess->processing_time; + processed_cmds = sess->processed_cmds; + spin_unlock_bh(&sess->meas_lock); + + TRACE_DBG("sess %p, processing_time %Ld, " + "processed_cmds %Ld", sess, processing_time, + processed_cmds); + +#if BITS_PER_LONG == 32 + while((processing_time & 0xFFFFFFFF00000000LL) != 0) { + TRACE_DBG("Processing time too big (" + "processing_time %Ld, processed_cmds %Ld", + processing_time, processed_cmds); + processing_time >>= 1; + processed_cmds >>= 1; + } +#endif + + if (sess->processed_cmds != 0) { + lat = (unsigned long)processing_time / + (unsigned long)processed_cmds; + } + + seq_printf(seq, "%-20s %-45s %-15ld\n", + sess->tgt->tgtt->name, + sess->initiator_name, + lat); + } + } + + mutex_unlock(&scst_mutex); + +out: + TRACE_EXIT_RES(res); + return res; +} + +static ssize_t scst_proc_scsi_tgt_gen_write_lat(struct file *file, const char __user *buf, + size_t length, loff_t *off) +{ + int res = length; + struct scst_acg *acg; + struct scst_session *sess; + + TRACE_ENTRY(); + + if (mutex_lock_interruptible(&scst_mutex) != 0) { + res = -EINTR; + goto out; + } + + list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) { + list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { + PRINT_INFO("Zeroing latency statistics for initiator %s", + sess->initiator_name); + spin_lock_bh(&sess->meas_lock); + sess->processing_time = 0; + sess->processed_cmds = 0; + spin_unlock_bh(&sess->meas_lock); + } + } + + mutex_unlock(&scst_mutex); + +out: + TRACE_EXIT_RES(res); + return res; +} + +static struct scst_proc_data scst_lat_proc_data = { + SCST_DEF_RW_SEQ_OP(scst_proc_scsi_tgt_gen_write_lat) + .show = lat_info_show, + .data = "scsi_tgt", +}; + +#endif /* MEASURE_LATENCY */ + static int __init scst_proc_init_module_log(void) { int res = 0; -#if defined(DEBUG) || defined(TRACING) +#if defined(DEBUG) || defined(TRACING) || defined(MEASURE_LATENCY) struct proc_dir_entry *generic; +#endif TRACE_ENTRY(); +#if defined(DEBUG) || defined(TRACING) generic = scst_create_proc_entry(scst_proc_scsi_tgt, SCST_PROC_LOG_ENTRY_NAME, &scst_log_proc_data); @@ -392,21 +500,39 @@ SCST_PROC_ENTRY_NAME, SCST_PROC_LOG_ENTRY_NAME); res = -ENOMEM; } +#endif +#ifdef MEASURE_LATENCY + if (res == 0) { + generic = scst_create_proc_entry(scst_proc_scsi_tgt, + SCST_PROC_LAT_ENTRY_NAME, + &scst_lat_proc_data); + if (!generic) { + PRINT_ERROR("cannot init /proc/%s/%s", + SCST_PROC_ENTRY_NAME, SCST_PROC_LAT_ENTRY_NAME); + res = -ENOMEM; + } + } +#endif + TRACE_EXIT_RES(res); -#endif return res; } static void __exit scst_proc_cleanup_module_log(void) { -#if defined(DEBUG) || defined(TRACING) TRACE_ENTRY(); +#if defined(DEBUG) || defined(TRACING) remove_proc_entry(SCST_PROC_LOG_ENTRY_NAME, scst_proc_scsi_tgt); +#endif +#ifdef MEASURE_LATENCY + remove_proc_entry(SCST_PROC_LAT_ENTRY_NAME, scst_proc_scsi_tgt); +#endif + TRACE_EXIT(); -#endif + return; } int scst_proc_group_add_tree(struct scst_acg *acg, const char *name) Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-11 18:09:38 UTC (rev 244) +++ trunk/scst/src/scst_targ.c 2008-01-14 18:21:01 UTC (rev 245) @@ -162,6 +162,13 @@ goto out; } +#ifdef MEASURE_LATENCY +static inline uint64_t scst_sec_to_nsec(time_t sec) +{ + return (uint64_t)sec * 1000000000; +} +#endif + void scst_cmd_init_done(struct scst_cmd *cmd, int pref_context) { unsigned long flags; @@ -169,6 +176,17 @@ TRACE_ENTRY(); +#ifdef MEASURE_LATENCY + { + struct timespec ts; + getnstimeofday(&ts); + cmd->start = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; + TRACE_DBG("cmd %p (sess %p): start %Ld (tv_sec %ld, " + "tv_nsec %ld)", cmd, sess, cmd->start, ts.tv_sec, + ts.tv_nsec); + } +#endif + TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd); TRACE(TRACE_SCSI, "tag=%llu, lun=%Ld, CDB len=%d", cmd->tag, (uint64_t)cmd->lun, cmd->cdb_len); @@ -1028,6 +1046,17 @@ { TRACE_ENTRY(); +#ifdef MEASURE_LATENCY + { + struct timespec ts; + getnstimeofday(&ts); + cmd->post_exec_start = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; + TRACE_DBG("cmd %p (sess %p): post_exec_start %Ld (tv_sec %ld, " + "tv_nsec %ld)", cmd, cmd->sess, cmd->post_exec_start, ts.tv_sec, + ts.tv_nsec); + } +#endif + cmd->status = result & 0xff; cmd->msg_status = msg_byte(result); cmd->host_status = host_byte(result); @@ -1154,6 +1183,17 @@ { TRACE_ENTRY(); +#ifdef MEASURE_LATENCY + { + struct timespec ts; + getnstimeofday(&ts); + cmd->post_exec_start = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; + TRACE_DBG("cmd %p (sess %p): post_exec_start %Ld (tv_sec %ld, " + "tv_nsec %ld)", cmd, cmd->sess, cmd->post_exec_start, ts.tv_sec, + ts.tv_nsec); + } +#endif + if (next_state == SCST_CMD_STATE_DEFAULT) next_state = SCST_CMD_STATE_PRE_DEV_DONE; @@ -1829,6 +1869,17 @@ } } +#ifdef MEASURE_LATENCY + if (cmd->pre_exec_finish == 0) { + struct timespec ts; + getnstimeofday(&ts); + cmd->pre_exec_finish = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; + TRACE_DBG("cmd %p (sess %p): pre_exec_finish %Ld (tv_sec %ld, " + "tv_nsec %ld)", cmd, cmd->sess, cmd->pre_exec_finish, ts.tv_sec, + ts.tv_nsec); + } +#endif + if (unlikely(scst_inc_on_dev_cmd(cmd) != 0)) goto out_put; @@ -2421,6 +2472,26 @@ res = SCST_CMD_STATE_RES_CONT_SAME; out: +#ifdef MEASURE_LATENCY + { + struct timespec ts; + uint64_t finish, processing_time; + struct scst_session *sess = cmd->sess; + + getnstimeofday(&ts); + finish = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; + + spin_lock_bh(&sess->meas_lock); + processing_time = cmd->pre_exec_finish - cmd->start; + processing_time += finish - cmd->post_exec_start; + sess->processing_time += processing_time; + sess->processed_cmds++; + TRACE_DBG("cmd %p (sess %p): finish %Ld (tv_sec %ld, " + "tv_nsec %ld), processing_time %Ld", cmd, sess, finish, + ts.tv_sec, ts.tv_nsec, processing_time); + spin_unlock_bh(&sess->meas_lock); + } +#endif TRACE_EXIT_HRES(res); return res; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-18 19:13:11
|
Revision: 246 http://scst.svn.sourceforge.net/scst/?rev=246&view=rev Author: vlnb Date: 2008-01-18 11:13:04 -0800 (Fri, 18 Jan 2008) Log Message: ----------- - Important iSCSI stability on connection close fixes. - Latency measurements improvements - Minor improvements and logging changes Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/iscsi-scst/kernel/conn.c 2008-01-18 19:13:04 UTC (rev 246) @@ -398,28 +398,28 @@ void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) { if (unlikely(current != conn->rd_task)) { + printk(KERN_EMERG "conn %p rd_task != current %p (pid %d)\n", conn, + current, current->pid); while(in_softirq()) local_bh_enable(); - printk(KERN_EMERG "conn %p rd_task != current %p (pid %d)\n", conn, - current, current->pid); printk(KERN_EMERG "rd_state %x\n", conn->rd_state); printk(KERN_EMERG "rd_task %p\n", conn->rd_task); printk(KERN_EMERG "rd_task->pid %d\n", conn->rd_task->pid); - sBUG(); + BUG(); } } void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn) { if (unlikely(current != conn->wr_task)) { + printk(KERN_EMERG "conn %p wr_task != current %p (pid %d)\n", conn, + current, current->pid); while(in_softirq()) local_bh_enable(); - printk(KERN_EMERG "conn %p wr_task != current %p (pid %d)\n", conn, - current, current->pid); printk(KERN_EMERG "wr_state %x\n", conn->wr_state); printk(KERN_EMERG "wr_task %p\n", conn->wr_task); printk(KERN_EMERG "wr_task->pid %d\n", conn->wr_task->pid); - sBUG(); + BUG(); } } Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-18 19:13:04 UTC (rev 246) @@ -97,6 +97,32 @@ SCST_CONTEXT_THREAD); } +static inline void iscsi_restart_waiting_cmnd(struct iscsi_cmnd *cmnd) +{ + /* + * There is no race with conn_abort(), since all functions + * called from single read thread + */ + iscsi_extracheck_is_rd_thread(cmnd->conn); + cmnd->data_waiting = 0; + + iscsi_restart_cmnd(cmnd); +} + +static inline void iscsi_fail_waiting_cmnd(struct iscsi_cmnd *cmnd) +{ + TRACE_DBG("Failing data waiting cmd %p", cmnd); + + /* + * There is no race with conn_abort(), since all functions + * called from single read thread + */ + iscsi_extracheck_is_rd_thread(cmnd->conn); + cmnd->data_waiting = 0; + + req_cmnd_release_force(cmnd, ISCSI_FORCE_RELEASE_WRITE); +} + struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *conn, struct iscsi_cmnd *parent) { struct iscsi_cmnd *cmnd; @@ -175,9 +201,12 @@ cmnd->parent_req); } + EXTRACHECKS_BUG_ON(cmnd->on_rx_digest_list); + if (cmnd->parent_req == NULL) { struct iscsi_conn *conn = cmnd->conn; TRACE_DBG("Deleting req %p from conn %p", cmnd, conn); + spin_lock_bh(&conn->cmd_list_lock); list_del(&cmnd->cmd_list_entry); spin_unlock_bh(&conn->cmd_list_lock); @@ -192,14 +221,14 @@ if (cmnd->scst_cmd) { switch(cmnd->scst_state) { case ISCSI_CMD_STATE_AFTER_PREPROC: - TRACE_DBG("%s", "AFTER_PREPROC"); + TRACE_DBG("cmd %p AFTER_PREPROC", cmnd); cmnd->scst_state = ISCSI_CMD_STATE_RESTARTED; scst_restart_cmd(cmnd->scst_cmd, SCST_PREPROCESS_STATUS_ERROR_FATAL, - SCST_CONTEXT_THREAD); + SCST_CONTEXT_DIRECT); break; case ISCSI_CMD_STATE_PROCESSED: - TRACE_DBG("%s", "PROCESSED"); + TRACE_DBG("cmd %p PROCESSED", cmnd); scst_tgt_cmd_done(cmnd->scst_cmd); break; default: @@ -211,10 +240,10 @@ } } else { EXTRACHECKS_BUG_ON(cmnd->scst_cmd != NULL); + TRACE_DBG("Deleting rsp %p from parent %p", cmnd, + cmnd->parent_req); spin_lock_bh(&cmnd->parent_req->rsp_cmd_lock); - TRACE_DBG("Deleting rsp %p from parent %p", cmnd, - cmnd->parent_req); list_del(&cmnd->rsp_cmd_list_entry); spin_unlock_bh(&cmnd->parent_req->rsp_cmd_lock); @@ -285,21 +314,32 @@ again_rsp: spin_lock_bh(&req->rsp_cmd_lock); list_for_each_entry_reverse(rsp, &req->rsp_cmd_list, rsp_cmd_list_entry) { - /* - * It's OK to check not under write_list_lock, since - * iscsi_cmnds_init_write() can't be called in parallel with us - * and once on_write_list or write_processing_started get set, - * rsp gets out of this function responsibility. - */ - if (rsp->on_write_list || rsp->write_processing_started || - rsp->force_cleanup_done) + bool r; + + if (rsp->force_cleanup_done) continue; + rsp->force_cleanup_done = 1; + + if (cmnd_get_check(rsp)) + continue; + spin_unlock_bh(&req->rsp_cmd_lock); - rsp->force_cleanup_done = 1; + spin_lock(&conn->write_list_lock); + r = rsp->on_write_list || rsp->write_processing_started; + spin_unlock(&conn->write_list_lock); + cmnd_put(rsp); + if (r) + continue; + + /* + * If both on_write_list and write_processing_started not set, + * we can safely put() cmnd + */ + cmnd_put(rsp); goto again_rsp; } spin_unlock_bh(&req->rsp_cmd_lock); @@ -336,9 +376,7 @@ list_for_each_entry_safe(c, t, &req->rx_ddigest_cmd_list, rx_ddigest_cmd_list_entry) { - TRACE_DBG("Deleting RX ddigest cmd %p from digest " - "list of req %p", c, req); - list_del(&c->rx_ddigest_cmd_list_entry); + cmd_del_from_rx_ddigest_list(c); cmnd_put(c); } @@ -390,8 +428,10 @@ */ static struct iscsi_cmnd *iscsi_cmnd_create_rsp_cmnd(struct iscsi_cmnd *parent) { - struct iscsi_cmnd *rsp = cmnd_alloc(parent->conn, parent); + struct iscsi_cmnd *rsp; + rsp = cmnd_alloc(parent->conn, parent); + spin_lock_bh(&parent->rsp_cmd_lock); TRACE_DBG("Adding rsp %p to parent %p", rsp, parent); list_add_tail(&rsp->rsp_cmd_list_entry, &parent->rsp_cmd_list); @@ -428,6 +468,7 @@ * erroneously rejected as a duplicate. */ if ((flags & ISCSI_INIT_WRITE_REMOVE_HASH) && rsp->parent_req->hashed && + (rsp->parent_req->r2t_length == 0) && (rsp->parent_req->outstanding_r2t == 0)) cmnd_remove_hash(rsp->parent_req); @@ -744,8 +785,10 @@ spin_lock(&session->cmnd_hash_lock); cmnd = __cmnd_find_hash(session, itt, ttt); - if (cmnd) - cmnd_get(cmnd); + if (cmnd != NULL) { + if (unlikely(cmnd_get_check(cmnd))) + cmnd = NULL; + } spin_unlock(&session->cmnd_hash_lock); return cmnd; @@ -966,12 +1009,12 @@ "(r2t_length %d, outstanding_r2t %d)", req, req->scst_cmd, req->r2t_length, req->outstanding_r2t); if (req->outstanding_r2t == 0) - iscsi_session_push_cmnd(req); + iscsi_fail_waiting_cmnd(req); goto out; } /* - * There is no race with data_out_start() and __cmnd_abort(), since + * There is no race with data_out_start() and conn_abort(), since * all functions called from single read thread */ iscsi_extracheck_is_rd_thread(req->conn); @@ -1041,8 +1084,7 @@ */ goto out; } - TRACE_DBG("Deleting RX digest cmd %p from digest list", c); - list_del(&c->rx_ddigest_cmd_list_entry); + cmd_del_from_rx_ddigest_list(c); cmnd_put(c); } @@ -1316,7 +1358,7 @@ TRACE_ENTRY(); /* - * There is no race with send_r2t() and __cmnd_abort(), since + * There is no race with send_r2t() and conn_abort(), since * all functions called from single read thread */ iscsi_extracheck_is_rd_thread(cmnd->conn); @@ -1382,10 +1424,7 @@ iscsi_extracheck_is_rd_thread(cmnd->conn); if (!(cmnd->conn->ddigest_type & DIGEST_NONE)) { - TRACE_DBG("Adding RX ddigest cmd %p to digest list " - "of req %p", cmnd, req); - list_add_tail(&cmnd->rx_ddigest_cmd_list_entry, - &req->rx_ddigest_cmd_list); + cmd_add_on_rx_ddigest_list(req, cmnd); cmnd_get(cmnd); } @@ -1393,9 +1432,11 @@ TRACE_DBG("ISCSI_RESERVED_TAG, FINAL %x", req_hdr->flags & ISCSI_FLG_FINAL); - if (req_hdr->flags & ISCSI_FLG_FINAL) + if (req_hdr->flags & ISCSI_FLG_FINAL) { req->is_unsolicited_data = 0; - else + if (req->pending) + goto out_put; + } else goto out_put; } else { TRACE_DBG("FINAL %x, outstanding_r2t %d, r2t_length %d", @@ -1419,60 +1460,34 @@ if (!req->is_unsolicited_data) send_r2t(req); } else - iscsi_session_push_cmnd(req); + iscsi_restart_waiting_cmnd(req); out_put: cmnd_put(cmnd); return; } -/* - * Must be called from the read thread. Also called under cmd_list_lock, - * but may drop it inside. - * - * Returns >0 if cmd_list_lock was dropped inside, 0 otherwise. - */ -static int __cmnd_abort(struct iscsi_cmnd *cmnd) +static void __cmnd_abort(struct iscsi_cmnd *cmnd) { - int res = 0; - struct iscsi_conn *conn = cmnd->conn; - TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " "ref_cnt %d, itt %x, sn %u, op %x, r2t_len %x, CDB op %x, " "size to write %u, is_unsolicited_data %d, " "outstanding_r2t %d, data_waiting %d, sess->exp_cmd_sn %u, " - "conn %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, + "conn %p, rd_task %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, atomic_read(&cmnd->ref_cnt), cmnd_itt(cmnd), cmnd->pdu.bhs.sn, cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), cmnd_write_size(cmnd), cmnd->is_unsolicited_data, cmnd->outstanding_r2t, cmnd->data_waiting, - conn->session->exp_cmd_sn, conn); + cmnd->conn->session->exp_cmd_sn, cmnd->conn, + cmnd->conn->rd_task); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); #endif - iscsi_extracheck_is_rd_thread(conn); - cmnd->tmfabort = 1; - if (cmnd->data_waiting && conn->closing) { - spin_unlock_bh(&conn->cmd_list_lock); - - res = 1; - - /* ToDo: this is racy for MC/S */ - TRACE_MGMT_DBG("Pushing data waiting cmd %p", cmnd); - iscsi_session_push_cmnd(cmnd); - - /* - * We are in the read thread, so we may not worry that after - * cmnd release conn gets released as well. - */ - spin_lock_bh(&conn->cmd_list_lock); - } - - return res; + return; } /* Must be called from the read thread */ @@ -1566,17 +1581,13 @@ list_for_each_entry(session, &target->session_list, session_list_entry) { list_for_each_entry(conn, &session->conn_list, conn_list_entry) { spin_lock_bh(&conn->cmd_list_lock); -again: list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { - int again = 0; if (cmnd == req) continue; if (all) - again = __cmnd_abort(cmnd); + __cmnd_abort(cmnd); else if (req_hdr->lun == cmnd_hdr(cmnd)->lun) - again = __cmnd_abort(cmnd); - if (again) - goto again; + __cmnd_abort(cmnd); } spin_unlock_bh(&conn->cmd_list_lock); } @@ -1600,7 +1611,6 @@ list_for_each_entry(conn, &session->conn_list, conn_list_entry) { spin_lock_bh(&conn->cmd_list_lock); -again: list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); if (cmnd == req) @@ -1610,8 +1620,7 @@ if (before(req_hdr->cmd_sn, hdr->cmd_sn) || req_hdr->cmd_sn == hdr->cmd_sn) continue; - if (__cmnd_abort(cmnd)) - goto again; + __cmnd_abort(cmnd); } spin_unlock_bh(&conn->cmd_list_lock); } @@ -1627,13 +1636,36 @@ TRACE_MGMT_DBG("Aborting conn %p", conn); + iscsi_extracheck_is_rd_thread(conn); + spin_lock_bh(&conn->cmd_list_lock); again: list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { - if (__cmnd_abort(cmnd)) - goto again; + __cmnd_abort(cmnd); + if (cmnd->data_waiting) { + if (!cmnd_get_check(cmnd)) { + spin_unlock_bh(&conn->cmd_list_lock); + + /* ToDo: this is racy for MC/S */ + TRACE_MGMT_DBG("Restarting data waiting cmd %p", + cmnd); + iscsi_fail_waiting_cmnd(cmnd); + + cmnd_put(cmnd); + + /* + * We are in the read thread, so we may not + * worry that after cmnd release conn gets + * released as well. + */ + spin_lock_bh(&conn->cmd_list_lock); + goto again; + } + } } spin_unlock_bh(&conn->cmd_list_lock); + + return; } static void execute_task_management(struct iscsi_cmnd *req) @@ -1646,9 +1678,13 @@ struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM cmd: req %p, itt %x, fn %d, rtt %x, sn %u", req, cmnd_itt(req), - function, req_hdr->rtt, req_hdr->cmd_sn); + "TM fn %d", function); + TRACE_MGMT_DBG("TM req %p, itt %x, rtt %x, sn %u, con %p", req, + cmnd_itt(req), req_hdr->rtt, req_hdr->cmd_sn, conn); + + iscsi_extracheck_is_rd_thread(conn); + spin_lock(&sess->sn_lock); sess->tm_active = 1; sess->tm_sn = req_hdr->cmd_sn; @@ -1828,13 +1864,21 @@ goto out; } + iscsi_extracheck_is_rd_thread(cmnd->conn); + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_CMD: + if (cmnd->r2t_length != 0) { + if (!cmnd->is_unsolicited_data) { + send_r2t(cmnd); + break; + } + } else + iscsi_restart_cmnd(cmnd); + break; case ISCSI_OP_NOOP_OUT: noop_out_exec(cmnd); break; - case ISCSI_OP_SCSI_CMD: - iscsi_restart_cmnd(cmnd); - break; case ISCSI_OP_SCSI_TASK_MGT_MSG: execute_task_management(cmnd); break; @@ -2009,12 +2053,6 @@ sBUG_ON(cmnd->parent_req != NULL); - /* - * There is no race with __cmnd_abort(), since all functions - * called from single read thread - */ - cmnd->data_waiting = 0; - if (cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE) { TRACE_DBG("Immediate cmd %p (cmd_sn %u)", cmnd, cmnd->pdu.bhs.sn); @@ -2056,6 +2094,7 @@ break; list_del(&cmnd->pending_list_entry); + cmnd->pending = 0; TRACE_DBG("Processing pending cmd %p (cmd_sn %u)", cmnd, cmd_sn); @@ -2129,6 +2168,7 @@ } list_add_tail(&cmnd->pending_list_entry, entry); + cmnd->pending = 1; } out: return; @@ -2217,12 +2257,6 @@ switch (cmnd_opcode(cmnd)) { case ISCSI_OP_SCSI_CMD: - if (cmnd->r2t_length != 0) { - if (!cmnd->is_unsolicited_data) - send_r2t(cmnd); - break; - } - /* else go through */ case ISCSI_OP_SCSI_REJECT: case ISCSI_OP_NOOP_OUT: case ISCSI_OP_SCSI_TASK_MGT_MSG: @@ -2530,12 +2564,14 @@ (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; struct iscsi_task_rsp_hdr *rsp_hdr; struct iscsi_session *sess = req->conn->session; + int fn = req_hdr->function & ISCSI_FUNCTION_MASK; TRACE_ENTRY(); + TRACE_MGMT_DBG("TM req %p finished", req); TRACE((req_hdr->function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM req %p finished, status %d", req, status); + "TM fn %d finished, status %d", fn, status); rsp = iscsi_cmnd_create_rsp_cmnd(req); rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs; @@ -2545,8 +2581,7 @@ rsp_hdr->itt = req_hdr->itt; rsp_hdr->response = status; - if ((req_hdr->function & ISCSI_FUNCTION_MASK) == - ISCSI_FUNCTION_TARGET_COLD_RESET) + if (fn == ISCSI_FUNCTION_TARGET_COLD_RESET) rsp->should_close_conn = 1; sBUG_ON(sess->tm_rsp != NULL); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-01-18 19:13:04 UTC (rev 246) @@ -138,12 +138,6 @@ spinlock_t cmd_list_lock; /* BH lock */ - /* - * IMPORTANT! If you find a cmd in cmd_list and immediately get_cmnd() - * it, it still can be destroyed immediately after you drop - * cmd_list_lock no matter how big is its ref_cnt! - */ - /* Protected by cmd_list_lock */ struct list_head cmd_list; /* in/outcoming pdus */ @@ -236,6 +230,7 @@ /* Some flags protected by conn->write_list_lock */ unsigned int hashed:1; unsigned int should_close_conn:1; + unsigned int pending:1; unsigned int own_sg:1; unsigned int on_write_list:1; unsigned int write_processing_started:1; @@ -243,6 +238,7 @@ unsigned int force_cleanup_done:1; unsigned int dec_active_cmnds:1; #ifdef EXTRACHECKS + unsigned int on_rx_digest_list:1; unsigned int release_called:1; #endif @@ -254,12 +250,6 @@ /* Unions are for readability and grepability */ - /* - * IMPORTANT! If you find a cmd in rsp_cmd_list and immediately - * get_cmnd() it, it still can be destroyed immediately after you drop - * rsp_cmd_lock no matter how big is its ref_cnt! - */ - union { /* Protected by rsp_cmd_lock */ struct list_head rsp_cmd_list; @@ -413,6 +403,27 @@ extern struct scst_tgt_template iscsi_template; +/* + * Skip this command if result is not 0. Must be called under + * corresponding lock. + */ +static inline bool cmnd_get_check(struct iscsi_cmnd *cmnd) +{ + int r = atomic_inc_return(&cmnd->ref_cnt); + int res; + if (unlikely(r == 1)) { + TRACE_DBG("cmnd %p is being destroyed", cmnd); + atomic_dec(&cmnd->ref_cnt); + res = 1; + /* Necessary code is serialized by locks in cmnd_done() */ + } else { + TRACE_DBG("cmnd %p, new ref_cnt %d", cmnd, + atomic_read(&cmnd->ref_cnt)); + res = 0; + } + return res; +} + static inline void cmnd_get(struct iscsi_cmnd *cmnd) { atomic_inc(&cmnd->ref_cnt); @@ -428,7 +439,7 @@ static inline void cmnd_put(struct iscsi_cmnd *cmnd) { - TRACE_DBG("cmnd %p, new cmnd->ref_cnt %d", cmnd, + TRACE_DBG("cmnd %p, new ref_cnt %d", cmnd, atomic_read(&cmnd->ref_cnt)-1); sBUG_ON(atomic_read(&cmnd->ref_cnt) == 0); if (atomic_dec_and_test(&cmnd->ref_cnt)) @@ -452,6 +463,27 @@ cmnd->on_write_list = 0; } +static inline void cmd_add_on_rx_ddigest_list(struct iscsi_cmnd *req, + struct iscsi_cmnd *cmnd) +{ + TRACE_DBG("Adding RX ddigest cmd %p to digest list " + "of req %p", cmnd, req); + list_add_tail(&cmnd->rx_ddigest_cmd_list_entry, + &req->rx_ddigest_cmd_list); +#ifdef EXTRACHECKS + cmnd->on_rx_digest_list = 1; +#endif +} + +static inline void cmd_del_from_rx_ddigest_list(struct iscsi_cmnd *cmnd) +{ + TRACE_DBG("Deleting RX digest cmd %p from digest list", cmnd); + list_del(&cmnd->rx_ddigest_cmd_list_entry); +#ifdef EXTRACHECKS + cmnd->on_rx_digest_list = 0; +#endif +} + static inline int test_write_ready(struct iscsi_conn *conn) { /* @@ -482,7 +514,7 @@ /* * It always ordered to protect from undesired side effects like - * accessing just destroyed obeject because of this *_dec() reordering. + * accessing just destroyed object because of this *_dec() reordering. */ smp_mb__before_atomic_dec(); atomic_dec(&conn->conn_ref_cnt); Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/iscsi-scst/kernel/nthread.c 2008-01-18 19:13:04 UTC (rev 246) @@ -76,21 +76,30 @@ again: spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { + struct iscsi_cmnd *rsp; + int restart = 0; + TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, data_waiting %d, " "ref_cnt %d, parent_req %p, net_ref_cnt %d, sg %p", cmnd, cmnd->scst_state, cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), cmnd->parent_req, atomic_read(&cmnd->net_ref_cnt), cmnd->sg); + sBUG_ON(cmnd->parent_req != NULL); + if (cmnd->sg != NULL) { - int sg_cnt, i, restart = 0; + int sg_cnt, i; + sg_cnt = get_pgcnt(cmnd->bufflen, cmnd->sg[0].offset); - cmnd_get(cmnd); + + if (cmnd_get_check(cmnd)) + continue; for(i = 0; i < sg_cnt; i++) { TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d", cmnd->sg[i].page, cmnd->sg[i].page->net_priv, atomic_read(&cmnd->sg[i].page->_count)); + if (cmnd->sg[i].page->net_priv != NULL) { if (restart == 0) { spin_unlock_bh(&conn->cmd_list_lock); @@ -101,9 +110,49 @@ } } cmnd_put(cmnd); + if (restart) goto again; } + + spin_lock_bh(&cmnd->rsp_cmd_lock); + list_for_each_entry(rsp, &cmnd->rsp_cmd_list, rsp_cmd_list_entry) { + TRACE_CONN_CLOSE_DBG(" rsp %p, ref_cnt %d, net_ref_cnt %d, " + "sg %p", rsp, atomic_read(&rsp->ref_cnt), + atomic_read(&rsp->net_ref_cnt), rsp->sg); + + if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) { + int sg_cnt, i; + + sg_cnt = get_pgcnt(rsp->bufflen, + rsp->sg[0].offset); + sBUG_ON(rsp->sg_cnt != sg_cnt); + + if (cmnd_get_check(rsp)) + continue; + for(i = 0; i < sg_cnt; i++) { + TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, " + "_count %d", rsp->sg[i].page, + rsp->sg[i].page->net_priv, + atomic_read(&rsp->sg[i].page->_count)); + + if (rsp->sg[i].page->net_priv != NULL) { + if (restart == 0) { + spin_unlock_bh(&cmnd->rsp_cmd_lock); + spin_unlock_bh(&conn->cmd_list_lock); + restart = 1; + } + while(rsp->sg[i].page->net_priv != NULL) + iscsi_put_page_callback(rsp->sg[i].page); + } + } + cmnd_put(rsp); + + if (restart) + goto again; + } + } + spin_unlock_bh(&cmnd->rsp_cmd_lock); } spin_unlock_bh(&conn->cmd_list_lock); @@ -194,6 +243,7 @@ cmnd); list_del(&cmnd->pending_list_entry); + cmnd->pending = 0; session->exp_cmd_sn++; @@ -225,6 +275,7 @@ "pending cmd %p", cmnd); list_del(&cmnd->pending_list_entry); + cmnd->pending = 0; if (session->exp_cmd_sn == cmnd->pdu.bhs.sn) session->exp_cmd_sn++; @@ -254,17 +305,20 @@ #ifdef NET_PAGE_CALLBACKS_DEFINED struct iscsi_cmnd *rsp; #endif + +#if 0 if (time_after(jiffies, start_waiting+10*HZ)) trace_flag |= TRACE_CONN_OC_DBG; +#endif spin_lock_bh(&conn->cmd_list_lock); list_for_each_entry(cmnd, &conn->cmd_list, cmd_list_entry) { TRACE_CONN_CLOSE_DBG("cmd %p, scst_state %x, scst_cmd " "state %d, data_waiting %d, ref_cnt %d, sn %u, " - "parent_req %p", cmnd, cmnd->scst_state, + "parent_req %p, pending %d", cmnd, cmnd->scst_state, (cmnd->scst_cmd != NULL) ? cmnd->scst_cmd->state : -1, cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), - cmnd->pdu.bhs.sn, cmnd->parent_req); + cmnd->pdu.bhs.sn, cmnd->parent_req, cmnd->pending); #ifdef NET_PAGE_CALLBACKS_DEFINED TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", atomic_read(&cmnd->net_ref_cnt), cmnd->sg); @@ -333,6 +387,39 @@ return; } +static int close_conn_thr(void *arg) +{ + struct iscsi_conn *conn = (struct iscsi_conn *)arg; + + TRACE_ENTRY(); + +#ifdef EXTRACHECKS + conn->rd_task = current; +#endif + close_conn(conn); + + TRACE_EXIT(); + return 0; +} + +/* No locks */ +static void start_close_conn(struct iscsi_conn *conn) +{ + struct task_struct *t; + + TRACE_ENTRY(); + + t = kthread_run(close_conn_thr, conn, "iscsi_conn_cleanup"); + if (IS_ERR(t)) { + PRINT_ERROR("kthread_run() failed (%ld), closing conn %p " + "directly", PTR_ERR(t), conn); + close_conn(conn); + } + + TRACE_EXIT(); + return; +} + static inline void iscsi_conn_init_read(struct iscsi_conn *conn, void *data, size_t len) { len = (len + 3) & -4; // XXX ??? @@ -525,12 +612,8 @@ case RX_CHECK_DDIGEST: conn->read_state = RX_END; if (cmnd_opcode(cmnd) == ISCSI_OP_SCSI_CMD) { - TRACE_DBG("Adding RX ddigest cmd %p to digest list " - "of self", cmnd); - list_add_tail(&cmnd->rx_ddigest_cmd_list_entry, - &cmnd->rx_ddigest_cmd_list); + cmd_add_on_rx_ddigest_list(cmnd, cmnd); cmnd_get(cmnd); - conn->read_state = RX_END; } else if (cmnd_opcode(cmnd) != ISCSI_OP_SCSI_DATA_OUT) { /* * We could get here only for NOP-Out. ISCSI RFC doesn't @@ -584,7 +667,7 @@ do { res = recv(conn); if (unlikely(conn->closing)) { - close_conn(conn); + start_close_conn(conn); *closed = 1; break; } Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/scst/include/scsi_tgt.h 2008-01-18 19:13:04 UTC (rev 246) @@ -949,8 +949,8 @@ #ifdef MEASURE_LATENCY spinlock_t meas_lock; - uint64_t processing_time; - int processed_cmds; + uint64_t scst_time, processing_time; + unsigned int processed_cmds; #endif }; Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-18 19:13:04 UTC (rev 246) @@ -732,17 +732,6 @@ lba_start |= ((u64)cdb[5]); data_len = cmd->bufflen; break; - case SYNCHRONIZE_CACHE: - lba_start |= ((u64)cdb[2]) << 24; - lba_start |= ((u64)cdb[3]) << 16; - lba_start |= ((u64)cdb[4]) << 8; - lba_start |= ((u64)cdb[5]); - data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0))) - << virt_dev->block_shift; - if (data_len == 0) - data_len = virt_dev->file_size - - ((loff_t)lba_start << virt_dev->block_shift); - break; case READ_16: case WRITE_16: case WRITE_VERIFY_16: @@ -757,6 +746,17 @@ lba_start |= ((u64)cdb[9]); data_len = cmd->bufflen; break; + case SYNCHRONIZE_CACHE: + lba_start |= ((u64)cdb[2]) << 24; + lba_start |= ((u64)cdb[3]) << 16; + lba_start |= ((u64)cdb[4]) << 8; + lba_start |= ((u64)cdb[5]); + data_len = ((cdb[7] << (BYTE * 1)) + (cdb[8] << (BYTE * 0))) + << virt_dev->block_shift; + if (data_len == 0) + data_len = virt_dev->file_size - + ((loff_t)lba_start << virt_dev->block_shift); + break; } loff = (loff_t)lba_start << virt_dev->block_shift; Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/scst/src/scst_proc.c 2008-01-18 19:13:04 UTC (rev 246) @@ -395,43 +395,45 @@ goto out; } - seq_printf(seq, "%-20s %-45s %-35s\n", "Target name", "Initiator name", - "Processing latency (us)"); + seq_printf(seq, "%-20s %-45s %-15s %15s\n", "Target name", "Initiator name", + "SCST latency", "Processing latency (us)"); list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) { list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { - unsigned long lat = 0; - uint64_t processing_time; - uint64_t processed_cmds; + unsigned long proc_lat = 0, scst_lat = 0; + uint64_t proc_time, scst_time; + unsigned int processed_cmds; spin_lock_bh(&sess->meas_lock); - processing_time = sess->processing_time; + proc_time = sess->processing_time; + scst_time = sess->scst_time; processed_cmds = sess->processed_cmds; spin_unlock_bh(&sess->meas_lock); - TRACE_DBG("sess %p, processing_time %Ld, " - "processed_cmds %Ld", sess, processing_time, - processed_cmds); + TRACE_DBG("sess %p, scst_time %Ld, proc_time %Ld, " + "processed_cmds %d", sess, scst_time, + proc_time, processed_cmds); #if BITS_PER_LONG == 32 - while((processing_time & 0xFFFFFFFF00000000LL) != 0) { - TRACE_DBG("Processing time too big (" - "processing_time %Ld, processed_cmds %Ld", - processing_time, processed_cmds); - processing_time >>= 1; + /* Unfortunately, do_div() doesn't work too well */ + while(((proc_time & 0xFFFFFFFF00000000LL) != 0) || + ((scst_time & 0xFFFFFFFF00000000LL) != 0)) { + TRACE_DBG("%s", "Gathered time too big"); + proc_time >>= 1; + scst_time >>= 1; processed_cmds >>= 1; } #endif if (sess->processed_cmds != 0) { - lat = (unsigned long)processing_time / - (unsigned long)processed_cmds; + proc_lat = (unsigned long)proc_time / processed_cmds; + scst_lat = (unsigned long)scst_time / processed_cmds; } - seq_printf(seq, "%-20s %-45s %-15ld\n", + seq_printf(seq, "%-20s %-45s %-15ld %-15ld\n", sess->tgt->tgtt->name, sess->initiator_name, - lat); + scst_lat, proc_lat); } } @@ -1837,12 +1839,12 @@ goto out; } - seq_printf(seq, "%-20s %-35s %-35s %-15s\n", "Target name", "Initiator name", + seq_printf(seq, "%-20s %-45s %-35s %-15s\n", "Target name", "Initiator name", "Group name", "Command Count"); list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) { list_for_each_entry(sess, &acg->acg_sess_list, acg_sess_list_entry) { - seq_printf(seq, "%-20s %-35s %-35s %-15d\n", + seq_printf(seq, "%-20s %-45s %-35s %-15d\n", sess->tgt->tgtt->name, sess->initiator_name, acg->acg_name, Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-14 18:21:01 UTC (rev 245) +++ trunk/scst/src/scst_targ.c 2008-01-18 19:13:04 UTC (rev 246) @@ -2475,21 +2475,27 @@ #ifdef MEASURE_LATENCY { struct timespec ts; - uint64_t finish, processing_time; + uint64_t finish, scst_time, proc_time; struct scst_session *sess = cmd->sess; getnstimeofday(&ts); finish = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; spin_lock_bh(&sess->meas_lock); - processing_time = cmd->pre_exec_finish - cmd->start; - processing_time += finish - cmd->post_exec_start; - sess->processing_time += processing_time; + + scst_time = cmd->pre_exec_finish - cmd->start; + scst_time += finish - cmd->post_exec_start; + proc_time = finish - cmd->start; + + sess->scst_time += scst_time; + sess->processing_time += proc_time; sess->processed_cmds++; + + spin_unlock_bh(&sess->meas_lock); + TRACE_DBG("cmd %p (sess %p): finish %Ld (tv_sec %ld, " - "tv_nsec %ld), processing_time %Ld", cmd, sess, finish, - ts.tv_sec, ts.tv_nsec, processing_time); - spin_unlock_bh(&sess->meas_lock); + "tv_nsec %ld), scst_time %Ld, proc_time %Ld", cmd, sess, + finish, ts.tv_sec, ts.tv_nsec, scst_time, proc_time); } #endif TRACE_EXIT_HRES(res); @@ -3389,9 +3395,9 @@ * we must wait here to be sure that we won't receive * double commands with the same tag. */ - TRACE((mcmd->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "cmd %p (tag %llu) being executed/xmitted (state %d), " - "deferring ABORT...", cmd, cmd->tag, cmd->state); + TRACE_MGMT_DBG("cmd %p (tag %llu) being executed/xmitted " + "(state %d), deferring ABORT...", cmd, cmd->tag, + cmd->state); #ifdef EXTRACHECKS if (cmd->mgmt_cmnd) { printk(KERN_ALERT "cmd %p (tag %llu, state %d) " @@ -3706,7 +3712,7 @@ } scst_cmd_get(cmd); spin_unlock_irq(&sess->sess_list_lock); - TRACE(TRACE_MGMT_MINOR, "Cmd %p for tag %llu (sn %ld, set %d, " + TRACE_MGMT_DBG("Cmd %p for tag %llu (sn %ld, set %d, " "queue_type %x) found, aborting it", cmd, mcmd->tag, cmd->sn, cmd->sn_set, cmd->queue_type); mcmd->cmd_to_abort = cmd; @@ -4419,8 +4425,10 @@ mcmd->cmd_sn = params->cmd_sn; TRACE((params->fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "sess=%p, fn %x, tag_set %d, tag %Ld, lun_set %d, " - "lun=%Ld, cmd_sn_set %d, cmd_sn %d", sess, params->fn, + "TM fn %x", params->fn); + + TRACE_MGMT_DBG("sess=%p, tag_set %d, tag %Ld, lun_set %d, " + "lun=%Ld, cmd_sn_set %d, cmd_sn %d", sess, params->tag_set, params->tag, params->lun_set, (uint64_t)mcmd->lun, params->cmd_sn_set, params->cmd_sn); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-01-24 10:57:25
|
Revision: 248 http://scst.svn.sourceforge.net/scst/?rev=248&view=rev Author: vlnb Date: 2008-01-24 02:56:35 -0800 (Thu, 24 Jan 2008) Log Message: ----------- - A bunch of minor, mostly stability related, fixes. - Docs update Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/etc/initd/initd.debian trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/session.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/README 2008-01-24 10:56:35 UTC (rev 248) @@ -102,7 +102,7 @@ their parameters, SCST core is responsible for handling backstorage. If you need to configure different LUs for different targets you should -create for each target group "Default_target_name", where target name +create for each target group "Default_target_name", where "target_name" means name of the target, for example: "Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz", and add there all necessary LUNs. Check SCST README file for details. @@ -114,6 +114,15 @@ iscsi-scstd.conf file for the corresponding target. See also SCST README file for more details about that issue. +Sometimes, when there are communication problems with initiator(s), +shutting down iSCSI-SCST can take very long time, up to about 10 +minutes. This can happen, because iSCSI-SCST can't be shutdown before +all already sent to TCP for initiator(s) data will be actually sent +and/or released by TCP. In case of communication failures this can take +up to TCP transmit timeout, which is about 10 minutes. In such cases +using netstat utility you can see that there is/are connection(s) to +initiator(s) with non-0 "Send-Q". + CAUTION: Working of target and initiator on the same host isn't ======== supported. See SCST README file for details. Modified: trunk/iscsi-scst/etc/initd/initd.debian =================================================================== --- trunk/iscsi-scst/etc/initd/initd.debian 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/etc/initd/initd.debian 2008-01-24 10:56:35 UTC (rev 248) @@ -109,23 +109,6 @@ exit 1 fi ;; - dump) - DUMP=`tempfile -p iscsi-scstd` - RETVAL=$? - if [ $RETVAL -ne 0 ]; then - echo "Failed to create dump file $DUMP" - exit 1 - fi - iscsi-scst-adm --mode dump --all >$DUMP - RETVAL=$? - if [ $RETVAL -ne 0 ]; then - echo "Error dumping config from daemon" - rm $DUMP - exit 1 - fi - mv -u $DUMP $CONFIG_FILE - echo "Config dumped to $CONFIG_FILE" - ;; *) echo $"Usage: $0 {start|stop|restart|status|dump}" exit 1 Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-01-24 10:56:35 UTC (rev 248) @@ -92,6 +92,8 @@ static inline void iscsi_restart_cmnd(struct iscsi_cmnd *cmnd) { + EXTRACHECKS_BUG_ON(cmnd->data_waiting); + cmnd->scst_state = ISCSI_CMD_STATE_RESTARTED; scst_restart_cmd(cmnd->scst_cmd, SCST_PREPROCESS_STATUS_SUCCESS, SCST_CONTEXT_THREAD); @@ -166,6 +168,12 @@ { TRACE_DBG("%p", cmnd); + if (unlikely(cmnd->tmfabort)) { + TRACE_MGMT_DBG("Free aborted cmd %p (scst cmd %p, state %d, " + "parent_req %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, + cmnd->parent_req); + } + /* Catch users from cmd_list or rsp_cmd_list */ EXTRACHECKS_BUG_ON(atomic_read(&cmnd->ref_cnt) != 0); @@ -221,12 +229,16 @@ if (cmnd->scst_cmd) { switch(cmnd->scst_state) { case ISCSI_CMD_STATE_AFTER_PREPROC: + { + struct scst_cmd *scst_cmd = cmnd->scst_cmd; TRACE_DBG("cmd %p AFTER_PREPROC", cmnd); cmnd->scst_state = ISCSI_CMD_STATE_RESTARTED; - scst_restart_cmd(cmnd->scst_cmd, + cmnd->scst_cmd = NULL; + scst_restart_cmd(scst_cmd, SCST_PREPROCESS_STATUS_ERROR_FATAL, - SCST_CONTEXT_DIRECT); + SCST_CONTEXT_THREAD); break; + } case ISCSI_CMD_STATE_PROCESSED: TRACE_DBG("cmd %p PROCESSED", cmnd); scst_tgt_cmd_done(cmnd->scst_cmd); @@ -1300,7 +1312,8 @@ if (dir == SCST_DATA_WRITE) { req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL); req->r2t_length = be32_to_cpu(req_hdr->data_length) - req->pdu.datasize; - req->data_waiting = 1; + if (req->r2t_length > 0) + req->data_waiting = 1; } req->target_task_tag = get_next_ttt(conn); req->sg = scst_cmd_get_sg(scst_cmd); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-01-24 10:56:35 UTC (rev 248) @@ -103,7 +103,7 @@ u32 tm_sn; struct iscsi_cmnd *tm_rsp; - /* read only, if there are connection(s) */ + /* Read only, if there are connection(s) */ struct iscsi_sess_param sess_param; spinlock_t cmnd_hash_lock; @@ -113,7 +113,7 @@ struct list_head session_list_entry; - /* Bot don't need any protection */ + /* Both don't need any protection */ char *initiator_name; u64 sid; }; Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/kernel/nthread.c 2008-01-24 10:56:35 UTC (rev 248) @@ -183,6 +183,15 @@ /* We want all our already send operations to complete */ conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); + /* + * We need to call scst_unregister_session() ASAP to make SCST start + * stuck commands recovery. + * + * ToDo: this is incompatible with MC/S + */ + scst_unregister_session(session->scst_sess, 0, NULL); + session->scst_sess = NULL; + if (conn->read_state != RX_INIT_BHS) { struct iscsi_cmnd *cmnd = conn->read_cmnd; conn->read_cmnd = NULL; @@ -295,7 +304,7 @@ } iscsi_make_conn_wr_active(conn); - msleep(50); + msleep(200); TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " "exp_cmd_sn %u", conn, atomic_read(&conn->conn_ref_cnt), @@ -379,8 +388,8 @@ mutex_lock(&target->target_mutex); conn_free(conn); - if (list_empty(&session->conn_list)) - session_del(target, session->sid); + /* ToDo: this is incompatible with MC/S */ + session_free(session); mutex_unlock(&target->target_mutex); TRACE_EXIT(); Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/iscsi-scst/kernel/session.c 2008-01-24 10:56:35 UTC (rev 248) @@ -136,7 +136,8 @@ for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) sBUG_ON(!list_empty(&session->cmnd_hash[i])); - scst_unregister_session(session->scst_sess, 1, NULL); + if (session->scst_sess != NULL) + scst_unregister_session(session->scst_sess, 1, NULL); list_del(&session->session_list_entry); Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/README 2008-01-24 10:56:35 UTC (rev 248) @@ -426,7 +426,11 @@ and "FLAGS" are valid only for disk VDISK. The block size must be power of 2 and >= 512 bytes. Default is 512. Possible flags: - - WRITE_THROUGH - write back caching disabled + - WRITE_THROUGH - write back caching disabled. Note, this option + has sense only if you also *manually* disable write-back cache + in *all* your backstorage devices and make sure it's actually + disabled, since many devices are known to lie about this mode to + get better benchmark results. - READ_ONLY - read only @@ -439,20 +443,23 @@ way as "*_perf" handlers. - NV_CACHE - enables "non-volatile cache" mode. In this mode it is - assumed that the target has GOOD UPS and software/hardware bug - free, i.e. all data from the target's cache are guaranteed - sooner or later to go to the media, hence all data - synchronization with media operations, like SYNCHRONIZE_CACHE, - are ignored (BTW, so violating SCSI standard) in order to bring - a bit more performance. Use with extreme caution, since in this - mode after a crash of the target journaled file systems don't - guarantee the consistency after journal recovery, therefore - manual fsck MUST be ran. The main intent for it is to determine - the performance impact caused by the cache synchronization. - Note, that since usually the journal barrier protection (see - "IMPORTANT" below) turned off, enabling NV_CACHE could change - nothing, since no data synchronization with media operations - will go from the initiator. + assumed that the target has a GOOD UPS with ability to cleanly + shutdown target in case of power failure and it is + software/hardware bugs free, i.e. all data from the target's + cache are guaranteed sooner or later to go to the media. Hence + all data synchronization with media operations, like + SYNCHRONIZE_CACHE, are ignored in order to bring more + performance. Also in this mode target reports to initiators that + the corresponding device has write-through cache to disable all + write-back cache workarounds used by initiators. Use with + extreme caution, since in this mode after a crash of the target + journaled file systems don't guarantee the consistency after + journal recovery, therefore manual fsck MUST be ran. Note, that + since usually the journal barrier protection (see "IMPORTANT" + note below) turned off, enabling NV_CACHE could change nothing + from data protection point of view, since no data + synchronization with media operations will go from the + initiator. This option overrides WRITE_THROUGH. - BLOCKIO - enables block mode, which will perform direct block IO with a block device, bypassing page-cache for all operations. @@ -503,7 +510,7 @@ backstorage device and lost on power failure event. Thus, ever with write-through cache mode, you still need a good UPS to protect yourself from your data loss (note, data loss, not - the file system integrity). + the file system integrity corruption). IMPORTANT: Some disk and partition table management utilities don't support ========= block sizes >512 bytes, therefore make sure that your favorite one Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/include/scsi_tgt.h 2008-01-24 10:56:35 UTC (rev 248) @@ -1621,13 +1621,23 @@ * Parameter: * - sess - session * - * Note: All outstanding commands will be finished regularly. After - * scst_unregister_session() returned no new commands must be sent to - * SCST via scst_rx_cmd(). Also, the caller must ensure that no - * scst_rx_cmd() or scst_rx_mgmt_fn_*() is called in paralell with - * scst_unregister_session(). - * Can be called before result_fn() of scst_register_session() called, - * i.e. during the session registration/initialization. + * Notes: + * + * - All outstanding commands will be finished regularly. After + * scst_unregister_session() returned no new commands must be sent to + * SCST via scst_rx_cmd(). + * + * - The caller must ensure that no scst_rx_cmd() or scst_rx_mgmt_fn_*() is + * called in paralell with scst_unregister_session(). + * + * - Can be called before result_fn() of scst_register_session() called, + * i.e. during the session registration/initialization. + * + * - It is highly recommended to call scst_unregister_session() as soon as it + * gets clear that session will be unregistered and not to wait until all + * related commands finished. This function provides the wait functionality, + * but it also starts recovering stuck commands, if there are any. + * Otherwise, your target driver could wait for those commands forever. */ void scst_unregister_session(struct scst_session *sess, int wait, void (*unreg_done_fn) (struct scst_session *sess)); Modified: trunk/scst/src/dev_handlers/scst_cdrom.c =================================================================== --- trunk/scst/src/dev_handlers/scst_cdrom.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_cdrom.c 2008-01-24 10:56:35 UTC (rev 248) @@ -148,8 +148,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out_free_buf; + } out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_changer.c 2008-01-24 10:56:35 UTC (rev 248) @@ -96,8 +96,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out; + } out: TRACE_EXIT_HRES(res); Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_disk.c 2008-01-24 10:56:35 UTC (rev 248) @@ -220,8 +220,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out_free_buf; + } out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2008-01-24 10:56:35 UTC (rev 248) @@ -235,8 +235,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d: %x", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, res); goto out_free_buf; + } out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_processor.c 2008-01-24 10:56:35 UTC (rev 248) @@ -96,8 +96,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out; + } out: TRACE_EXIT(); Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_raid.c 2008-01-24 10:56:35 UTC (rev 248) @@ -96,8 +96,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out; + } out: TRACE_EXIT(); Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_tape.c 2008-01-24 10:56:35 UTC (rev 248) @@ -223,8 +223,13 @@ } res = scst_obtain_device_parameters(dev); - if (res != 0) + if (res != 0) { + PRINT_ERROR("Failed to obtain control parameters for device " + "%d:%d:%d:%d", dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); goto out_free_buf; + } out_free_buf: kfree(buffer); Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-01-24 10:56:35 UTC (rev 248) @@ -351,7 +351,7 @@ open_flags |= O_RDWR; if (virt_dev->o_direct_flag) open_flags |= O_DIRECT; - if (virt_dev->wt_flag) + if (virt_dev->wt_flag && !virt_dev->nv_cache) open_flags |= O_SYNC; TRACE_DBG("Opening file %s, flags 0x%x", virt_dev->file_name, open_flags); fd = filp_open(virt_dev->file_name, O_LARGEFILE | open_flags, 0600); @@ -494,7 +494,7 @@ dev->dh_priv = virt_dev; dev->tst = DEF_TST; - if (virt_dev->wt_flag) + if (virt_dev->wt_flag && !virt_dev->nv_cache) dev->queue_alg = DEF_QUEUE_ALG_WT; else dev->queue_alg = DEF_QUEUE_ALG; @@ -1313,7 +1313,7 @@ 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; memcpy(p, caching_pg, sizeof(caching_pg)); - p[2] |= !(virt_dev->wt_flag) ? WCE : 0; + p[2] |= !(virt_dev->wt_flag || virt_dev->nv_cache) ? WCE : 0; if (1 == pcontrol) memset(p + 2, 0, sizeof(caching_pg) - 2); return sizeof(caching_pg); @@ -1344,7 +1344,7 @@ break; case 2: p[2] |= DEF_TST << 5; - if (virt_dev->wt_flag) + if (virt_dev->wt_flag || virt_dev->nv_cache) p[3] |= DEF_QUEUE_ALG_WT << 4; else p[3] |= DEF_QUEUE_ALG << 4; @@ -1529,7 +1529,7 @@ TRACE_ENTRY(); - if ((virt_dev->wt_flag == wt) || virt_dev->nullio) + if ((virt_dev->wt_flag == wt) || virt_dev->nullio || virt_dev->nv_cache) goto out; spin_lock(&virt_dev->flags_lock); @@ -2486,7 +2486,7 @@ struct scst_vdisk_dev *virt_dev = (struct scst_vdisk_dev *)dev->dh_priv; dev->tst = DEF_TST; - if (virt_dev->wt_flag) + if (virt_dev->wt_flag && !virt_dev->nv_cache) dev->queue_alg = DEF_QUEUE_ALG_WT; else dev->queue_alg = DEF_QUEUE_ALG; Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/scst_lib.c 2008-01-24 10:56:35 UTC (rev 248) @@ -2296,7 +2296,11 @@ goto out; } else { +#if 0 /* 3ware controller is buggy and returns CONDITION_GOOD instead of CHECK_CONDITION */ if ((status_byte(res) == CHECK_CONDITION) && +#else + if ( +#endif SCST_SENSE_VALID(sense_buffer) && (sense_buffer[2] == ILLEGAL_REQUEST)) { TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d " @@ -3103,7 +3107,6 @@ /* All serialized by scst_tm_dbg_lock */ struct { - unsigned int tm_dbg_active:1; unsigned int tm_dbg_release:1; unsigned int tm_dbg_blocked:1; } tm_dbg_flags; @@ -3122,19 +3125,16 @@ { if ((acg_dev->acg == scst_default_acg) && (acg_dev->lun == 0)) { unsigned long flags; + /* Do TM debugging only for LUN 0 */ spin_lock_irqsave(&scst_tm_dbg_lock, flags); - if (!tm_dbg_flags.tm_dbg_active) { - /* Do TM debugging only for LUN 0 */ - tm_dbg_p_cmd_list_waitQ = - &tgt_dev->dev->p_cmd_lists->cmd_list_waitQ; - tm_dbg_state = INIT_TM_DBG_STATE; - tm_dbg_on_state_passes = - tm_dbg_on_state_num_passes[tm_dbg_state]; - __set_bit(SCST_TGT_DEV_UNDER_TM_DBG, &tgt_dev->tgt_dev_flags); - PRINT_INFO("LUN 0 connected from initiator %s is under " - "TM debugging", tgt_dev->sess->tgt->tgtt->name); - tm_dbg_flags.tm_dbg_active = 1; - } + tm_dbg_p_cmd_list_waitQ = + &tgt_dev->dev->p_cmd_lists->cmd_list_waitQ; + tm_dbg_state = INIT_TM_DBG_STATE; + tm_dbg_on_state_passes = + tm_dbg_on_state_num_passes[tm_dbg_state]; + __set_bit(SCST_TGT_DEV_UNDER_TM_DBG, &tgt_dev->tgt_dev_flags); + PRINT_INFO("LUN 0 connected from initiator %s is under " + "TM debugging", tgt_dev->sess->tgt->tgtt->name); spin_unlock_irqrestore(&scst_tm_dbg_lock, flags); } } @@ -3146,7 +3146,6 @@ del_timer_sync(&tm_dbg_timer); spin_lock_irqsave(&scst_tm_dbg_lock, flags); tm_dbg_p_cmd_list_waitQ = NULL; - tm_dbg_flags.tm_dbg_active = 0; spin_unlock_irqrestore(&scst_tm_dbg_lock, flags); } } @@ -3342,9 +3341,6 @@ { unsigned long flags; - if (!tm_dbg_flags.tm_dbg_active) - goto out; - if (dev != NULL) { struct scst_tgt_dev *tgt_dev; bool found = 0; @@ -3371,7 +3367,8 @@ tm_dbg_change_state(); tm_dbg_flags.tm_dbg_release = 1; smp_mb(); - wake_up_all(tm_dbg_p_cmd_list_waitQ); + if (tm_dbg_p_cmd_list_waitQ != NULL) + wake_up_all(tm_dbg_p_cmd_list_waitQ); } else { TRACE_MGMT_DBG("%s: while OFFLINE state, doing nothing", fn); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-01-23 16:03:20 UTC (rev 247) +++ trunk/scst/src/scst_targ.c 2008-01-24 10:56:35 UTC (rev 248) @@ -208,9 +208,16 @@ spin_lock_irqsave(&sess->sess_list_lock, flags); - list_add_tail(&cmd->search_cmd_list_entry, &sess->search_cmd_list); - if (unlikely(sess->init_phase != SCST_SESS_IPH_READY)) { + /* + * We have to always keep command in the search list from the + * very beginning, because otherwise it can be missed during + * TM processing. This check is needed because there might be + * old, i.e. deferred, commands and new, i.e. just coming, ones. + */ + if (cmd->search_cmd_list_entry.next == NULL) + list_add_tail(&cmd->search_cmd_list_entry, + &sess->search_cmd_list); switch(sess->init_phase) { case SCST_SESS_IPH_SUCCESS: break; @@ -228,7 +235,8 @@ default: sBUG(); } - } + } else + list_add_tail(&cmd->search_cmd_list_entry, &sess->search_cmd_list); spin_unlock_irqrestore(&sess->sess_list_lock, flags); @@ -1845,6 +1853,7 @@ struct scst_cmd *cmd = *active_cmd; struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; struct scst_device *dev = cmd->dev; + struct scst_session *sess = cmd->sess; typeof(tgt_dev->expected_sn) expected_sn; int count; @@ -1852,11 +1861,12 @@ res = SCST_CMD_STATE_RES_CONT_NEXT; - __scst_get(0); /* protect dev & tgt_dev */ + __scst_get(0); /* protect dev */ + scst_sess_get(sess); /* protect tgt_dev */ if (unlikely(cmd->internal || cmd->retry)) { rc = scst_do_send_to_midlev(cmd); - /* !! At this point cmd, sess & tgt_dev can be already freed !! */ + /* !! At this point cmd can be already freed !! */ if (rc == SCST_EXEC_NEED_THREAD) { TRACE_DBG("%s", "scst_do_send_to_midlev() requested " "thread context, rescheduling"); @@ -1875,7 +1885,7 @@ getnstimeofday(&ts); cmd->pre_exec_finish = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec; TRACE_DBG("cmd %p (sess %p): pre_exec_finish %Ld (tv_sec %ld, " - "tv_nsec %ld)", cmd, cmd->sess, cmd->pre_exec_finish, ts.tv_sec, + "tv_nsec %ld)", cmd, sess, cmd->pre_exec_finish, ts.tv_sec, ts.tv_nsec); } #endif @@ -1960,6 +1970,7 @@ generic_unplug_device(dev->scsi_dev->request_queue); out_put: + scst_sess_put(sess); __scst_put(); /* !! At this point sess, dev and tgt_dev can be already freed !! */ @@ -2434,6 +2445,19 @@ TRACE_ENTRY(); +#ifdef DEBUG_TM + if (cmd->tm_dbg_delayed && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { + if (scst_cmd_atomic(cmd)) { + TRACE_MGMT_DBG("%s", "DEBUG_TM delayed cmd needs a thread"); + res = SCST_CMD_STATE_RES_NEED_THREAD; + return res; + } + TRACE_MGMT_DBG("Delaying cmd %p (tag %llu) for 1 second", + cmd, cmd->tag); + schedule_timeout_uninterruptible(HZ); + } +#endif + if (cmd->tgt_dev != NULL) { if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE)) scst_on_hq_cmd_response(cmd); @@ -2516,19 +2540,6 @@ goto out; } -#ifdef DEBUG_TM - if (cmd->tm_dbg_delayed && !test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { - if (atomic && !cmd->tgtt->xmit_response_atomic) { - TRACE_MGMT_DBG("%s", "DEBUG_TM delayed cmd needs a thread"); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - TRACE_MGMT_DBG("Delaying cmd %p (tag %llu) for 1 second", - cmd, cmd->tag); - schedule_timeout_uninterruptible(HZ); - } -#endif - while (1) { int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds); @@ -3439,12 +3450,12 @@ return res; } -static int __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd) +static bool __scst_check_unblock_aborted_cmd(struct scst_cmd *cmd, + struct list_head *list_entry) { - int res; + bool res; if (test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { - TRACE_MGMT_DBG("Adding aborted blocked cmd %p to active cmd " - "list", cmd); + list_del(list_entry); spin_lock(&cmd->cmd_lists->cmd_list_lock); list_add_tail(&cmd->cmd_list_entry, &cmd->cmd_lists->active_cmd_list); @@ -3472,8 +3483,11 @@ local_irq_disable(); list_for_each_entry_safe(cmd, tcmd, &dev->blocked_cmd_list, blocked_cmd_list_entry) { - if (__scst_check_unblock_aborted_cmd(cmd)) - list_del(&cmd->blocked_cmd_list_entry); + if (__scst_check_unblock_aborted_cmd(cmd, + &cmd->blocked_cmd_list_entry)) { + TRACE_MGMT_DBG("Unblock aborted blocked cmd %p", + cmd); + } } local_irq_enable(); spin_unlock_bh(&dev->dev_lock); @@ -3485,11 +3499,11 @@ list_for_each_entry_safe(cmd, tcmd, &tgt_dev->deferred_cmd_list, sn_cmd_list_entry) { - if (__scst_check_unblock_aborted_cmd(cmd)) { - TRACE_MGMT_DBG("Deleting aborted SN " - "cmd %p from SN list", cmd); + if (__scst_check_unblock_aborted_cmd(cmd, + &cmd->sn_cmd_list_entry)) { + TRACE_MGMT_DBG("Unblockd aborted SN " + "cmd %p", cmd); tgt_dev->def_cmd_count--; - list_del(&cmd->sn_cmd_list_entry); } } spin_unlock(&tgt_dev->sn_lock); @@ -4105,6 +4119,9 @@ if (scst_is_strict_mgmt_fn(mcmd->fn) && (mcmd->completed_cmd_count > 0)) mcmd->status = SCST_MGMT_STATUS_TASK_NOT_EXIST; + TRACE(TRACE_MGMT_MINOR, "TM command fn %d finished, status %x", + mcmd->fn, mcmd->status); + if (mcmd->sess->tgt->tgtt->task_mgmt_fn_done) { TRACE_DBG("Calling target %s task_mgmt_fn_done()", mcmd->sess->tgt->tgtt->name); @@ -4557,7 +4574,6 @@ TRACE_DBG("Deleting cmd %p from init deferred cmd list", cmd); list_del(&cmd->cmd_list_entry); atomic_dec(&sess->sess_cmd_count); - list_del(&cmd->search_cmd_list_entry); spin_unlock_irq(&sess->sess_list_lock); scst_cmd_init_done(cmd, SCST_CONTEXT_THREAD); spin_lock_irq(&sess->sess_list_lock); @@ -4666,12 +4682,13 @@ sess->shutdown_compl = NULL; #endif + TRACE_DBG("Adding sess %p to scst_sess_shut_list", sess); + list_add_tail(&sess->sess_shut_list_entry, &scst_sess_shut_list); + spin_unlock_irqrestore(&scst_mgmt_lock, flags); - tm_dbg_task_mgmt(NULL, "UNREGISTER SESSION", 1); + wake_up(&scst_mgmt_waitQ); - scst_sess_put(sess); - if (wait) { TRACE_DBG("Waiting for session %p to complete", sess); wait_for_completion(pc); @@ -4689,10 +4706,11 @@ { int i; struct scst_tgt_dev *tgt_dev; - unsigned long flags; TRACE_ENTRY(); + tm_dbg_task_mgmt(NULL, "UNREGISTER SESSION", 1); + mutex_lock(&scst_mutex); for(i = 0; i < TGT_DEV_HASH_SIZE; i++) { struct list_head *sess_tgt_dev_list_head = @@ -4713,10 +4731,7 @@ sess->shut_phase = SCST_SESS_SPH_SHUTDOWN; - spin_lock_irqsave(&scst_mgmt_lock, flags); - TRACE_DBG("Adding sess %p to scst_sess_shut_list", sess); - list_add_tail(&sess->sess_shut_list_entry, &scst_sess_shut_list); - spin_unlock_irqrestore(&scst_mgmt_lock, flags); + scst_sess_put(sess); TRACE_EXIT(); return; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-02-25 18:48:08
|
Revision: 295 http://scst.svn.sourceforge.net/scst/?rev=295&view=rev Author: vlnb Date: 2008-02-25 10:48:02 -0800 (Mon, 25 Feb 2008) Log Message: ----------- A bunch of pending changes: - Response data send timeout implemented: now if initiator doesn't accept data for too long (7 sec), target closes connection - Connction closing improved: now session cleared without need to wait for all outstanding commands data fully transmitted - On session unregistration now all outstanding commands are implicitely aborted - TM processing in SCST core made independant from other TM commands (before they were serialized) - Few bug fixes - Other minor improvements and cleanups - Docs update Modified Paths: -------------- trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/kernel/target.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/include/scst_const.h trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/include/iscsi_u.h 2008-02-25 18:48:02 UTC (rev 295) @@ -20,7 +20,7 @@ #include <sys/uio.h> #endif -#define ISCSI_VERSION_STRING "0.9.6/0.4.15r147" +#define ISCSI_VERSION_STRING "0.9.6/0.4.15r148" /* The maximum length of 223 bytes in the RFC. */ #define ISCSI_NAME_LEN 256 Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/conn.c 2008-02-25 18:48:02 UTC (rev 295) @@ -158,15 +158,21 @@ return; } -void mark_conn_closed(struct iscsi_conn *conn) +void __mark_conn_closed(struct iscsi_conn *conn, bool force) { spin_lock_bh(&iscsi_rd_lock); conn->closing = 1; + conn->force_close = force; spin_unlock_bh(&iscsi_rd_lock); iscsi_make_conn_rd_active(conn); } +void mark_conn_closed(struct iscsi_conn *conn) +{ + __mark_conn_closed(conn, 0); +} + static void iscsi_state_change(struct sock *sk) { struct iscsi_conn *conn = sk->sk_user_data; @@ -178,7 +184,7 @@ PRINT_ERROR("Connection with initiator %s (%p) " "unexpectedly closed!", conn->session->initiator_name, conn); - mark_conn_closed(conn); + __mark_conn_closed(conn, 1); } } else iscsi_make_conn_rd_active(conn); @@ -226,6 +232,45 @@ return; } +static void conn_rsp_timer_fn(unsigned long arg) +{ + struct iscsi_conn *conn = (struct iscsi_conn *)arg; + + TRACE_ENTRY(); + + TRACE_DBG("Timer (conn %p)", conn); + + spin_lock_bh(&conn->write_list_lock); + + if (!list_empty(&conn->written_list)) { + struct iscsi_cmnd *wr_cmd = list_entry(conn->written_list.next, + struct iscsi_cmnd, write_list_entry); + + if (unlikely(time_after_eq(jiffies, wr_cmd->write_timeout))) { + if (!conn->closing) { + PRINT_ERROR("Timeout sending data to initiator " + "%s (SID %Lx), closing connection", + conn->session->initiator_name, + conn->session->sid); + __mark_conn_closed(conn, 1); + } + } else { + TRACE_DBG("Restarting timer on %ld (conn %p)", + wr_cmd->write_timeout, conn); + /* + * Timer might have been restarted while we were + * entering here. + */ + mod_timer(&conn->rsp_timer, wr_cmd->write_timeout); + } + } + + spin_unlock_bh(&conn->write_list_lock); + + TRACE_EXIT(); + return; +} + static int iscsi_socket_bind(struct iscsi_conn *conn) { int res = 0; @@ -279,6 +324,8 @@ conn->session, (unsigned long long)conn->session->sid, conn->cid); + del_timer_sync(&conn->rsp_timer); + sBUG_ON(atomic_read(&conn->conn_ref_cnt) != 0); sBUG_ON(!list_empty(&conn->cmd_list)); sBUG_ON(!list_empty(&conn->write_list)); @@ -337,6 +384,8 @@ INIT_LIST_HEAD(&conn->cmd_list); spin_lock_init(&conn->write_list_lock); INIT_LIST_HEAD(&conn->write_list); + INIT_LIST_HEAD(&conn->written_list); + setup_timer(&conn->rsp_timer, conn_rsp_timer_fn, (unsigned long)conn); conn->file = fget(info->fd); Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-02-25 18:48:02 UTC (rev 295) @@ -179,7 +179,7 @@ kfree(cmnd->pdu.ahs); - if (unlikely(cmnd->on_write_list)) { + if (unlikely(cmnd->on_write_list || cmnd->on_written_list)) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); PRINT_ERROR("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x", @@ -211,6 +211,16 @@ EXTRACHECKS_BUG_ON(cmnd->on_rx_digest_list); + if (cmnd->on_written_list) { + struct iscsi_conn *conn = cmnd->conn; + TRACE_DBG("Deleting cmd %p from conn %p written_list", cmnd, + conn); + spin_lock_bh(&conn->write_list_lock); + list_del(&cmnd->write_list_entry); + cmnd->on_written_list = 0; + spin_unlock_bh(&conn->write_list_lock); + } + if (cmnd->parent_req == NULL) { struct iscsi_conn *conn = cmnd->conn; TRACE_DBG("Deleting req %p from conn %p", cmnd, conn); @@ -305,7 +315,7 @@ sBUG_ON(req == conn->read_cmnd); if (flags & ISCSI_FORCE_RELEASE_WRITE) { - spin_lock(&conn->write_list_lock); + spin_lock_bh(&conn->write_list_lock); list_for_each_entry_safe(rsp, t, &conn->write_list, write_list_entry) { if (rsp->parent_req != req) @@ -315,7 +325,7 @@ list_add_tail(&rsp->write_list_entry, &cmds_list); } - spin_unlock(&conn->write_list_lock); + spin_unlock_bh(&conn->write_list_lock); list_for_each_entry_safe(rsp, t, &cmds_list, write_list_entry) { list_del(&rsp->write_list_entry); @@ -338,18 +348,18 @@ spin_unlock_bh(&req->rsp_cmd_lock); - spin_lock(&conn->write_list_lock); + spin_lock_bh(&conn->write_list_lock); r = rsp->on_write_list || rsp->write_processing_started; - spin_unlock(&conn->write_list_lock); + spin_unlock_bh(&conn->write_list_lock); cmnd_put(rsp); if (r) - continue; + goto again_rsp; /* * If both on_write_list and write_processing_started not set, - * we can safely put() cmnd + * we can safely put() rsp. */ cmnd_put(rsp); goto again_rsp; @@ -488,6 +498,20 @@ (rsp->parent_req->outstanding_r2t == 0)) cmnd_remove_hash(rsp->parent_req); + if (!(conn->ddigest_type & DIGEST_NONE)) { + list_for_each(pos, send) { + rsp = list_entry(pos, struct iscsi_cmnd, + write_list_entry); + + if (rsp->pdu.datasize != 0) { + TRACE_DBG("Doing data digest (%p:%x)", rsp, + cmnd_opcode(rsp)); + digest_tx_data(rsp); + } + } + } + + spin_lock_bh(&conn->write_list_lock); list_for_each_safe(pos, next, send) { rsp = list_entry(pos, struct iscsi_cmnd, write_list_entry); @@ -495,16 +519,10 @@ sBUG_ON(conn != rsp->conn); - if (!(conn->ddigest_type & DIGEST_NONE) && - (rsp->pdu.datasize != 0)) - digest_tx_data(rsp); - list_del(&rsp->write_list_entry); - - spin_lock(&conn->write_list_lock); cmd_add_on_write_list(conn, rsp); - spin_unlock(&conn->write_list_lock); } + spin_unlock_bh(&conn->write_list_lock); if (flags & ISCSI_INIT_WRITE_WAKE) iscsi_make_conn_wr_active(conn); @@ -1090,6 +1108,17 @@ EXTRACHECKS_BUG_ON(scst_cmd_atomic(scst_cmd)); + if (scst_cmd_get_data_direction(scst_cmd) == SCST_DATA_READ) { + if (!(req->conn->ddigest_type & DIGEST_NONE)) + scst_set_long_xmit(scst_cmd); +#ifndef NET_PAGE_CALLBACKS_DEFINED + else if (cmnd_hdr(req)->data_length > 8*1024) + scst_set_long_xmit(scst_cmd); +#endif + EXTRACHECKS_BUG_ON(!list_empty(&req->rx_ddigest_cmd_list)); + goto out; + } + /* If data digest isn't used this list will be empty */ list_for_each_entry_safe(c, t, &req->rx_ddigest_cmd_list, rx_ddigest_cmd_list_entry) { @@ -2366,7 +2395,8 @@ * upon entrance in this function, because otherwise it could be destroyed * inside as a result of iscsi_send(), which releases sent commands. */ -static void iscsi_try_local_processing(struct iscsi_conn *conn) +static void iscsi_try_local_processing(struct iscsi_conn *conn, + bool single_only) { int local; @@ -2395,7 +2425,7 @@ int rc = 1; while(test_write_ready(conn)) { rc = iscsi_send(conn); - if (rc <= 0) { + if ((rc <= 0) || single_only) { break; } } @@ -2427,6 +2457,7 @@ u8 *sense = scst_cmd_get_sense_buffer(scst_cmd); int sense_len = scst_cmd_get_sense_buffer_len(scst_cmd); int old_state = req->scst_state; + bool single_only = !scst_get_long_xmit(scst_cmd); scst_cmd_set_tgt_priv(scst_cmd, NULL); @@ -2525,7 +2556,7 @@ conn_get_ordered(conn); req_cmnd_release(req); - iscsi_try_local_processing(conn); + iscsi_try_local_processing(conn, single_only); conn_put(conn); out: @@ -2667,12 +2698,15 @@ scst_mgmt_cmd_get_tgt_priv(scst_mcmd); int status = iscsi_get_mgmt_response(scst_mgmt_cmd_get_status(scst_mcmd)); - TRACE_MGMT_DBG("req %p, scst_mcmd %p, scst status %d", req, scst_mcmd, + TRACE_MGMT_DBG("req %p, scst_mcmd %p, fn %d, scst status %d", + req, scst_mcmd, scst_mgmt_cmd_get_fn(scst_mcmd), scst_mgmt_cmd_get_status(scst_mcmd)); iscsi_send_task_mgmt_resp(req, status); scst_mgmt_cmd_set_tgt_priv(scst_mcmd, NULL); + + return; } static int iscsi_target_detect(struct scst_tgt_template *templ) Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-02-25 18:48:02 UTC (rev 295) @@ -100,6 +100,7 @@ /* All 3 protected by sn_lock */ unsigned int tm_active:1; + unsigned int shutting_down:1; /* Let's save some cache footprint by putting it here */ u32 tm_sn; struct iscsi_cmnd *tm_rsp; @@ -113,6 +114,8 @@ struct list_head session_list_entry; + struct completion unreg_compl; + /* Both don't need any protection */ char *initiator_name; u64 sid; @@ -145,8 +148,12 @@ spinlock_t write_list_lock; /* List of data pdus to be sent, protected by write_list_lock */ - struct list_head write_list; + struct list_head write_list; + /* List of data pdus being sent, protected by write_list_lock */ + struct list_head written_list; + struct timer_list rsp_timer; + /* All 2 protected by iscsi_wr_lock */ unsigned short wr_state; unsigned short wr_space_ready:1; @@ -182,6 +189,7 @@ unsigned short rd_state; unsigned short rd_data_ready:1; unsigned short closing:1; /* Let's save some cache footprint by putting it here */ + unsigned short force_close:1; /* Let's save some cache footprint by putting it here */ struct list_head rd_list_entry; @@ -238,6 +246,7 @@ unsigned int force_cleanup_done:1; unsigned int dec_active_cmnds:1; unsigned int ddigest_checked:1; + unsigned int on_written_list:1; #ifdef EXTRACHECKS unsigned int on_rx_digest_list:1; unsigned int release_called:1; @@ -262,6 +271,8 @@ struct list_head write_list_entry; }; + unsigned long write_timeout; + /* * Unprotected, since could be accessed from only a single * thread at time @@ -306,6 +317,8 @@ /* Flags for req_cmnd_release_force() */ #define ISCSI_FORCE_RELEASE_WRITE 1 +#define ISCSI_RSP_TIMEOUT (7*HZ) + extern struct mutex target_mgmt_mutex; extern struct file_operations ctr_fops; @@ -336,6 +349,7 @@ 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 __mark_conn_closed(struct iscsi_conn *, bool); extern void mark_conn_closed(struct iscsi_conn *); extern void iscsi_make_conn_wr_active(struct iscsi_conn *); extern void conn_info_show(struct seq_file *, struct iscsi_session *); @@ -447,7 +461,7 @@ cmnd_done(cmnd); } -/* conn->write_list_lock supposed to be locked */ +/* conn->write_list_lock supposed to be locked and BHs off */ static inline void cmd_add_on_write_list(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) { @@ -456,7 +470,7 @@ cmnd->on_write_list = 1; } -/* conn->write_list_lock supposed to be locked */ +/* conn->write_list_lock supposed to be locked and BHs off */ static inline void cmd_del_from_write_list(struct iscsi_cmnd *cmnd) { TRACE_DBG("%p", cmnd); Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/nthread.c 2008-02-25 18:48:02 UTC (rev 295) @@ -165,6 +165,22 @@ static inline void iscsi_check_closewait(struct iscsi_conn *conn) {}; #endif +static void iscsi_unreg_cmds_done_fn(struct scst_session *scst_sess) +{ + struct iscsi_session *sess = + (struct iscsi_session *)scst_sess_get_tgt_priv(scst_sess); + + TRACE_ENTRY(); + + TRACE_CONN_CLOSE("sess %p (scst_sess %p)", sess, scst_sess); + + sess->shutting_down = 1; + complete_all(&sess->unreg_compl); + + TRACE_EXIT(); + return; +} + /* No locks */ static void close_conn(struct iscsi_conn *conn) { @@ -181,8 +197,13 @@ sBUG_ON(!conn->closing); - /* We want all our already send operations to complete */ - conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); + if (conn->force_close) { + conn->sock->ops->shutdown(conn->sock, + RCV_SHUTDOWN|SEND_SHUTDOWN); + } else { + /* We want all our already send operations to complete */ + conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); + } /* * We need to call scst_unregister_session() ASAP to make SCST start @@ -190,7 +211,8 @@ * * ToDo: this is incompatible with MC/S */ - scst_unregister_session(session->scst_sess, 0, NULL); + scst_unregister_session_ex(session->scst_sess, 0, + NULL, iscsi_unreg_cmds_done_fn); session->scst_sess = NULL; if (conn->read_state != RX_INIT_BHS) { @@ -269,8 +291,8 @@ } while(req_freed); spin_unlock(&session->sn_lock); - if (time_after(jiffies, start_waiting + 5*HZ)) { - TRACE_CONN_CLOSE("%s", "Wait time expired"); + if (time_after(jiffies, start_waiting + 10*HZ)) { + TRACE_CONN_CLOSE("%s", "Pending wait time expired"); spin_lock(&session->sn_lock); do { req_freed = 0; @@ -305,6 +327,12 @@ } iscsi_make_conn_wr_active(conn); + + if (time_after(jiffies, start_waiting + 7*HZ)) { + TRACE_CONN_CLOSE("%s", "Wait time expired"); + conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN); + } + msleep(200); TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " @@ -388,6 +416,8 @@ TRACE_CONN_CLOSE("Notifying user space about closing connection %p", conn); event_send(target->tid, session->sid, conn->cid, E_CONN_CLOSE, 0); + wait_for_completion(&session->unreg_compl); + mutex_lock(&target->target_mutex); conn_free(conn); /* ToDo: this is incompatible with MC/S */ @@ -453,14 +483,14 @@ { struct iscsi_cmnd *cmnd = NULL; - spin_lock(&conn->write_list_lock); + spin_lock_bh(&conn->write_list_lock); if (!list_empty(&conn->write_list)) { cmnd = list_entry(conn->write_list.next, struct iscsi_cmnd, write_list_entry); cmd_del_from_write_list(cmnd); cmnd->write_processing_started = 1; } - spin_unlock(&conn->write_list_lock); + spin_unlock_bh(&conn->write_list_lock); return cmnd; } @@ -862,6 +892,28 @@ else ref_cmd = write_cmnd; + if (!ref_cmd->on_written_list) { + TRACE_DBG("Adding cmd %p to conn %p written_list", ref_cmd, + conn); + spin_lock_bh(&conn->write_list_lock); + ref_cmd->on_written_list = 1; + ref_cmd->write_timeout = jiffies + ISCSI_RSP_TIMEOUT; + list_add_tail(&ref_cmd->write_list_entry, &conn->written_list); + spin_unlock_bh(&conn->write_list_lock); + } + + if (!timer_pending(&conn->rsp_timer)) { + sBUG_ON(!ref_cmd->write_timeout); + spin_lock_bh(&conn->write_list_lock); + if (likely(!timer_pending(&conn->rsp_timer))) { + TRACE_DBG("Starting timer on %ld (conn %p)", + ref_cmd->write_timeout, conn); + conn->rsp_timer.expires = ref_cmd->write_timeout; + add_timer(&conn->rsp_timer); + } + spin_unlock_bh(&conn->write_list_lock); + } + file = conn->file; saved_size = size = conn->write_size; iop = conn->write_iop; Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/session.c 2008-02-25 18:48:02 UTC (rev 295) @@ -22,7 +22,7 @@ struct iscsi_session *session; list_for_each_entry(session, &target->session_list, session_list_entry) { - if (session->sid == sid) + if ((session->sid == sid) && !session->shutting_down) return session; } return NULL; @@ -35,9 +35,6 @@ struct iscsi_session *session; char *name = NULL; - TRACE_MGMT_DBG("Creating session: target %p, tid %u, sid %#Lx", - target, target->tid, (unsigned long long) info->sid); - if (!(session = kzalloc(sizeof(*session), GFP_KERNEL))) return -ENOMEM; @@ -91,8 +88,14 @@ kfree(name); + scst_sess_set_tgt_priv(session->scst_sess, session); + init_completion(&session->unreg_compl); + list_add(&session->session_list_entry, &target->session_list); + TRACE_MGMT_DBG("Session %p created: target %p, tid %u, sid %#Lx", + session, target, target->tid, (unsigned long long) info->sid); + return 0; err: if (session) { @@ -110,8 +113,11 @@ int err = -EEXIST; session = session_lookup(target, info->sid); - if (session) + if (session) { + PRINT_ERROR("Attempt to add session with existing SID %Lx", + info->sid); return err; + } err = iscsi_session_alloc(target, info); Modified: trunk/iscsi-scst/kernel/target.c =================================================================== --- trunk/iscsi-scst/kernel/target.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/iscsi-scst/kernel/target.c 2008-02-25 18:48:02 UTC (rev 295) @@ -264,6 +264,8 @@ mutex_unlock(&target_mgmt_mutex); + TRACE_MGMT_DBG("%s", "Deleting all targets finished"); + TRACE_EXIT(); return; } Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/README 2008-02-25 18:48:02 UTC (rev 295) @@ -471,8 +471,11 @@ * "change NAME [PATH]" - changes a virtual CD in the VDISK CDROM. +By default, if neither BLOCKIO, nor NULLIO option is supplied, FILEIO +mode is used. + For example, "echo "open disk1 /vdisks/disk1" >/proc/scsi_tgt/vdisk/vdisk" -will open file /vdisks/disk1 as virtual VDISK disk with name "disk1". +will open file /vdisks/disk1 as virtual FILEIO disk with name "disk1". IMPORTANT: By default for performance reasons VDISK FILEIO devices use write ========= back caching policy. This is generally safe from the consistence of Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/include/scsi_tgt.h 2008-02-25 18:48:02 UTC (rev 295) @@ -140,14 +140,17 @@ *************************************************************/ /* LUN translation (mcmd->tgt_dev assignment) */ -#define SCST_MGMT_CMD_STATE_INIT 1 +#define SCST_MGMT_CMD_STATE_INIT 0 /* Mgmt cmd is ready for processing */ -#define SCST_MGMT_CMD_STATE_READY 2 +#define SCST_MGMT_CMD_STATE_READY 1 /* Mgmt cmd is being executing */ -#define SCST_MGMT_CMD_STATE_EXECUTING 3 +#define SCST_MGMT_CMD_STATE_EXECUTING 2 +/* Reservations are going to be cleared, if necessary */ +#define SCST_MGMT_CMD_STATE_CHECK_NEXUS_LOSS 3 + /* Target driver's task_mgmt_fn_done() is going to be called */ #define SCST_MGMT_CMD_STATE_DONE 4 @@ -167,15 +170,15 @@ /* * Direct cmd's processing (i.e. regular function calls in the current - * context), sleeping is allowed, no restrictions + * context) sleeping is not allowed */ -#define SCST_CONTEXT_DIRECT 0 +#define SCST_CONTEXT_DIRECT_ATOMIC 0 /* * Direct cmd's processing (i.e. regular function calls in the current - * context) sleeping is not allowed + * context), sleeping is allowed, no restrictions */ -#define SCST_CONTEXT_DIRECT_ATOMIC 1 +#define SCST_CONTEXT_DIRECT 1 /* Tasklet or thread context required for cmd's processing */ #define SCST_CONTEXT_TASKLET 2 @@ -183,6 +186,14 @@ /* Thread context required for cmd's processing */ #define SCST_CONTEXT_THREAD 3 +/* + * SCST internal flag, which specifies that context is processable, i.e. the + * next command in the active list will be processed after the current one. + * + * Target drivers must never use it!! + */ +#define SCST_CONTEXT_PROCESSABLE 0x100 + /************************************************************* ** Values for status parameter of scst_rx_data() *************************************************************/ @@ -677,6 +688,9 @@ struct scst_dev_type { + /* SCSI type of the supported device. MUST HAVE */ + int type; + /* * True, if corresponding function supports execution in * the atomic (non-sleeping) context @@ -688,6 +702,9 @@ /* Set, if no /proc files should be automatically created by SCST */ unsigned no_proc:1; + /* Set, if exec() is synchronous */ + unsigned exec_sync:1; + /* * Called to parse CDB from the cmd and initialize * cmd->bufflen and cmd->data_direction (both - REQUIRED). @@ -721,6 +738,10 @@ * by scst_cmd_atomic(): it is true if the function called in the * atomic (non-sleeping) context. * + * If this function provides sync execution, you must set above + * exec_sync flag and should consider to setup dedicated threads by + * setting threads_num > 0. + * * !! If this function is implemented, scst_check_local_events() shall !! * !! be called inside it just before the actual command's execution. !! * @@ -808,9 +829,6 @@ /* Name of the dev handler. Must be unique. MUST HAVE */ char name[15]; - /* SCSI type of the supported device. MUST HAVE */ - int type; - /* * Number of dedicated threads. If 0 - no dedicated threads will * be created, if <0 - creation of dedicated threads is prohibited. @@ -951,8 +969,9 @@ void (*init_result_fn) (struct scst_session *sess, void *data, int result); void (*unreg_done_fn) (struct scst_session *sess); + void (*unreg_cmds_done_fn) (struct scst_session *sess); -#ifdef MEASURE_LATENCY +#ifdef MEASURE_LATENCY /* must be last */ spinlock_t meas_lock; uint64_t scst_time, processing_time; unsigned int processed_cmds; @@ -1003,6 +1022,12 @@ /* Set if cmd is being processed in atomic context */ unsigned int atomic:1; + /* + * Set if the cmd is being processed in the processable context. See + * comment for SCST_CONTEXT_PROCESSABLE for what it means. + */ + unsigned int context_processable:1; + /* Set if cmd is internally generated */ unsigned int internal:1; @@ -1085,18 +1110,25 @@ /* Set if the cmd was done or aborted out of its SN */ unsigned int out_of_sn:1; - /* Set if the cmd is deferred HEAD OF QUEUE */ - unsigned int hq_deferred:1; + /* Set if increment expected_sn in cmd->scst_cmd_done() */ + unsigned int inc_expected_sn_on_done:1; /* - * Set if increment expected_sn in cmd->scst_cmd_done() (to save - * extra dereferences) + * Set if xmit_response() is going to need a considerable processing + * time. Processing time is considerable, if it's > context switch time + * (about 1 usec on modern systems). It's needed to trigger other + * threads to start processing other outstanding commands without + * waiting XMIT for the current one to finish. E.g., it should be set + * if iSCSI data digest used and cmd has READ direction. */ - unsigned int inc_expected_sn_on_done:1; + unsigned int long_xmit:1; /* Set if tgt_sn field is valid */ unsigned int tgt_sn_set:1; + /* Set if cmd is done */ + unsigned int done:1; + /* Set if cmd is finished */ unsigned int finished:1; @@ -1115,9 +1147,6 @@ lun_t lun; /* LUN for this cmd */ - /* The corresponding mgmt cmd, if any, protected by sess_list_lock */ - struct scst_mgmt_cmd *mgmt_cmnd; - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) struct scsi_request *scsi_req; /* SCSI request */ #endif @@ -1211,12 +1240,15 @@ */ int orig_sg_cnt, orig_sg_entry, orig_entry_len; + /* List corresponding mgmt cmd, if any, protected by sess_list_lock */ + struct list_head mgmt_cmd_list; + /* List entry for dev's blocked_cmd_list */ struct list_head blocked_cmd_list_entry; struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */ -#ifdef MEASURE_LATENCY +#ifdef MEASURE_LATENCY /* must be last */ uint64_t start, pre_exec_finish, post_exec_start; #endif }; @@ -1235,6 +1267,14 @@ unsigned char cmd_sn_set; }; +struct scst_mgmt_cmd_stub +{ + struct scst_mgmt_cmd *mcmd; + + /* List entry in cmd->mgmt_cmd_list */ + struct list_head cmd_mgmt_cmd_list_entry; +}; + struct scst_mgmt_cmd { /* List entry for *_mgmt_cmd_list */ @@ -1253,13 +1293,21 @@ unsigned int needs_unblocking:1; unsigned int lun_set:1; /* set, if lun field is valid */ unsigned int cmd_sn_set:1; /* set, if cmd_sn field is valid */ + unsigned int nexus_loss_check_active:1; /* set, if nexus loss check is active */ + unsigned int nexus_loss_check_done:1; /* set, if nexus loss check is done */ /* - * Number of commands to complete before sending response, + * Number of commands to finish before sending response, * protected by scst_mcmd_lock */ - int cmd_wait_count; + int cmd_finish_wait_count; + /* + * Number of commands to complete (done) before resetting reservation, + * protected by scst_mcmd_lock + */ + int cmd_done_wait_count; + /* Number of completed commands, protected by scst_mcmd_lock */ int completed_cmd_count; @@ -1633,6 +1681,11 @@ * the session is about to be completely freed. Can be NULL. * Parameter: * - sess - session + * unreg_cmds_done_fn - pointer to the function that will be + * asynchronously called when the last session's command completes, i.e. + * goes to XMIT stage. Can be NULL. + * Parameter: + * - sess - session * * Notes: * @@ -1652,9 +1705,16 @@ * but it also starts recovering stuck commands, if there are any. * Otherwise, your target driver could wait for those commands forever. */ -void scst_unregister_session(struct scst_session *sess, int wait, - void (*unreg_done_fn) (struct scst_session *sess)); +void scst_unregister_session_ex(struct scst_session *sess, int wait, + void (*unreg_done_fn) (struct scst_session *sess), + void (*unreg_cmds_done_fn) (struct scst_session *sess)); +static inline void scst_unregister_session(struct scst_session *sess, int wait, + void (*unreg_done_fn) (struct scst_session *sess)) +{ + scst_unregister_session_ex(sess, wait, unreg_done_fn, NULL); +} + /* * Registers dev handler driver * Returns 0 on success or appropriate error code otherwise @@ -2221,6 +2281,24 @@ } /* + * Get/set/clear functions for cmd's long XMIT flag. + */ +static inline int scst_get_long_xmit(struct scst_cmd *cmd) +{ + return cmd->long_xmit; +} + +static inline void scst_set_long_xmit(struct scst_cmd *cmd) +{ + cmd->long_xmit = 1; +} + +static inline void scst_clear_long_xmit(struct scst_cmd *cmd) +{ + cmd->long_xmit = 0; +} + +/* * Get/Set function for mgmt cmd's target private data */ static inline void *scst_mgmt_cmd_get_tgt_priv(struct scst_mgmt_cmd *mcmd) @@ -2242,6 +2320,14 @@ return mcmd->status; } +/* + * Returns mgmt cmd's TM fn + */ +static inline int scst_mgmt_cmd_get_fn(struct scst_mgmt_cmd *mcmd) +{ + return mcmd->fn; +} + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) static inline struct page *sg_page(struct scatterlist *sg) @@ -2390,7 +2476,8 @@ /* * Main SCST commands processing routing. Must be used only by dev handlers. * Argument context sets the execution context, only SCST_CONTEXT_DIRECT and - * SCST_CONTEXT_DIRECT_ATOMIC are allowed. + * SCST_CONTEXT_DIRECT_ATOMIC with optional SCST_CONTEXT_PROCESSABLE flag + * are allowed. */ void scst_process_active_cmd(struct scst_cmd *cmd, int context); Modified: trunk/scst/include/scst_const.h =================================================================== --- trunk/scst/include/scst_const.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/include/scst_const.h 2008-02-25 18:48:02 UTC (rev 295) @@ -70,6 +70,14 @@ /* Aborts all tasks in all sessions of the tgt */ #define SCST_ABORT_ALL_TASKS 9 +/* + * Internal TM command issued by SCST in scst_unregister_session(). It is the + * same as SCST_NEXUS_LOSS_SESS, except it calls unreg_cmds_done_fn(). + * + * Target driver shall NEVER use it!! + */ +#define SCST_UNREG_SESS_TM 10 + /************************************************************* ** Values for mgmt cmd's status field. Codes taken from iSCSI *************************************************************/ Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/include/scst_debug.h 2008-02-25 18:48:02 UTC (rev 295) @@ -93,7 +93,6 @@ #ifdef DEBUG //# define LOG_FLAG KERN_DEBUG # define LOG_FLAG KERN_INFO - # define INFO_FLAG KERN_INFO # define ERROR_FLAG KERN_INFO #else @@ -102,6 +101,8 @@ # define ERROR_FLAG KERN_ERR #endif +#define CRIT_FLAG KERN_CRIT + #define NO_FLAG "" #define TRACE_NULL 0x00000000 @@ -260,6 +261,16 @@ PRINT_LOG_FLAG(ERROR_FLAG, "***ERROR*** " format, args); \ } while(0) +#define PRINT_CRIT_ERROR(format, args...) \ +do { \ + if (strcmp(CRIT_FLAG, LOG_FLAG)) \ + { \ + PRINT_LOG_FLAG(LOG_FLAG, "***CRITICAL ERROR*** " format, args); \ + } \ + PRINT_LOG_FLAG(CRIT_FLAG, "***CRITICAL ERROR*** " format, args); \ +} while(0) + + #define PRINT_INFO(format, args...) \ do { \ if (strcmp(INFO_FLAG, LOG_FLAG)) \ @@ -361,6 +372,12 @@ format, LOG_PREFIX, args); \ } while(0) +#define PRINT_CRIT_ERROR(format, args...) \ +do { \ + PRINT(CRIT_FLAG, "%s: ***CRITICAL ERROR*** " \ + format, LOG_PREFIX, args); \ +} while(0) + #else #define PRINT_INFO(format, args...) \ @@ -374,6 +391,12 @@ format, args); \ } while(0) +#define PRINT_CRIT_ERROR(format, args...) \ +do { \ + PRINT(CRIT_FLAG, "***CRITICAL ERROR*** " \ + format, args); \ +} while(0) + #endif /* LOG_PREFIX */ #endif /* DEBUG */ Modified: trunk/scst/src/dev_handlers/scst_disk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_disk.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/dev_handlers/scst_disk.c 2008-02-25 18:48:02 UTC (rev 295) @@ -377,15 +377,17 @@ case READ_12: case READ_16: cmd->completed = 1; - break; + goto out_done; } +out: + TRACE_EXIT_RES(res); + return res; + out_done: res = SCST_EXEC_COMPLETED; cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); - - TRACE_EXIT_RES(res); - return res; + goto out; } MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar"); Modified: trunk/scst/src/dev_handlers/scst_modisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_modisk.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/dev_handlers/scst_modisk.c 2008-02-25 18:48:02 UTC (rev 295) @@ -392,15 +392,17 @@ case READ_12: case READ_16: cmd->completed = 1; - break; + goto out_done; } +out: + TRACE_EXIT_RES(res); + return res; + out_done: res = SCST_EXEC_COMPLETED; cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); - - TRACE_EXIT_RES(res); - return res; + goto out; } MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar"); Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/dev_handlers/scst_tape.c 2008-02-25 18:48:02 UTC (rev 295) @@ -416,15 +416,17 @@ case WRITE_6: case READ_6: cmd->completed = 1; - break; + goto out_done; } +out: + TRACE_EXIT_RES(res); + return res; + out_done: res = SCST_EXEC_COMPLETED; cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); - - TRACE_EXIT_RES(res); - return res; + goto out; } MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar"); Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-02-25 18:48:02 UTC (rev 295) @@ -1463,7 +1463,8 @@ TRACE_DBG("Deleting cmd %p from active cmd list", cmd); list_del(&cmd->cmd_list_entry); spin_unlock_irq(&dev->cmd_lists.cmd_list_lock); - scst_process_active_cmd(cmd, SCST_CONTEXT_DIRECT); + scst_process_active_cmd(cmd, SCST_CONTEXT_DIRECT | + SCST_CONTEXT_PROCESSABLE); spin_lock_irq(&dev->cmd_lists.cmd_list_lock); res++; } @@ -3101,16 +3102,15 @@ dev_user_sysfs_class = class_create(THIS_MODULE, DEV_USER_NAME); if (IS_ERR(dev_user_sysfs_class)) { - printk(KERN_ERR "Unable create sysfs class for SCST user " - "space handler\n"); + PRINT_ERROR("%s", "Unable create sysfs class for SCST user " + "space handler"); res = PTR_ERR(dev_user_sysfs_class); goto out_proc; } res = register_chrdev(DEV_USER_MAJOR, DEV_USER_NAME, &dev_user_fops); if (res) { - printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", - DEV_USER_MAJOR); + PRINT_ERROR("Unable to get major %d for SCSI tapes", DEV_USER_MAJOR); goto out_class; } Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-25 18:48:02 UTC (rev 295) @@ -256,6 +256,7 @@ #define VDISK_TYPE { \ name: VDISK_NAME, \ type: TYPE_DISK, \ + exec_sync: 1, \ threads_num: -1, \ parse_atomic: 1, \ exec_atomic: 0, \ @@ -291,6 +292,7 @@ #define VCDROM_TYPE { \ name: VCDROM_NAME, \ type: TYPE_ROM, \ + exec_sync: 1, \ threads_num: -1, \ parse_atomic: 1, \ exec_atomic: 0, \ @@ -1563,8 +1565,9 @@ } if (!(cmd->cdb[1] & PF) || (cmd->cdb[1] & SP)) { - PRINT_ERROR("MODE SELECT: PF and/or SP are wrongly set " - "(cdb[1]=%x)", cmd->cdb[1]); + TRACE(TRACE_MINOR|TRACE_SCSI, "MODE SELECT: Unsupported " + "value(s) of PF and/or SP bits (cdb[1]=%x)", + cmd->cdb[1]); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); goto out_put; @@ -1852,17 +1855,12 @@ TRACE_DBG("PERSIST/PREVENT 0x%02x", cmd->cdb[4]); - spin_lock(&virt_dev->flags_lock); - if (cmd->dev->handler->type == TYPE_ROM) + if (cmd->dev->handler->type == TYPE_ROM) { + spin_lock(&virt_dev->flags_lock); virt_dev->prevent_allow_medium_removal = cmd->cdb[4] & 0x01 ? 1 : 0; - else { - PRINT_ERROR("%s", "Prevent allow medium removal for " - "non-CDROM device"); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_opcode)); + spin_unlock(&virt_dev->flags_lock); } - spin_unlock(&virt_dev->flags_lock); return; } Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/scst_lib.c 2008-02-25 18:48:02 UTC (rev 295) @@ -52,7 +52,7 @@ cmd->sense = mempool_alloc(scst_sense_mempool, gfp_mask); if (cmd->sense == NULL) { - PRINT_ERROR("FATAL!!! Sense memory allocation failed (op %x). " + PRINT_CRIT_ERROR("Sense memory allocation failed (op %x). " "The sense data will be lost!!", cmd->cdb[0]); res = -ENOMEM; goto out; @@ -1010,7 +1010,7 @@ return; } -static void scst_send_release(struct scst_tgt_dev *tgt_dev) +static void scst_send_release(struct scst_device *dev) { struct scsi_request *req; struct scsi_device *scsi_dev; @@ -1018,10 +1018,10 @@ TRACE_ENTRY(); - if (tgt_dev->dev->scsi_dev == NULL) + if (dev->scsi_dev == NULL) goto out; - scsi_dev = tgt_dev->dev->scsi_dev; + scsi_dev = dev->scsi_dev; req = scsi_allocate_request(scsi_dev, GFP_KERNEL); if (req == NULL) { @@ -1042,7 +1042,7 @@ req->sr_use_sg = 0; req->sr_bufflen = 0; req->sr_buffer = NULL; - req->sr_request->rq_disk = tgt_dev->dev->rq_disk; + req->sr_request->rq_disk = dev->rq_disk; req->sr_sense_buffer[0] = 0; TRACE(TRACE_DEBUG | TRACE_SCSI, "Sending RELEASE req %p to SCSI " @@ -1055,7 +1055,7 @@ return; } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ -static void scst_send_release(struct scst_tgt_dev *tgt_dev) +static void scst_send_release(struct scst_device *dev) { struct scsi_device *scsi_dev; unsigned char cdb[6]; @@ -1064,13 +1064,13 @@ TRACE_ENTRY(); - if (tgt_dev->dev->scsi_dev == NULL) + if (dev->scsi_dev == NULL) goto out; /* We can't afford missing RELEASE due to memory shortage */ sense = kmalloc(SCST_SENSE_BUFFERSIZE, GFP_KERNEL|__GFP_NOFAIL); - scsi_dev = tgt_dev->dev->scsi_dev; + scsi_dev = dev->scsi_dev; for(i = 0; i < 5; i++) { memset(cdb, 0, sizeof(cdb)); @@ -1092,7 +1092,7 @@ PRINT_ERROR("RELEASE failed: %d", rc); PRINT_BUFFER("RELEASE sense", sense, SCST_SENSE_BUFFERSIZE); - scst_check_internal_sense(tgt_dev->dev, rc, + scst_check_internal_sense(dev, rc, sense, SCST_SENSE_BUFFERSIZE); } } @@ -1124,11 +1124,12 @@ &tgt_dev_tmp->tgt_dev_flags); } dev->dev_reserved = 0; + release = 1; } spin_unlock_bh(&dev->dev_lock); if (release) - scst_send_release(tgt_dev); + scst_send_release(dev); TRACE_EXIT(); return; @@ -1293,6 +1294,7 @@ cmd->state = SCST_CMD_STATE_INIT_WAIT; atomic_set(&cmd->cmd_ref, 1); cmd->cmd_lists = &scst_main_cmd_lists; + INIT_LIST_HEAD(&cmd->mgmt_cmd_list); cmd->queue_type = SCST_CMD_QUEUE_SIMPLE; cmd->timeout = SCST_DEFAULT_TIMEOUT; cmd->retries = 0; @@ -1473,7 +1475,7 @@ mcmd = mempool_alloc(scst_mgmt_mempool, gfp_mask); if (mcmd == NULL) { - PRINT_ERROR("%s", "Allocation of management command " + PRINT_CRIT_ERROR("%s", "Allocation of management command " "failed, some commands and their data could leak"); goto out; } @@ -1555,6 +1557,7 @@ int atomic = scst_cmd_atomic(cmd); int flags; struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; + int bufflen = cmd->bufflen; TRACE_ENTRY(); @@ -1563,7 +1566,21 @@ flags = atomic ? SCST_POOL_NO_ALLOC_ON_CACHE_MISS : 0; if (cmd->no_sgv) flags |= SCST_POOL_ALLOC_NO_CACHED; - cmd->sg = sgv_pool_alloc(tgt_dev->pool, cmd->bufflen, gfp_mask, flags, + + if (unlikely(cmd->bufflen == 0)) { + TRACE(TRACE_MGMT_MINOR, "Data direction %d or/and zero buffer " + "length. Opcode 0x%x, handler %s, target %s", + cmd->data_direction, cmd->cdb[0], + cmd->dev->handler->name, cmd->tgtt->name); + /* + * Be on the safe side and alloc stub buffer. Neither target + * drivers, nor user space will touch it, since bufflen + * remains 0. + */ + bufflen = PAGE_SIZE; + } + + cmd->sg = sgv_pool_alloc(tgt_dev->pool, bufflen, gfp_mask, flags, &cmd->sg_cnt, &cmd->sgv, NULL); if (cmd->sg == NULL) goto out; @@ -1749,16 +1766,6 @@ *op_flags = ptr->flags; *transfer_len = (*ptr->get_trans_len)(cdb_p, ptr->off); -#ifdef EXTRACHECKS - if (unlikely((*transfer_len == 0) && - (*direction != SCST_DATA_NONE) && - ((*op_flags & SCST_UNKNOWN_LENGTH) == 0))) { - PRINT_ERROR("transfer_len 0, direction %d, flags %x, changing " - "direction on NONE", *direction, *op_flags); - *direction = SCST_DATA_NONE; - } -#endif - out: TRACE_EXIT(); return res; @@ -2488,9 +2495,10 @@ UA_entry = mempool_alloc(scst_ua_mempool, GFP_ATOMIC); if (UA_entry == NULL) { - PRINT_ERROR("%s", "UNIT ATTENTION memory " + PRINT_CRIT_ERROR("%s", "UNIT ATTENTION memory " "allocation failed. The UNIT ATTENTION " "on some sessions will be missed"); + PRINT_BUFFER("Lost UA", sense, sense_len); goto out; } memset(UA_entry, 0, sizeof(*UA_entry)); @@ -2609,6 +2617,9 @@ spin_lock_irq(&tgt_dev->sn_lock); + if (unlikely(tgt_dev->hq_cmd_count != 0)) + goto out_unlock; + restart: list_for_each_entry_safe(cmd, t, &tgt_dev->deferred_cmd_list, sn_cmd_list_entry) { @@ -2935,16 +2946,14 @@ return; } -static struct scst_cmd *__scst_unblock_deferred( - struct scst_tgt_dev *tgt_dev, struct scst_cmd *out_of_sn_cmd) +static void __scst_unblock_deferred(struct scst_tgt_dev *tgt_dev, + struct scst_cmd *out_of_sn_cmd) { - struct scst_cmd *res = NULL; - EXTRACHECKS_BUG_ON(!out_of_sn_cmd->sn_set); if (out_of_sn_cmd->sn == tgt_dev->expected_sn) { scst_inc_expected_sn(tgt_dev, out_of_sn_cmd->sn_slot); - res = scst_check_deferred_commands(tgt_dev); + scst_make_deferred_commands_active(tgt_dev, out_of_sn_cmd); } else { out_of_sn_cmd->out_of_sn = 1; spin_lock_irq(&tgt_dev->sn_lock); @@ -2957,14 +2966,12 @@ spin_unlock_irq(&tgt_dev->sn_lock); } - return res; + return; } void scst_unblock_deferred(struct scst_tgt_dev *tgt_dev, struct scst_cmd *out_of_sn_cmd) { - struct scst_cmd *cmd; - TRACE_ENTRY(); if (!out_of_sn_cmd->sn_set) { @@ -2972,16 +2979,7 @@ goto out; } - cmd = __scst_unblock_deferred(tgt_dev, out_of_sn_cmd); - if (cmd != NULL) { - unsigned long flags; - spin_lock_irqsave(&cmd->cmd_lists->cmd_list_lock, flags); - TRACE_SN("cmd %p with sn %ld added to the head of active cmd " - "list", cmd, cmd->sn); - list_add(&cmd->cmd_list_entry, &cmd->cmd_lists->active_cmd_list); - wake_up(&cmd->cmd_lists->cmd_list_waitQ); - spin_unlock_irqrestore(&cmd->cmd_lists->cmd_list_lock, flags); - } + __scst_unblock_deferred(tgt_dev, out_of_sn_cmd); out: TRACE_EXIT(); @@ -3005,18 +3003,8 @@ * non-locked state. In the worst case we will only have * unneeded run of the deferred commands. */ - if (tgt_dev->hq_cmd_count == 0) { - struct scst_cmd *c = - scst_check_deferred_commands(tgt_dev); - if (c != NULL) { - spin_lock_irq(&c->cmd_lists->cmd_list_lock); - TRACE_SN("Adding cmd %p to active cmd list", c); - list_add_tail(&c->cmd_list_entry, - &c->cmd_lists->active_cmd_list); - wake_up(&c->cmd_lists->cmd_list_waitQ); - spin_unlock_irq(&c->cmd_lists->cmd_list_lock); - } - } + if (tgt_dev->hq_cmd_count == 0) + scst_make_deferred_commands_active(tgt_dev, cmd); TRACE_EXIT(); return; @@ -3026,6 +3014,12 @@ { TRACE_ENTRY(); + TRACE_MGMT_DBG("Aborted cmd %p done (cmd_ref %d, " + "scst_cmd_count %d)", cmd, atomic_read(&cmd->cmd_ref), + atomic_read(&scst_cmd_count)); + + scst_done_cmd_mgmt(cmd); + smp_rmb(); if (test_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags)) { if (cmd->completed) { Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/scst_main.c 2008-02-25 18:48:02 UTC (rev 295) @@ -76,6 +76,8 @@ struct kmem_cache *scst_mgmt_cachep; mempool_t *scst_mgmt_mempool; +struct kmem_cache *scst_mgmt_stub_cachep; +mempool_t *scst_mgmt_stub_mempool; struct kmem_cache *scst_ua_cachep; mempool_t *scst_ua_mempool; struct kmem_cache *scst_sense_cachep; @@ -1558,7 +1560,10 @@ } while (0) INIT_CACHEP(scst_mgmt_cachep, scst_mgmt_cmd, out); - INIT_CACHEP(scst_ua_cachep, scst_tgt_dev_UA, out_destroy_mgmt_cache); + INIT_CACHEP(scst_mgmt_stub_cachep, scst_mgmt_cmd_stub, + out_destroy_mgmt_cache); + INIT_CACHEP(scst_ua_cachep, scst_tgt_dev_UA, + out_destroy_mgmt_stub_cache); { struct scst_sense { uint8_t s[SCST_SENSE_BUFFERSIZE]; }; INIT_CACHEP(scst_sense_cachep, scst_sense, out_destroy_ua_cache); @@ -1568,18 +1573,25 @@ INIT_CACHEP(scst_tgtd_cachep, scst_tgt_dev, out_destroy_sess_cache); INIT_CACHEP(scst_acgd_cachep, scst_acg_dev, out_destroy_tgt_cache); - scst_mgmt_mempool = mempool_create(10, mempool_alloc_slab, + scst_mgmt_mempool = mempool_create(64, mempool_alloc_slab, mempool_free_slab, scst_mgmt_cachep); if (scst_mgmt_mempool == NULL) { res = -ENOMEM; goto out_destroy_acg_cache; } - scst_ua_mempool = mempool_create(25, mempool_alloc_slab, + scst_mgmt_stub_mempool = mempool_create(1024, mempool_alloc_slab, + mempool_free_slab, scst_mgmt_stub_cachep); + if (scst_mgmt_stub_mempool == NULL) { + res = -ENOMEM; + goto out_destroy_mgmt_mempool; + } + + scst_ua_mempool = mempool_create(64, mempool_alloc_slab, mempool_free_slab, scst_ua_cachep); if (scst_ua_mempool == NULL) { res = -ENOMEM; - goto out_destroy_mgmt_mempool; + goto out_destroy_mgmt_stub_mempool; } /* Loosing sense may have fatal consequences, so let's have a big pool */ @@ -1663,6 +1675,9 @@ out_destroy_ua_mempool: mempool_destroy(scst_ua_mempool); +out_destroy_mgmt_stub_mempool: + mempool_destroy(scst_mgmt_stub_mempool); + out_destroy_mgmt_mempool: mempool_destroy(scst_mgmt_mempool); @@ -1684,6 +1699,9 @@ out_destroy_ua_cache: kmem_cache_destroy(scst_ua_cachep); +out_destroy_mgmt_stub_cache: + kmem_cache_destroy(scst_mgmt_stub_cachep); + out_destroy_mgmt_cache: kmem_cache_destroy(scst_mgmt_cachep); goto out; @@ -1715,10 +1733,12 @@ } while (0) mempool_destroy(scst_mgmt_mempool); + mempool_destroy(scst_mgmt_stub_mempool); mempool_destroy(scst_ua_mempool); mempool_destroy(scst_sense_mempool); DEINIT_CACHEP(scst_mgmt_cachep); + DEINIT_CACHEP(scst_mgmt_stub_cachep); DEINIT_CACHEP(scst_ua_cachep); DEINIT_CACHEP(scst_sense_cachep); DEINIT_CACHEP(scst_cmd_cachep); @@ -1760,7 +1780,7 @@ * Target Driver Side (i.e. HBA) */ EXPORT_SYMBOL(scst_register_session); -EXPORT_SYMBOL(scst_unregister_session); +EXPORT_SYMBOL(scst_unregister_session_ex); EXPORT_SYMBOL(__scst_register_target_template); EXPORT_SYMBOL(scst_unregister_target_template); Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/scst_mem.c 2008-02-25 18:48:02 UTC (rev 295) @@ -493,7 +493,7 @@ { struct sgv_pool_obj *obj; int order, pages, cnt; - struct scatterlist *res; + struct scatterlist *res = NULL; int pages_to_alloc; struct kmem_cache *cache; int no_cached = flags & SCST_POOL_ALLOC_NO_CACHED; @@ -501,7 +501,8 @@ TRACE_ENTRY(); - sBUG_ON(size == 0); + if (unlikely(size == 0)) + goto out; pages = ((size + PAGE_SIZE - 1) >> PAGE_SHIFT); order = get_order(size); Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/scst_priv.h 2008-02-25 18:48:02 UTC (rev 295) @@ -96,9 +96,6 @@ /* Set if new commands initialization is suspended for a while */ #define SCST_FLAG_SUSPENDED 1 -/* Set if a TM command is being performed */ -#define SCST_FLAG_TM_ACTIVE 2 - /** ** Return codes for cmd state process functions **/ @@ -139,6 +136,7 @@ extern unsigned long scst_max_cmd_mem; extern mempool_t *scst_mgmt_mempool; +extern mempool_t *scst_mgmt_stub_mempool; extern mempool_t *scst_ua_mempool; extern mempool_t *scst_sense_mempool; @@ -228,6 +226,28 @@ return __scst_check_deferred_commands(tgt_dev); } +static inline void scst_make_deferred_commands_active( + struct scst_tgt_dev *tgt_dev, struct scst_cmd *curr_cmd) +{ + struct scst_cmd *c; + + c = __scst_check_deferred_commands(tgt_dev); + if (c != NULL) { + TRACE_SN("Adding cmd %p to active cmd list", c); + + EXTRACHECKS_BUG_ON(c->cmd_lists != curr_cmd->cmd_lists); + + spin_lock_irq(&c->cmd_lists->cmd_list_lock); + list_add_tail(&c->cmd_list_entry, + &c->cmd_lists->active_cmd_list); + if (!curr_cmd->context_processable || curr_cmd->long_xmit) + wake_up(&c->cmd_lists->cmd_list_waitQ); + spin_unlock_irq(&c->cmd_lists->cmd_list_lock); + } + + return; +} + void scst_inc_expected_sn(struct scst_tgt_dev *tgt_dev, atomic_t *slot); int scst_check_hq_cmd(struct scst_cmd *cmd); @@ -339,7 +359,7 @@ struct scst_mgmt_cmd *scst_alloc_mgmt_cmd(int gfp_mask); void scst_free_mgmt_cmd(struct scst_mgmt_cmd *mcmd); -void scst_complete_cmd_mgmt(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd); +void scst_done_cmd_mgmt(struct scst_cmd *cmd); /* /proc support */ int scst_proc_init_module(void); Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-02-19 12:02:14 UTC (rev 294) +++ trunk/scst/src/scst_targ.c 2008-02-25 18:48:02 UTC (rev 295) @@ -33,6 +33,7 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd); static int __scst_init_cmd(struct scst_cmd *cmd); +static void scst_finish_cmd_mgmt(struct scst_cmd *cmd); static inline void scst_schedule_tasklet(struct scst_cmd *cmd) { @@ -49,7 +50,7 @@ } /* - * Must not be called in parallel with scst_unregister_session() for the + * Must not be called in parallel with scst_unregister_session_ex() for the * same sess */ struct scst_cmd *scst_rx_cmd(struct scst_session *sess, @@ -316,8 +317,10 @@ TRACE_ENTRY(); - cmd->inc_expected_sn_on_done = !dev->has_own_order_mgmt && - (dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER); + cmd->inc_expected_sn_on_done = dev->handler->exec_sync || + (!dev->has_own_order_mgmt && + ((dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER) || + (cmd->queue_type == SCST_CMD_QUEUE_ORDERED))); sBUG_ON(cmd->internal); @@ -425,7 +428,6 @@ struct scst_device *dev = cmd->dev; int atomic = scst_cmd_atomic(cmd); int orig_bufflen = cmd->bufflen; - scst_data_direction orig_data_direction = cmd->data_direction; TRACE_ENTRY(); @@ -514,36 +516,35 @@ cmd->data_direction = cmd->expected_data_direction; cmd->bufflen = cmd->expected_transfer_len; #else - if (unlikely(cmd->data_direction != orig_data_direction)) { + if (unlikely(cmd->data_direction != cmd->expected_data_direction)) { PRINT_ERROR("Expected data direction %d for opcode " "0x%02x (handler %s, target %s) doesn't match " "decoded value %d", cmd->data_direction, cmd->cdb[0], dev->handler->name, - cmd->tgtt->name, orig_data_direction); + cmd->tgtt->name, cmd->expected_data_direction); scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_invalid_message)); goto out_dev_done; } if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) { - PRINT_INFO("Warning: expected transfer length %d for " - "opcode 0x%02x (handler %s, target %s) doesn't " - "match decoded value %d. Faulty initiator " - "(e.g. VMware is known to be such) or " + TRACE(TRACE_MINOR, "Warning: expected transfer length " + "%d for opcode 0x%02x (handler %s, target %s) " + "doesn't match decoded value %d. Faulty " + "initiator (e.g. VMware is known to be such) or " "scst_scsi_op_table should be updated?", cmd->expected_transfer_len, cmd->cdb[0], dev->handler->name, cmd->tgtt->name, cmd->bufflen); - PRINT_BUFFER("Suspicious CDB", cmd->cdb, cmd->cdb_len); + PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB", cmd->cdb, + cmd->cdb_len); } #endif } - if ((cmd->data_direction == SCST_DATA_UNKNOWN) || - ((cmd->bufflen == 0) && (cmd->data_direction != SCST_DATA_NONE))) { - PRINT_ERROR("Wrong data direction (%d) or/and buffer " - "length (%d). Opcode 0x%x, handler %s, target %s", - cmd->data_direction, cmd->bufflen, cmd->cdb[0], - dev->handler->name, cmd->tgtt->name); + if (unlikely(cmd->data_direction == SCST_DATA_UNKNOWN)) { + PRINT_ERROR("Unknown data direction. Opcode 0x%x, handler %s, " + "target %s", cmd->cdb[0], dev->handler->name, + cmd->tgtt->name); goto out_error; } @@ -618,6 +619,11 @@ if (r > 0) goto alloc; else if (r == 0) { + if (unlikely(cmd->bufflen == 0)) { + /* See comment in scst_alloc_space() */ + if (cmd->sg == NULL) + goto alloc; + } cmd->data_buf_alloced = 1; if (unlikely(orig_bufflen < cmd->bufflen)) { PRINT_ERROR("Target driver allocated data " @@ -626,16 +632,13 @@ cmd->bufflen); goto out_error; } - } else - goto check; + TRACE_MEM("%s", "data_buf_alloced, returning"); + } + goto check; } alloc: - if (!cmd->data_buf_alloced) { - r = scst_alloc_space(cmd); - } else { - TRACE_MEM("%s", "data_buf_alloced set, returning"); - } + r = scst_alloc_space(cmd); check: if (r != 0) { @@ -912,11 +915,13 @@ TRACE_ENTRY(); - TRACE_DBG("Context: %d", context); + TRACE_DBG("Context: %x", context); - switch(context) { + switch(context & ~SCST_CONTEXT_PROCESSABLE) { + case SCST_CONTEXT_DIRECT_ATOMIC: + context &= ~SCST_CONTEXT_PROCESSABLE; + /* go through */ case SCST_CONTEXT_DIRECT: - case SCST_CONTEXT_DIRECT_ATOMIC: if (check_retries) scst_check_retries(cmd->tgt); scst_process_active_cmd(cmd, context); @@ -1188,6 +1193,8 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state) { + int context; + TRACE_ENTRY(); #ifdef MEASURE_LATENCY @@ -1235,8 +1242,10 @@ #endif cmd->state = next_state; - scst_proccess_redirect_cmd(cmd, - scst_optimize_post_exec_context(cmd, scst_get_context()), 0); + context = scst_optimize_post_exec_context(cmd, scst_get_context()); + if (cmd->context_processable) + context |= SCST_CONTEXT_PROCESSABLE; + scst_proccess_redirect_cmd(cmd, context, 0); TRACE_EXIT(); return; @@ -1668,14 +1677,16 @@ static int scst_do_send_to_midlev(struct scst_cmd *cmd) { int rc = SCST_EXEC_NOT_COMPLETED; + struct scst_device *dev = cmd->dev; + struct scst_dev_type *handler = dev->handler; TRACE_ENTRY(); /* Check here to let an out of SN cmd be queued w/o context switch */ - if (scst_cmd_atomic(cmd) && !cmd->dev->handler->exec_atomic) { + if (scst_cmd_atomic(cmd) && !handler->exec_atomic) { TRACE_DBG("Dev handler %s exec() can not be " "called in atomic context, rescheduling to the thread", - cmd->dev->handler->name); + handler->name); rc = SCST_EXEC_NEED_THREAD; goto out; } @@ -1704,15 +1715,17 @@ goto out_rc_error; } - if (cmd->dev->handler->exec) { - struct scst_device *dev = cmd->dev; + if (!handler->exec_sync) + cmd->context_processable = 0; + + if (handler->exec) { TRACE_DBG("Calling dev handler %s exec(%p)", - dev->handler->name, cmd); + handler->name, cmd); TRACE_BUFF_FLAG(TRACE_SND_TOP, "Execing: ", cmd->cdb, cmd->cdb_len); cmd->scst_cmd_done = scst_cmd_done_local; - rc = dev->handler->exec(cmd); + rc = handler->exec(cmd); TRACE_DBG("Dev handler %s exec() returned %d", - dev->handler->name, rc); + handler->name, rc); if (rc == SCST_EXEC_COMPLETED) goto out; else if (rc == SCST_EXEC_NEED_THREAD) @@ -1723,7 +1736,7 @@ TRACE_DBG("Sending cmd %p to SCSI mid-level", cmd); - if (unlikely(cmd->dev->scsi_dev == NULL)) { + if (unlikely(dev->scsi_dev == NULL)) { PRINT_ERROR("Command for virtual device must be " "processed by device handler (lun %Ld)!", (uint64_t)cmd->lun); @@ -1751,7 +1764,7 @@ cmd->scsi_req->sr_bufflen, scst_cmd_done, cmd->timeout, cmd->retries); #else - rc = scst_exec_req(cmd->dev->scsi_dev, cmd->cdb, cmd->cdb_len, + rc = scst_exec_req(dev->scsi_dev, cmd->cdb, cmd->cdb_len, cmd->data_direction, cmd->sg, cmd->bufflen, cmd->sg_cnt, cmd->timeout, cmd->retries, cmd, scst_cmd_done, scst_cmd_atomic(cmd) ? GFP_ATOMIC : GFP_KERNEL); @@ -1780,7 +1793,7 @@ out_rc_error: PRINT_ERROR("Dev handler %s exec() or scst_local_exec() returned " - "invalid code %d", cmd->dev->handler->name, rc); + "invalid code %d", handler->name, rc); /* go through */ out_error: @@ -1953,6 +1966,7 @@ count = 0; while(1) { atomic_t *slot = cmd->sn_slot; + /* For HQ commands SN is not set */ int inc_expected_sn = !cmd->inc_expected_sn_on_done && cmd->sn_set; @@ -2359,21 +2373,10 @@ static void scst_inc_check_expected_sn(struct scst_cmd *cmd) { - struct scst_cmd *c; - if (likely(cmd->sn_set)) scst_inc_expected_sn(cmd->tgt_dev, cmd->sn_slot); - c = scst_check_deferred_commands(cmd->tgt_dev); - if (c != NULL) { - unsigned long flags; - spin_lock_irqsave(&c->cmd_lists->cmd_list_lock, flags); - TRACE_SN("Adding cmd %p to active cmd list", c); - list_add_tail(&c->cmd_list_entry, - &c->cmd_lists->active_cmd_list); - wake_up(&c->cmd_lists->cmd_list_waitQ); - spin_unlock_irqrestore(&c->cmd_lists->cmd_list_lock, flags); - } + scst_make_deferred_commands_active(cmd->tgt_dev, cmd); } static int scst_dev_done(struct scst_cmd *cmd) @@ -2503,6 +2506,9 @@ list_del(&cmd->search_cmd_list_entry); spin_unlock_irq(&cmd->sess->sess_list_lock); + cmd->done = 1; + smp_mb(); /* to sync with scst_abort_cmd() */ + if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) scst_xmit_process_aborted_cmd(cmd); @@ -2662,16 +2668,11 @@ smp_mb(); /* to sync with scst_abort_cmd() */ if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) { - unsigned long flags; - TRACE_MGMT_DBG("Aborted cmd %p finished (cmd_ref %d, " "scst_cmd_count %d)", cmd, atomic_read(&cmd->cmd_ref), atomic_read(&scst_cmd_count)); - spin_lock_irqsave(&scst_mcmd_lock, flags); - if (cmd->mgmt_cmnd) - scst_complete_cmd_mgmt(cmd, cmd->mgmt_cmnd); - spin_unlock_irqrestore(&scst_mcmd_lock, flags); + scst_finish_cmd_mgmt(cmd); } if (unlikely(cmd->delivery_status != SCST_CMD_DELIVERY_SUCCESS)) { @@ -2808,6 +2809,7 @@ tgt_dev->cur_sn_slot-tgt_dev->sn_slots); cmd->sn_set = 1; + out: return; } @@ -3060,8 +3062,13 @@ EXTRACHECKS_BUG_ON(in_irq()); + cmd->context_processable = context | SCST_CONTEXT_PROCESSABLE; + context &= ~SCST_CONTEXT_PROCESSABLE; cmd->atomic = (context == SCST_CONTEXT_DIRECT_ATOMIC); + TRACE_DBG("cmd %p, context_processable %d, atomic %d", cmd, + cmd->context_processable, cmd->atomic); + do { switch (cmd->state) { case SCST_CMD_STATE_PRE_PARSE: @@ -3189,8 +3196,11 @@ TRACE_ENTRY(); #ifdef EXTRACHECKS - WARN_ON((context != SCST_CONTEXT_DIRECT_ATOMIC) && - (context != SCST_CONTEXT_DIRECT)); + { + int c = context & ~SCST_CONTEXT_PROCESSABLE; + sBUG_ON((c != SCST_CONTEXT_DIRECT_ATOMIC) && + (c != SCST_CONTEXT_DIRECT)); + } #endif while (!list_empty(cmd_list)) { @@ -3255,7 +3265,8 @@ } scst_do_job_active(&p_cmd_lists->active_cmd_list, - &p_cmd_lists->cmd_list_lock, SCST_CONTEXT_DIRECT); + &p_cmd_lists->cmd_list_lock, SCST_CONTEXT_DIRECT | + SCST_CONTEXT_PROCESSABLE); } spin_unlock_irq(&p_cmd_lists->cmd_list_lock); @@ -3337,45 +3348,104 @@ return res; } -/* scst_mcmd_lock supposed to be held and IRQ off */ -void scst_complete_cmd_mgmt(struct scst_cmd *cmd, struct scst_mgmt_cmd *mcmd) +/* No locks */ +void scst_done_cmd_mgmt(struct scst_cmd *cmd) { + struct scst_mgmt_cmd_stub *mstb; + bool wake = 0; + unsigned long flags; + TRACE_ENTRY(); - TRACE_MGMT_DBG("cmd %p completed (tag %llu, mcmd %p, " - "mcmd->cmd_wait_count %d)", cmd, cmd->tag, mcmd, - mcmd->cmd_wait_count); + TRACE_MGMT_DBG("cmd %p done (tag %llu)", cmd, cmd->tag); - cmd->mgmt_cmnd = NULL; + spin_lock_irqsave(&scst_mcmd_lock, flags); - if (cmd->completed) - mcmd->completed_cmd_count++; + list_for_each_entry(mstb, &cmd->mgmt_cmd_list, + cmd_mgmt_cmd_list_entry) { + struct scst_mgmt_cmd *mcmd = mstb->mcmd; - mcmd->cmd_wait_count--; - if (mcmd->cmd_wait_count > ... [truncated message content] |
From: <vl...@us...> - 2008-02-26 18:22:49
|
Revision: 296 http://scst.svn.sourceforge.net/scst/?rev=296&view=rev Author: vlnb Date: 2008-02-26 10:22:45 -0800 (Tue, 26 Feb 2008) Log Message: ----------- - Fixes for previous commit - Minor logging improvements Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/session.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_cdbprobe.h trunk/scst/src/scst_lib.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/conn.c 2008-02-26 18:22:45 UTC (rev 296) @@ -329,6 +329,7 @@ sBUG_ON(atomic_read(&conn->conn_ref_cnt) != 0); sBUG_ON(!list_empty(&conn->cmd_list)); sBUG_ON(!list_empty(&conn->write_list)); + sBUG_ON(!list_empty(&conn->written_list)); list_del(&conn->conn_list_entry); Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-02-26 18:22:45 UTC (rev 296) @@ -113,7 +113,7 @@ static inline void iscsi_fail_waiting_cmnd(struct iscsi_cmnd *cmnd) { - TRACE_DBG("Failing data waiting cmd %p", cmnd); + TRACE_MGMT_DBG("Failing data waiting cmd %p", cmnd); /* * There is no race with conn_abort(), since all functions @@ -182,7 +182,7 @@ if (unlikely(cmnd->on_write_list || cmnd->on_written_list)) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); - PRINT_ERROR("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x", + PRINT_CRIT_ERROR("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x", 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)); @@ -190,7 +190,7 @@ if (unlikely(cmnd->parent_req)) { struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->parent_req); - PRINT_ERROR("%p %x %u", req, req->opcode, req->scb[0]); + PRINT_CRIT_ERROR("%p %x %u", req, req->opcode, req->scb[0]); } sBUG(); } @@ -254,7 +254,7 @@ scst_tgt_cmd_done(cmnd->scst_cmd); break; default: - PRINT_ERROR("Unexpected cmnd scst state %d", + PRINT_CRIT_ERROR("Unexpected cmnd scst state %d", cmnd->scst_state); sBUG(); break; @@ -290,6 +290,13 @@ "new value %d)", cmnd, sess, atomic_read(&sess->active_cmds)-1); atomic_dec(&sess->active_cmds); +#ifdef EXTRACHECKS + if (unlikely(atomic_read(&sess->active_cmds) < 0)) { + PRINT_CRIT_ERROR("active_cmds < 0 (%d)!!", + atomic_read(&sess->active_cmds)); + sBUG(); + } +#endif } cmnd_free(cmnd); @@ -310,7 +317,7 @@ TRACE_ENTRY(); - TRACE_DBG("%p", req); + TRACE_MGMT_DBG("%p", req); sBUG_ON(req == conn->read_cmnd); @@ -328,6 +335,7 @@ spin_unlock_bh(&conn->write_list_lock); list_for_each_entry_safe(rsp, t, &cmds_list, write_list_entry) { + TRACE_MGMT_DBG("Putting write rsp %p", rsp); list_del(&rsp->write_list_entry); cmnd_put(rsp); } @@ -361,6 +369,7 @@ * If both on_write_list and write_processing_started not set, * we can safely put() rsp. */ + TRACE_MGMT_DBG("Putting rsp %p", rsp); cmnd_put(rsp); goto again_rsp; } @@ -412,6 +421,13 @@ atomic_read(&sess->active_cmds)-1); atomic_dec(&sess->active_cmds); req->dec_active_cmnds = 0; +#ifdef EXTRACHECKS + if (unlikely(atomic_read(&sess->active_cmds) < 0)) { + PRINT_CRIT_ERROR("active_cmds < 0 (%d)!!", + atomic_read(&sess->active_cmds)); + sBUG(); + } +#endif } cmnd_put(req); @@ -533,7 +549,7 @@ LIST_HEAD(head); if (unlikely(rsp->on_write_list)) { - PRINT_ERROR("cmd already on write list (%x %x %x %x %u %u " + PRINT_CRIT_ERROR("cmd already on write list (%x %x %x %x %u %u " "%u %u %u %u %u %d %d", cmnd_itt(rsp), cmnd_ttt(rsp), cmnd_opcode(rsp), cmnd_scsicode(rsp), rsp->r2t_sn, @@ -1605,8 +1621,10 @@ cmnd_put(cmnd); err = 0; - } else + } else { + TRACE_MGMT_DBG("cmd RTT %x not found", req_hdr->rtt); err = ISCSI_RESPONSE_UNKNOWN_TASK; + } out: return err; @@ -1834,6 +1852,7 @@ ISCSI_RESPONSE_FUNCTION_UNSUPPORTED); break; default: + PRINT_ERROR("Unknown TM function %d", function); iscsi_send_task_mgmt_resp(req, ISCSI_RESPONSE_FUNCTION_REJECTED); break; @@ -2076,7 +2095,7 @@ case ISCSI_OP_LOGOUT_RSP: break; default: - PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_CRIT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); sBUG(); break; } @@ -2497,7 +2516,7 @@ if (unlikely((req->bufflen != 0) && !(resp_flags & SCST_TSC_FLAG_STATUS))) { - PRINT_ERROR("%s", "Sending DATA without STATUS is unsupported"); + PRINT_CRIT_ERROR("%s", "Sending DATA without STATUS is unsupported"); scst_set_cmd_error(scst_cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-02-26 18:22:45 UTC (rev 296) @@ -235,7 +235,10 @@ struct iscsi_cmnd { struct iscsi_conn *conn; - /* Some flags protected by conn->write_list_lock */ + /* + * Some flags protected by conn->write_list_lock, but all modified only + * from single read thread or when there are no references to cmd. + */ unsigned int hashed:1; unsigned int should_close_conn:1; unsigned int pending:1; @@ -246,7 +249,6 @@ unsigned int force_cleanup_done:1; unsigned int dec_active_cmnds:1; unsigned int ddigest_checked:1; - unsigned int on_written_list:1; #ifdef EXTRACHECKS unsigned int on_rx_digest_list:1; unsigned int release_called:1; @@ -271,6 +273,8 @@ struct list_head write_list_entry; }; + /* Both modified only from single write thread */ + unsigned int on_written_list:1; unsigned long write_timeout; /* Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-26 18:22:45 UTC (rev 296) @@ -35,7 +35,7 @@ #ifdef DEBUG #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_LINE | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | \ - TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC) + TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC | TRACE_CONN_OC_DBG) #else #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ TRACE_MINOR | TRACE_SPECIAL) Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/nthread.c 2008-02-26 18:22:45 UTC (rev 296) @@ -63,7 +63,7 @@ if ((conn->sock->sk->sk_state != TCP_CLOSE_WAIT) && (conn->sock->sk->sk_state != TCP_CLOSE)) { - TRACE_CONN_CLOSE_DBG("sk_state %d, skipping", + TRACE_CONN_CLOSE("sk_state %d, skipping", conn->sock->sk->sk_state); goto out; } @@ -407,7 +407,16 @@ conn->sock->sk->sk_write_space = conn->old_write_space; write_unlock_bh(&conn->sock->sk->sk_callback_lock); - while(conn->wr_state != ISCSI_CONN_WR_STATE_IDLE) { + while(1) { + bool t; + + spin_lock_bh(&iscsi_wr_lock); + t = (conn->wr_state == ISCSI_CONN_WR_STATE_IDLE); + spin_unlock_bh(&iscsi_wr_lock); + + if (t && (atomic_read(&conn->conn_ref_cnt) == 0)) + break; + TRACE_CONN_CLOSE("Waiting for wr thread (conn %p), wr_state %x", conn, conn->wr_state); msleep(50); @@ -418,6 +427,8 @@ wait_for_completion(&session->unreg_compl); + sBUG_ON(!session->shutting_down); + mutex_lock(&target->target_mutex); conn_free(conn); /* ToDo: this is incompatible with MC/S */ @@ -681,7 +692,7 @@ } break; default: - PRINT_ERROR("%d %x", conn->read_state, cmnd_opcode(cmnd)); + PRINT_CRIT_ERROR("%d %x", conn->read_state, cmnd_opcode(cmnd)); sBUG(); } @@ -692,7 +703,8 @@ goto out; if (unlikely(conn->read_size)) { - PRINT_ERROR("%d %x %d", res, cmnd_opcode(cmnd), conn->read_size); + PRINT_CRIT_ERROR("%d %x %d", res, cmnd_opcode(cmnd), + conn->read_size); sBUG(); } @@ -903,7 +915,7 @@ } if (!timer_pending(&conn->rsp_timer)) { - sBUG_ON(!ref_cmd->write_timeout); + sBUG_ON(!ref_cmd->on_written_list); spin_lock_bh(&conn->write_list_lock); if (likely(!timer_pending(&conn->rsp_timer))) { TRACE_DBG("Starting timer on %ld (conn %p)", @@ -989,7 +1001,7 @@ #ifdef NET_PAGE_CALLBACKS_DEFINED if (unlikely((sg_page(&sg[idx])->net_priv != NULL) && (sg_page(&sg[idx])->net_priv != ref_cmd))) { - PRINT_ERROR("net_priv isn't NULL and != ref_cmd " + PRINT_CRIT_ERROR("net_priv isn't NULL and != ref_cmd " "(write_cmnd %p, ref_cmd %p, sg %p, idx %d, " "net_priv %p)", write_cmnd, ref_cmd, sg, idx, sg_page(&sg[idx])->net_priv); @@ -1200,7 +1212,7 @@ res = tx_ddigest(cmnd, TX_END); break; default: - PRINT_ERROR("%d %d %x", res, conn->write_state, + PRINT_CRIT_ERROR("%d %d %x", res, conn->write_state, cmnd_opcode(cmnd)); sBUG(); } @@ -1212,7 +1224,7 @@ goto out; if (unlikely(conn->write_size)) { - PRINT_ERROR("%d %x %u", res, cmnd_opcode(cmnd), + PRINT_CRIT_ERROR("%d %x %u", res, cmnd_opcode(cmnd), conn->write_size); sBUG(); } Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/iscsi-scst/kernel/session.c 2008-02-26 18:22:45 UTC (rev 296) @@ -134,7 +134,7 @@ sBUG_ON(!list_empty(&session->conn_list)); if (unlikely(atomic_read(&session->active_cmds) != 0)) { - PRINT_ERROR("active_cmds not 0 (%d)!!", + PRINT_CRIT_ERROR("active_cmds not 0 (%d)!!", atomic_read(&session->active_cmds)); sBUG(); } Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-02-26 18:22:45 UTC (rev 296) @@ -1946,7 +1946,7 @@ } default: - PRINT_ERROR("Wrong ucmd state %x", state); + PRINT_CRIT_ERROR("Wrong ucmd state %x", state); sBUG(); break; } Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/scst/src/scst_cdbprobe.h 2008-02-26 18:22:45 UTC (rev 296) @@ -118,7 +118,7 @@ {0x03, "MMMMMMMMMMMMMMMM", "REQUEST SENSE", SCST_DATA_READ, SCST_SMALL_TIMEOUT, 4, get_trans_len_1}, {0x04, "M O O ", "FORMAT UNIT", - SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none}, + SCST_DATA_WRITE, SCST_LONG_TIMEOUT|SCST_UNKNOWN_LENGTH, 0, get_trans_len_none}, {0x04, " O ", "FORMAT", SCST_DATA_NONE, FLAG_NONE, 0, get_trans_len_none}, {0x05, "VMVVVV V ", "READ BLOCK LIMITS", Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/scst/src/scst_lib.c 2008-02-26 18:22:45 UTC (rev 296) @@ -260,7 +260,7 @@ #ifdef EXTRACHECKS if (!list_empty(&dev->dev_tgt_dev_list) || !list_empty(&dev->dev_acg_dev_list)) { - PRINT_ERROR("%s: dev_tgt_dev_list or dev_acg_dev_list " + PRINT_CRIT_ERROR("%s: dev_tgt_dev_list or dev_acg_dev_list " "is not empty!", __FUNCTION__); sBUG(); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-02-25 18:48:02 UTC (rev 295) +++ trunk/scst/src/scst_targ.c 2008-02-26 18:22:45 UTC (rev 296) @@ -63,7 +63,7 @@ #ifdef EXTRACHECKS if (unlikely(sess->shut_phase != SCST_SESS_SPH_READY)) { - PRINT_ERROR("%s", "New cmd while shutting down the session"); + PRINT_CRIT_ERROR("%s", "New cmd while shutting down the session"); sBUG(); } #endif @@ -381,13 +381,15 @@ if (scst_cmd_is_expected_set(cmd)) { /* * Command data length can't be easily - * determined from the CDB. ToDo, that should - * be fixed. Until it's fixed, get it from - * the supplied expected value, but - * limit it to some reasonable value (15MB). + * determined from the CDB. ToDo, all such + * commands should be fixed. Until they are + * fixed, get it from the supplied expected + * value, but limit it to some reasonable + * value (15MB). */ cmd->bufflen = min(cmd->expected_transfer_len, 15*1024*1024); + cmd->op_flags &= ~SCST_UNKNOWN_LENGTH; } else cmd->bufflen = 0; } @@ -3136,8 +3138,8 @@ break; default: - PRINT_ERROR("cmd (%p) in state %d, but shouldn't be", - cmd, cmd->state); + PRINT_CRIT_ERROR("cmd (%p) in state %d, but shouldn't " + "be", cmd, cmd->state); sBUG(); res = SCST_CMD_STATE_RES_CONT_NEXT; break; @@ -3169,7 +3171,7 @@ /* not very valid commands */ case SCST_CMD_STATE_DEFAULT: case SCST_CMD_STATE_NEED_THREAD_CTX: - PRINT_ERROR("cmd %p is in state %d, not putting on " + PRINT_CRIT_ERROR("cmd %p is in state %d, not putting on " "useful list (left on scst cmd list)", cmd, cmd->state); spin_unlock_irq(&cmd->cmd_lists->cmd_list_lock); @@ -4575,7 +4577,7 @@ scst_sess_get(sess); if (unlikely(sess->shut_phase != SCST_SESS_SPH_READY)) { - PRINT_ERROR("New mgmt cmd while shutting down the session %p " + PRINT_CRIT_ERROR("New mgmt cmd while shutting down the session %p " "shut_phase %ld", sess, sess->shut_phase); sBUG(); } @@ -5024,7 +5026,7 @@ if (sess->init_phase == SCST_SESS_IPH_INITING) scst_init_session(sess); else { - PRINT_ERROR("session %p is in " + PRINT_CRIT_ERROR("session %p is in " "scst_sess_init_list, but in unknown " "init phase %x", sess, sess->init_phase); @@ -5051,7 +5053,7 @@ scst_free_session_callback(sess); break; default: - PRINT_ERROR("session %p is in " + PRINT_CRIT_ERROR("session %p is in " "scst_sess_shut_list, but in unknown " "shut phase %lx", sess, sess->shut_phase); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-02-29 18:26:00
|
Revision: 297 http://scst.svn.sourceforge.net/scst/?rev=297&view=rev Author: vlnb Date: 2008-02-29 10:25:56 -0800 (Fri, 29 Feb 2008) Log Message: ----------- - TM fixes - Optimizations and send timeout introduced in r295 temporary disabled - Big connection shutdown times improvements. Great thanks to Alexey Kuznetsov for suggestions! - RESERVE/RELEASE serialization now made with TST field 0 (i.e. single task set) - Other minor fixes and improvements Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_dbg.h trunk/iscsi-scst/kernel/nthread.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_priv.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/README 2008-02-29 18:25:56 UTC (rev 297) @@ -115,15 +115,6 @@ like 8 (default is 32). See also SCST README file for more details about that issue. -Sometimes, when there are communication problems with initiator(s), -shutting down iSCSI-SCST can take very long time, up to about 10 -minutes. This can happen, because iSCSI-SCST can't be shutdown before -all already sent to TCP for initiator(s) data will be actually sent -and/or released by TCP. In case of communication failures this can take -up to TCP transmit timeout, which is about 10 minutes. In such cases -using netstat utility you can see that there is/are connection(s) to -initiator(s) with non-0 "Send-Q". - CAUTION: Working of target and initiator on the same host isn't ======== supported. See SCST README file for details. Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-02-29 18:25:56 UTC (rev 297) @@ -1742,7 +1742,7 @@ struct iscsi_session *sess = conn->session; struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; - int err = 0, function = req_hdr->function & ISCSI_FUNCTION_MASK; + int rc, status, function = req_hdr->function & ISCSI_FUNCTION_MASK; struct scst_rx_mgmt_params params; TRACE((function == ISCSI_FUNCTION_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, @@ -1754,13 +1754,20 @@ iscsi_extracheck_is_rd_thread(conn); spin_lock(&sess->sn_lock); - sess->tm_active = 1; + sess->tm_active++; sess->tm_sn = req_hdr->cmd_sn; if (sess->tm_rsp != NULL) { struct iscsi_cmnd *tm_rsp = sess->tm_rsp; + TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); + sess->tm_rsp = NULL; + sess->tm_active--; + spin_unlock(&sess->sn_lock); + + sBUG_ON(sess->tm_active < 0); + rsp_cmnd_release(tm_rsp); } else spin_unlock(&sess->sn_lock); @@ -1773,7 +1780,8 @@ (req_hdr->rtt != ISCSI_RESERVED_TAG)) { PRINT_ERROR("Invalid RTT %x (TM fn %x)", req_hdr->rtt, function); - err = -1; + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_REJECTED; goto reject; } @@ -1781,8 +1789,9 @@ switch (function) { case ISCSI_FUNCTION_ABORT_TASK: - err = cmnd_abort(req); - if (err == 0) { + rc = -1; + status = cmnd_abort(req); + if (status == 0) { params.fn = SCST_ABORT_TASK; params.tag = req_hdr->rtt; params.tag_set = 1; @@ -1791,8 +1800,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; } break; case ISCSI_FUNCTION_ABORT_TASK_SET: @@ -1803,8 +1813,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_CLEAR_TASK_SET: task_set_abort(req); @@ -1814,8 +1825,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_CLEAR_ACA: params.fn = SCST_CLEAR_ACA; @@ -1824,8 +1836,9 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_TARGET_COLD_RESET: case ISCSI_FUNCTION_TARGET_WARM_RESET: @@ -1833,8 +1846,9 @@ params.fn = SCST_TARGET_RESET; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: target_abort(req, 0); @@ -1844,25 +1858,26 @@ params.lun_set = 1; params.cmd_sn = req_hdr->cmd_sn; params.cmd_sn_set = 1; - err = scst_rx_mgmt_fn(conn->session->scst_sess, + rc = scst_rx_mgmt_fn(conn->session->scst_sess, ¶ms); + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; case ISCSI_FUNCTION_TASK_REASSIGN: - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_UNSUPPORTED); + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; break; default: PRINT_ERROR("Unknown TM function %d", function); - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_REJECTED); + rc = -1; + status = ISCSI_RESPONSE_FUNCTION_REJECTED; break; } reject: - if (err != 0) { - iscsi_send_task_mgmt_resp(req, - ISCSI_RESPONSE_FUNCTION_REJECTED); - } + if (rc != 0) + iscsi_send_task_mgmt_resp(req, status); + + return; } static void noop_out_exec(struct iscsi_cmnd *req) @@ -2140,7 +2155,7 @@ while (1) { session->exp_cmd_sn = ++cmd_sn; - if (unlikely(session->tm_active)) { + if (unlikely(session->tm_active > 0)) { if (before(cmd_sn, session->tm_sn)) { struct iscsi_conn *conn = cmnd->conn; @@ -2476,7 +2491,11 @@ u8 *sense = scst_cmd_get_sense_buffer(scst_cmd); int sense_len = scst_cmd_get_sense_buffer_len(scst_cmd); int old_state = req->scst_state; +#if 0 /* temp. ToDo */ bool single_only = !scst_get_long_xmit(scst_cmd); +#else + bool single_only = 0; +#endif scst_cmd_set_tgt_priv(scst_cmd, NULL); @@ -2622,10 +2641,12 @@ TRACE(TRACE_MGMT_MINOR, "Sending delayed rsp %p", tm_rsp); sess->tm_rsp = NULL; - sess->tm_active = 0; + sess->tm_active--; spin_unlock(&sess->sn_lock); + sBUG_ON(sess->tm_active < 0); + iscsi_cmnd_init_write(tm_rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); @@ -2676,9 +2697,11 @@ spin_unlock(&sess->sn_lock); goto out_release; } - sess->tm_active = 0; + sess->tm_active--; spin_unlock(&sess->sn_lock); + sBUG_ON(sess->tm_active < 0); + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-02-29 18:25:56 UTC (rev 297) @@ -99,8 +99,7 @@ u32 exp_cmd_sn; /* protected by sn_lock */ /* All 3 protected by sn_lock */ - unsigned int tm_active:1; - unsigned int shutting_down:1; /* Let's save some cache footprint by putting it here */ + int tm_active; u32 tm_sn; struct iscsi_cmnd *tm_rsp; @@ -118,6 +117,7 @@ /* Both don't need any protection */ char *initiator_name; + unsigned int shutting_down:1; u64 sid; }; Modified: trunk/iscsi-scst/kernel/iscsi_dbg.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/iscsi_dbg.h 2008-02-29 18:25:56 UTC (rev 297) @@ -35,7 +35,7 @@ #ifdef DEBUG #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_FUNCTION | TRACE_LINE | TRACE_PID | \ TRACE_OUT_OF_MEM | TRACE_MGMT | TRACE_MGMT_MINOR | TRACE_MGMT_DEBUG | \ - TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC | TRACE_CONN_OC_DBG) + TRACE_MINOR | TRACE_SPECIAL | TRACE_CONN_OC) #else #define ISCSI_DEFAULT_LOG_FLAGS (TRACE_OUT_OF_MEM | TRACE_MGMT | \ TRACE_MINOR | TRACE_SPECIAL) Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/iscsi-scst/kernel/nthread.c 2008-02-29 18:25:56 UTC (rev 297) @@ -61,16 +61,17 @@ TRACE_ENTRY(); - if ((conn->sock->sk->sk_state != TCP_CLOSE_WAIT) && - (conn->sock->sk->sk_state != TCP_CLOSE)) { - TRACE_CONN_CLOSE("sk_state %d, skipping", - conn->sock->sk->sk_state); + TRACE_CONN_CLOSE("conn %p, sk_state %d", conn, conn->sock->sk->sk_state); + + if (conn->sock->sk->sk_state != TCP_CLOSE) { + TRACE_CONN_CLOSE_DBG("conn %p, skipping", conn); goto out; } /* - * No data are going to be sent, so all being sent buffers can be freed - * now. Strange that TCP doesn't do that itself. + * No data are going to be sent, so all queued buffers can be freed + * now. In many cases TCP does that only in close(), but we can't rely + * on user space on calling it. */ again: @@ -235,7 +236,8 @@ TRACE(TRACE_MGMT_MINOR, "Dropping delayed TM rsp %p", tm_rsp); session->tm_rsp = NULL; - session->tm_active = 0; + session->tm_active--; + WARN_ON(session->tm_active < 0); spin_unlock(&session->sn_lock); mutex_unlock(&target->target_mutex); @@ -329,10 +331,18 @@ iscsi_make_conn_wr_active(conn); if (time_after(jiffies, start_waiting + 7*HZ)) { - TRACE_CONN_CLOSE("%s", "Wait time expired"); + TRACE_CONN_CLOSE("Wait time expired (conn %p, " + "sk_state %d)", conn, conn->sock->sk->sk_state); conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN); } + if (time_after(jiffies, start_waiting + 15*HZ)) { + TRACE_CONN_CLOSE("Wait time after shutdown expired " + "(conn %p, sk_state %d)", conn, + conn->sock->sk->sk_state); + conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); + } + msleep(200); TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " @@ -914,6 +924,7 @@ spin_unlock_bh(&conn->write_list_lock); } +#if 0 /* temp. ToDo */ if (!timer_pending(&conn->rsp_timer)) { sBUG_ON(!ref_cmd->on_written_list); spin_lock_bh(&conn->write_list_lock); @@ -925,6 +936,7 @@ } spin_unlock_bh(&conn->write_list_lock); } +#endif file = conn->file; saved_size = size = conn->write_size; Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-02-29 18:25:56 UTC (rev 297) @@ -2571,6 +2571,43 @@ return res; } +static void vdisk_report_registering(const char *type, + const struct scst_vdisk_dev *virt_dev) +{ + char buf[128]; + int i, j; + + i = snprintf(buf, sizeof(buf), "Registering virtual %s device %s", + type, virt_dev->name); + j = i; + + if (virt_dev->wt_flag) + i += snprintf(&buf[i], sizeof(buf) - i, " (WRITE_THROUGH"); + + if (virt_dev->nv_cache) + i += snprintf(&buf[i], sizeof(buf) - i, "%sNV_CACHE", + (j == i) ? "(" : ", "); + + if (virt_dev->rd_only_flag) + i += snprintf(&buf[i], sizeof(buf) - i, "%sREAD_ONLY", + (j == i) ? "(" : ", "); + + if (virt_dev->o_direct_flag) + i += snprintf(&buf[i], sizeof(buf) - i, "%sO_DIRECT", + (j == i) ? "(" : ", "); + + if (virt_dev->nullio) + i += snprintf(&buf[i], sizeof(buf) - i, "%sNULLIO", + (j == i) ? "(" : ", "); + + if (j == i) + PRINT_INFO("%s", buf); + else + PRINT_INFO("%s)", buf); + + return; +} + /* * Called when a file in the /proc/VDISK_NAME/VDISK_NAME is written */ @@ -2753,14 +2790,17 @@ list_add_tail(&virt_dev->vdisk_dev_list_entry, &vdisk_dev_list); - if (virt_dev->blockio) + if (virt_dev->blockio) { + vdisk_report_registering("BLOCKIO", virt_dev); virt_dev->virt_id = scst_register_virtual_device(&vdisk_blk_devtype, virt_dev->name); - else + } else { + vdisk_report_registering("FILEIO", virt_dev); virt_dev->virt_id = scst_register_virtual_device(&vdisk_devtype, virt_dev->name); + } if (virt_dev->virt_id < 0) { res = virt_dev->virt_id; goto out_free_vpath; @@ -2880,6 +2920,8 @@ list_add_tail(&virt_dev->vdisk_dev_list_entry, &vcdrom_dev_list); + PRINT_INFO("Registering virtual CDROM %s", name); + virt_dev->virt_id = scst_register_virtual_device(&vcdrom_devtype, virt_dev->name); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_lib.c 2008-02-29 18:25:56 UTC (rev 297) @@ -719,13 +719,15 @@ out: if (res == 0) { if (dev->virt_name != NULL) { - PRINT_INFO("Added device %s to group %s", - dev->virt_name, acg->acg_name); + PRINT_INFO("Added device %s to group %s (LUN %Ld, " + "rd_only %d)", dev->virt_name, acg->acg_name, + lun, read_only); } else { - PRINT_INFO("Added device %d:%d:%d:%d to group %s", - dev->scsi_dev->host->host_no, + PRINT_INFO("Added device %d:%d:%d:%d to group %s (LUN " + "%Ld, rd_only %d)", dev->scsi_dev->host->host_no, dev->scsi_dev->channel, dev->scsi_dev->id, - dev->scsi_dev->lun, acg->acg_name); + dev->scsi_dev->lun, acg->acg_name, lun, + read_only); } } @@ -1568,9 +1570,9 @@ flags |= SCST_POOL_ALLOC_NO_CACHED; if (unlikely(cmd->bufflen == 0)) { - TRACE(TRACE_MGMT_MINOR, "Data direction %d or/and zero buffer " - "length. Opcode 0x%x, handler %s, target %s", - cmd->data_direction, cmd->cdb[0], + TRACE(TRACE_MGMT_MINOR, "Warning: data direction %d or/and " + "zero buffer length. Opcode 0x%x, handler %s, target " + "%s", cmd->data_direction, cmd->cdb[0], cmd->dev->handler->name, cmd->tgtt->name); /* * Be on the safe side and alloc stub buffer. Neither target Modified: trunk/scst/src/scst_priv.h =================================================================== --- trunk/scst/src/scst_priv.h 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_priv.h 2008-02-29 18:25:56 UTC (rev 297) @@ -240,7 +240,9 @@ spin_lock_irq(&c->cmd_lists->cmd_list_lock); list_add_tail(&c->cmd_list_entry, &c->cmd_lists->active_cmd_list); +#if 0 /* temp. ToDo */ if (!curr_cmd->context_processable || curr_cmd->long_xmit) +#endif wake_up(&c->cmd_lists->cmd_list_waitQ); spin_unlock_irq(&c->cmd_lists->cmd_list_lock); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-02-26 18:22:45 UTC (rev 296) +++ trunk/scst/src/scst_targ.c 2008-02-29 18:25:56 UTC (rev 297) @@ -476,6 +476,7 @@ PRINT_ERROR("Dev handler supplied data buffer (size %d), " "is less, than required (size %d)", cmd->bufflen, orig_bufflen); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -487,6 +488,7 @@ PRINT_ERROR("Unknown data transfer length for opcode 0x%x " "(handler %s, target %s)", cmd->cdb[0], dev->handler->name, cmd->tgtt->name); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -499,6 +501,7 @@ "or sg %p (opcode 0x%x)", dev->handler->name, cmd->data_direction, cmd->bufflen, state, cmd->sg, cmd->cdb[0]); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } #endif @@ -513,20 +516,27 @@ "bufflen %d, expected_transfer_len %d", cmd->data_direction, cmd->expected_data_direction, cmd->bufflen, cmd->expected_transfer_len); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); } # endif cmd->data_direction = cmd->expected_data_direction; cmd->bufflen = cmd->expected_transfer_len; #else if (unlikely(cmd->data_direction != cmd->expected_data_direction)) { - PRINT_ERROR("Expected data direction %d for opcode " - "0x%02x (handler %s, target %s) doesn't match " - "decoded value %d", cmd->data_direction, - cmd->cdb[0], dev->handler->name, - cmd->tgtt->name, cmd->expected_data_direction); - scst_set_cmd_error(cmd, - SCST_LOAD_SENSE(scst_sense_invalid_message)); - goto out_dev_done; + if (((cmd->expected_data_direction != SCST_DATA_NONE) || + (cmd->bufflen != 0)) && + /* Crazy VMware people sometimes do TUR with READ direction */ + !(cmd->cdb[0] == TEST_UNIT_READY)) { + PRINT_ERROR("Expected data direction %d for opcode " + "0x%02x (handler %s, target %s) doesn't match " + "decoded value %d", cmd->expected_data_direction, + cmd->cdb[0], dev->handler->name, + cmd->tgtt->name, cmd->data_direction); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_message)); + goto out_dev_done; + } } if (unlikely(cmd->bufflen != cmd->expected_transfer_len)) { TRACE(TRACE_MINOR, "Warning: expected transfer length " @@ -547,6 +557,7 @@ PRINT_ERROR("Unknown data direction. Opcode 0x%x, handler %s, " "target %s", cmd->cdb[0], dev->handler->name, cmd->tgtt->name); + PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len); goto out_error; } @@ -1418,7 +1429,8 @@ dev = cmd->dev; - scst_block_dev_cmd(cmd, 1); + if (dev->tst == SCST_CONTR_MODE_ONE_TASK_SET) + scst_block_dev_cmd(cmd, 1); rc = scst_check_local_events(cmd); if (unlikely(rc != 0)) @@ -1473,7 +1485,8 @@ dev = cmd->dev; - scst_block_dev_cmd(cmd, 1); + if (dev->tst == SCST_CONTR_MODE_ONE_TASK_SET) + scst_block_dev_cmd(cmd, 1); rc = scst_check_local_events(cmd); if (unlikely(rc != 0)) @@ -3497,7 +3510,7 @@ TRACE_ENTRY(); TRACE(((mcmd != NULL) && (mcmd->fn == SCST_ABORT_TASK)) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "Aborting cmd %p (tag %llu)", cmd, cmd->tag); + "Aborting cmd %p (tag %llu, op %x)", cmd, cmd->tag, cmd->cdb[0]); if (other_ini) { set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); @@ -3890,11 +3903,17 @@ } case SCST_TARGET_RESET: + case SCST_NEXUS_LOSS_SESS: + case SCST_ABORT_ALL_TASKS_SESS: + case SCST_NEXUS_LOSS: case SCST_ABORT_ALL_TASKS: - case SCST_NEXUS_LOSS: + case SCST_UNREG_SESS_TM: break; - default: + case SCST_ABORT_TASK_SET: + case SCST_CLEAR_ACA: + case SCST_CLEAR_TASK_SET: + case SCST_LUN_RESET: rc = scst_mgmt_translate_lun(mcmd); if (rc < 0) { PRINT_ERROR("Corresponding device for lun %Ld not " @@ -3904,6 +3923,9 @@ } else if (rc != 0) res = rc; break; + + default: + sBUG(); } out: @@ -4315,9 +4337,13 @@ if ((mcmd->fn == SCST_UNREG_SESS_TM) && (mcmd->sess->unreg_cmds_done_fn != NULL)) { struct scst_session *sess = mcmd->sess; + TRACE_MGMT_DBG("Calling unreg_cmds_done_fn(%p)", sess); sess->unreg_cmds_done_fn(sess); TRACE_MGMT_DBG("task_mgmt_all_cmds_done(%p) returned", sess); + + /* To prevent scst_mgmt_cmd_send_done() to call it again */ + sess->unreg_cmds_done_fn = NULL; } mcmd->nexus_loss_check_done = 1; @@ -4332,6 +4358,7 @@ { struct scst_device *dev; struct scst_tgt_dev *tgt_dev; + struct scst_session *sess = mcmd->sess; TRACE_ENTRY(); @@ -4342,13 +4369,20 @@ TRACE(TRACE_MGMT_MINOR, "TM command fn %d finished, status %x", mcmd->fn, mcmd->status); - if (mcmd->sess->tgt->tgtt->task_mgmt_fn_done && - (mcmd->fn != SCST_UNREG_SESS_TM)) { - TRACE_DBG("Calling target %s task_mgmt_fn_done()", - mcmd->sess->tgt->tgtt->name); - mcmd->sess->tgt->tgtt->task_mgmt_fn_done(mcmd); - TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() returned", - mcmd->sess->tgt->tgtt->name); + if (mcmd->fn == SCST_UNREG_SESS_TM) { + if (sess->unreg_cmds_done_fn != NULL) { + TRACE_MGMT_DBG("Calling unreg_cmds_done_fn(%p)", sess); + sess->unreg_cmds_done_fn(sess); + TRACE_MGMT_DBG("task_mgmt_all_cmds_done(%p) returned", sess); + } + } else { + if (sess->tgt->tgtt->task_mgmt_fn_done) { + TRACE_DBG("Calling target %s task_mgmt_fn_done(%p)", + sess->tgt->tgtt->name, sess); + sess->tgt->tgtt->task_mgmt_fn_done(mcmd); + TRACE_MGMT_DBG("Target's %s task_mgmt_fn_done() " + "returned", sess->tgt->tgtt->name); + } } if (mcmd->needs_unblocking) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-03-11 19:09:37
|
Revision: 301 http://scst.svn.sourceforge.net/scst/?rev=301&view=rev Author: vlnb Date: 2008-03-11 12:09:30 -0700 (Tue, 11 Mar 2008) Log Message: ----------- - Fixed race on TM leading to crashes - Connection close improved to be less agressive and honor TCP TIME_WATE state - Docs updates Modified Paths: -------------- trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/kernel/target.c trunk/scst/README trunk/scst/include/scsi_tgt.h trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/iscsi-scst/kernel/conn.c 2008-03-11 19:09:30 UTC (rev 301) @@ -158,11 +158,14 @@ return; } -void __mark_conn_closed(struct iscsi_conn *conn, bool force) +void __mark_conn_closed(struct iscsi_conn *conn, int flags) { spin_lock_bh(&iscsi_rd_lock); conn->closing = 1; - conn->force_close = force; + if (flags & ISCSI_CONN_ACTIVE_CLOSE) + conn->active_close = 1; + if (flags & ISCSI_CONN_DELETING) + conn->deleting = 1; spin_unlock_bh(&iscsi_rd_lock); iscsi_make_conn_rd_active(conn); @@ -170,7 +173,7 @@ void mark_conn_closed(struct iscsi_conn *conn) { - __mark_conn_closed(conn, 0); + __mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE); } static void iscsi_state_change(struct sock *sk) @@ -184,7 +187,7 @@ PRINT_ERROR("Connection with initiator %s (%p) " "unexpectedly closed!", conn->session->initiator_name, conn); - __mark_conn_closed(conn, 1); + __mark_conn_closed(conn, 0); } } else iscsi_make_conn_rd_active(conn); @@ -252,7 +255,7 @@ "%s (SID %Lx), closing connection", conn->session->initiator_name, conn->session->sid); - __mark_conn_closed(conn, 1); + mark_conn_closed(conn); } } else { TRACE_DBG("Restarting timer on %ld (conn %p)", @@ -438,7 +441,7 @@ PRINT_INFO("Deleting connection with initiator %s (%p)", conn->session->initiator_name, conn); - mark_conn_closed(conn); + __mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE|ISCSI_CONN_DELETING); return 0; } Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-03-11 19:09:30 UTC (rev 301) @@ -115,7 +115,7 @@ struct completion unreg_compl; - /* Both don't need any protection */ + /* All don't need any protection */ char *initiator_name; unsigned int shutting_down:1; u64 sid; @@ -185,11 +185,13 @@ int hdigest_type; int ddigest_type; - /* All 4 protected by iscsi_rd_lock */ + /* All 5 protected by iscsi_rd_lock */ unsigned short rd_state; unsigned short rd_data_ready:1; - unsigned short closing:1; /* Let's save some cache footprint by putting it here */ - unsigned short force_close:1; /* Let's save some cache footprint by putting it here */ + /* Let's save some cache footprint by putting them here */ + unsigned short closing:1; + unsigned short active_close:1; + unsigned short deleting:1; struct list_head rd_list_entry; @@ -353,7 +355,11 @@ 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 __mark_conn_closed(struct iscsi_conn *, bool); + +#define ISCSI_CONN_ACTIVE_CLOSE 1 +#define ISCSI_CONN_DELETING 2 +extern void __mark_conn_closed(struct iscsi_conn *, int); + extern void mark_conn_closed(struct iscsi_conn *); extern void iscsi_make_conn_wr_active(struct iscsi_conn *); extern void conn_info_show(struct seq_file *, struct iscsi_session *); Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/iscsi-scst/kernel/nthread.c 2008-03-11 19:09:30 UTC (rev 301) @@ -61,7 +61,8 @@ TRACE_ENTRY(); - TRACE_CONN_CLOSE("conn %p, sk_state %d", conn, conn->sock->sk->sk_state); + TRACE_CONN_CLOSE_DBG("conn %p, sk_state %d", conn, + conn->sock->sk->sk_state); if (conn->sock->sk->sk_state != TCP_CLOSE) { TRACE_CONN_CLOSE_DBG("conn %p, skipping", conn); @@ -173,7 +174,7 @@ TRACE_ENTRY(); - TRACE_CONN_CLOSE("sess %p (scst_sess %p)", sess, scst_sess); + TRACE_CONN_CLOSE_DBG("sess %p (scst_sess %p)", sess, scst_sess); sess->shutting_down = 1; complete_all(&sess->unreg_compl); @@ -188,6 +189,8 @@ struct iscsi_session *session = conn->session; struct iscsi_target *target = conn->target; unsigned long start_waiting = jiffies; + unsigned long shut_start_waiting = start_waiting; + bool pending_reported = 0, wait_expired = 0, shut_expired = 0; TRACE_ENTRY(); @@ -198,12 +201,12 @@ sBUG_ON(!conn->closing); - if (conn->force_close) { + if (conn->active_close) { + /* We want all our already send operations to complete */ + conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); + } else { conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN|SEND_SHUTDOWN); - } else { - /* We want all our already send operations to complete */ - conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN); } /* @@ -251,7 +254,7 @@ struct list_head *pending_list = &session->pending_list; int req_freed; - TRACE_CONN_CLOSE("Disposing pending commands on " + TRACE_CONN_CLOSE_DBG("Disposing pending commands on " "connection %p (conn_ref_cnt=%d)", conn, atomic_read(&conn->conn_ref_cnt)); @@ -267,13 +270,13 @@ req_freed = 0; list_for_each_entry(cmnd, pending_list, pending_list_entry) { - TRACE_CONN_CLOSE("Pending cmd %p" + TRACE_CONN_CLOSE_DBG("Pending cmd %p" "(conn %p, cmd_sn %u, exp_cmd_sn %u)", cmnd, conn, cmnd->pdu.bhs.sn, session->exp_cmd_sn); if ((cmnd->conn == conn) && (session->exp_cmd_sn == cmnd->pdu.bhs.sn)) { - TRACE_CONN_CLOSE("Freeing pending cmd %p", + TRACE_CONN_CLOSE_DBG("Freeing pending cmd %p", cmnd); list_del(&cmnd->pending_list_entry); @@ -294,13 +297,16 @@ spin_unlock(&session->sn_lock); if (time_after(jiffies, start_waiting + 10*HZ)) { - TRACE_CONN_CLOSE("%s", "Pending wait time expired"); + if (!pending_reported) { + TRACE_CONN_CLOSE("%s", "Pending wait time expired"); + pending_reported = 1; + } spin_lock(&session->sn_lock); do { req_freed = 0; list_for_each_entry(cmnd, pending_list, pending_list_entry) { - TRACE_CONN_CLOSE("Pending cmd %p" + TRACE_CONN_CLOSE_DBG("Pending cmd %p" "(conn %p, cmd_sn %u, exp_cmd_sn %u)", cmnd, conn, cmnd->pdu.bhs.sn, session->exp_cmd_sn); @@ -330,22 +336,28 @@ iscsi_make_conn_wr_active(conn); - if (time_after(jiffies, start_waiting + 7*HZ)) { + if (time_after(jiffies, start_waiting + 10*HZ) && !wait_expired) { TRACE_CONN_CLOSE("Wait time expired (conn %p, " "sk_state %d)", conn, conn->sock->sk->sk_state); conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN); + wait_expired = 1; + shut_start_waiting = jiffies; } - if (time_after(jiffies, start_waiting + 15*HZ)) { - TRACE_CONN_CLOSE("Wait time after shutdown expired " - "(conn %p, sk_state %d)", conn, - conn->sock->sk->sk_state); - conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); - } + if (conn->deleting) { + if (wait_expired && !shut_expired && + time_after(jiffies, shut_start_waiting + 10*HZ)) { + TRACE_CONN_CLOSE("Wait time after shutdown expired " + "(conn %p, sk_state %d)", conn, + conn->sock->sk->sk_state); + conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); + shut_expired = 1; + } + msleep(200); + } else + msleep(1000); - msleep(200); - - TRACE_CONN_CLOSE("conn %p, conn_ref_cnt %d left, wr_state %d, " + TRACE_CONN_CLOSE_DBG("conn %p, conn_ref_cnt %d left, wr_state %d, " "exp_cmd_sn %u", conn, atomic_read(&conn->conn_ref_cnt), conn->wr_state, session->exp_cmd_sn); #ifdef DEBUG @@ -427,8 +439,8 @@ if (t && (atomic_read(&conn->conn_ref_cnt) == 0)) break; - TRACE_CONN_CLOSE("Waiting for wr thread (conn %p), wr_state %x", - conn, conn->wr_state); + TRACE_CONN_CLOSE_DBG("Waiting for wr thread (conn %p), " + "wr_state %x", conn, conn->wr_state); msleep(50); } Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/iscsi-scst/kernel/session.c 2008-03-11 19:09:30 UTC (rev 301) @@ -177,8 +177,9 @@ struct iscsi_session *session; list_for_each_entry(session, &target->session_list, session_list_entry) { - seq_printf(seq, "\tsid:%llu initiator:%s\n", - (unsigned long long) session->sid, session->initiator_name); + seq_printf(seq, "\tsid:%llu initiator:%s shutting down %d\n", + (unsigned long long)session->sid, + session->initiator_name, session->shutting_down); conn_info_show(seq, session); } } Modified: trunk/iscsi-scst/kernel/target.c =================================================================== --- trunk/iscsi-scst/kernel/target.c 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/iscsi-scst/kernel/target.c 2008-03-11 19:09:30 UTC (rev 301) @@ -240,7 +240,8 @@ conn_list_entry) { TRACE_MGMT_DBG("Mark conn %p " "closing", conn); - mark_conn_closed(conn); + __mark_conn_closed(conn, + ISCSI_CONN_ACTIVE_CLOSE|ISCSI_CONN_DELETING); } } else { TRACE_MGMT_DBG("Freeing session %p " Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/scst/README 2008-03-11 19:09:30 UTC (rev 301) @@ -477,6 +477,13 @@ For example, "echo "open disk1 /vdisks/disk1" >/proc/scsi_tgt/vdisk/vdisk" will open file /vdisks/disk1 as virtual FILEIO disk with name "disk1". +CAUTION: If you partitioned/formatted your device with block size X, *NEVER* +======== ever try to export and then mount it (even accidentally) with another + block size. Otherwise you can *instantly* damage it pretty + badly as well as all your data on it. Messages on initiator like: + "attempt to access beyond end of device" is the sign of such + damage. + IMPORTANT: By default for performance reasons VDISK FILEIO devices use write ========= back caching policy. This is generally safe from the consistence of journaled file systems, laying over them, point of view, but @@ -743,14 +750,18 @@ comparing with your target link speed and amount of simultaneously queued commands. On some seek intensive workloads even fast disks or RAIDs, which able to serve continuous data stream on 500+ MB/s speed, -can be as slow as 0.3 MB/s. So, simply processing of one or more -commands takes too long time, hence initiator decides that they are -stuck on the target and tries to recover. Particularly, it is known that -the default amount of simultaneously queued commands (48) is sometimes -too high if you do intensive writes from VMware on a target disk, which -uses LVM in the snapshot mode. In this case value like 16 or even 8-10 -depending of your backstorage speed could be more appropriate. +can be as slow as 0.3 MB/s. Another possible cause for that can be +MD/LVM/RAID on your target as in http://lkml.org/lkml/2008/2/27/96 +(check the whole thread as well). +Thus, in such situations simply processing of one or more commands takes +too long time, hence initiator decides that they are stuck on the target +and tries to recover. Particularly, it is known that the default amount +of simultaneously queued commands (48) is sometimes too high if you do +intensive writes from VMware on a target disk, which uses LVM in the +snapshot mode. In this case value like 16 or even 8-10 depending of your +backstorage speed could be more appropriate. + Unfortunately, currently SCST lacks dynamic I/O flow control, when the queue depth on the target is dynamically decreased/increased based on how slow/fast the backstorage speed comparing to the target link. So, Modified: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/scst/include/scsi_tgt.h 2008-03-11 19:09:30 UTC (rev 301) @@ -1288,7 +1288,6 @@ unsigned int needs_unblocking:1; unsigned int lun_set:1; /* set, if lun field is valid */ unsigned int cmd_sn_set:1; /* set, if cmd_sn field is valid */ - unsigned int nexus_loss_check_active:1; /* set, if nexus loss check is active */ unsigned int nexus_loss_check_done:1; /* set, if nexus loss check is done */ /* Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-03-11 14:27:13 UTC (rev 300) +++ trunk/scst/src/scst_targ.c 2008-03-11 19:09:30 UTC (rev 301) @@ -3399,7 +3399,7 @@ if (mcmd->completed) { sBUG_ON(mcmd->nexus_loss_check_done); - mcmd->nexus_loss_check_active = 1; + mcmd->completed = 0; mcmd->state = SCST_MGMT_CMD_STATE_CHECK_NEXUS_LOSS; TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd " "list", mcmd); @@ -3451,7 +3451,7 @@ continue; } - if (mcmd->completed && !mcmd->nexus_loss_check_active) { + if (mcmd->completed) { mcmd->state = SCST_MGMT_CMD_STATE_DONE; TRACE_MGMT_DBG("Adding mgmt cmd %p to active mgmt cmd " "list", mcmd); @@ -4354,7 +4354,6 @@ } mcmd->nexus_loss_check_done = 1; - mcmd->nexus_loss_check_active = 0; res = scst_set_mcmd_next_state(mcmd); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-04-17 15:25:55
|
Revision: 336 http://scst.svn.sourceforge.net/scst/?rev=336&view=rev Author: vlnb Date: 2008-04-17 08:25:39 -0700 (Thu, 17 Apr 2008) Log Message: ----------- - Fixes scst_user brokennesses in various modes, especially in iSCSI-SCST - Minor debug logging fixes - Minor cleanups Modified Paths: -------------- trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_debug.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/digest.c 2008-04-17 15:25:39 UTC (rev 336) @@ -106,9 +106,9 @@ return evaluate_crc32_from_sg(sg, nbytes, 0); } -static u32 digest_data(struct iscsi_cmnd *req, u32 osize, u32 offset) +static u32 digest_data(struct iscsi_cmnd *cmd, u32 osize, u32 offset) { - struct scatterlist *sg = req->sg; + struct scatterlist *sg = cmd->sg; int idx, count; struct scatterlist saved_sg; u32 size = (osize + 3) & ~3; @@ -119,7 +119,10 @@ offset &= ~PAGE_MASK; count = get_pgcnt(size, offset); - sBUG_ON(idx + count > get_pgcnt(req->bufflen, 0)); + + TRACE_DBG("req %p, idx %d, count %d, sg_cnt %d, size %d, " + "offset %d", cmd, idx, count, cmd->sg_cnt, size, offset); + sBUG_ON(idx + count > cmd->sg_cnt); sBUG_ON(count > ISCSI_CONN_IOV_MAX); saved_sg = sg[idx]; Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-04-17 15:25:39 UTC (rev 336) @@ -567,12 +567,13 @@ { cmnd->pdu.datasize = size; - if (cmnd->pdu.datasize & 3) { - int idx = (offset + cmnd->pdu.datasize) >> PAGE_SHIFT; - u8 *p = (u8 *)page_address(sg_page(&cmnd->sg[idx])) + - ((offset + cmnd->pdu.datasize) & ~PAGE_MASK); - int i = 4 - (cmnd->pdu.datasize & 3); - while (i--) + if (size & 3) { + u32 last_off = offset + size; + int idx = last_off >> PAGE_SHIFT; + u8 *p = (u8*)page_address(sg_page(&cmnd->sg[idx])) + + (last_off & ~PAGE_MASK); + int i = 4 - (size & 3); + while(i--) *p++ = 0; } } @@ -586,16 +587,18 @@ LIST_HEAD(send); TRACE_DBG("req %p", req); + pdusize = req->conn->session->sess_param.max_xmit_data_length; expsize = cmnd_read_size(req); size = min(expsize, (u32)req->bufflen); offset = 0; sn = 0; - while (1) { + while(1) { rsp = iscsi_cmnd_create_rsp_cmnd(req); TRACE_DBG("rsp %p", rsp); rsp->sg = req->sg; + rsp->sg_cnt = req->sg_cnt; rsp->bufflen = req->bufflen; rsp_hdr = (struct iscsi_data_in_hdr *)&rsp->pdu.bhs; @@ -606,6 +609,7 @@ rsp_hdr->data_sn = cpu_to_be32(sn); if (size <= pdusize) { + TRACE_DBG("offset %d, size %d", offset, size); iscsi_set_datasize(rsp, offset, size); if (send_status) { TRACE_DBG("status %x", status); @@ -627,6 +631,9 @@ break; } + TRACE_DBG("pdusize %d, offset %d, size %d", pdusize, offset, + size); + iscsi_set_datasize(rsp, offset, pdusize); size -= pdusize; @@ -1369,6 +1376,7 @@ } req->target_task_tag = get_next_ttt(conn); req->sg = scst_cmd_get_sg(scst_cmd); + req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd); req->bufflen = scst_cmd_get_bufflen(scst_cmd); if (unlikely(req->r2t_length > req->bufflen)) { PRINT_ERROR("req->r2t_length %d > req->bufflen %d", @@ -1903,10 +1911,12 @@ if (req->sg) { rsp->sg = req->sg; + rsp->sg_cnt = req->sg_cnt; rsp->bufflen = req->bufflen; } sBUG_ON(get_pgcnt(req->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX); + rsp->pdu.datasize = req->pdu.datasize; iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE); @@ -2529,9 +2539,11 @@ req->bufflen = scst_cmd_get_resp_data_len(scst_cmd); req->sg = scst_cmd_get_sg(scst_cmd); + req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd); - TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p", req, - resp_flags, req->bufflen, req->sg); + TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p, " + "req->sg_cnt %d", req, resp_flags, req->bufflen, req->sg, + req->sg_cnt); if (unlikely((req->bufflen != 0) && !(resp_flags & SCST_TSC_FLAG_STATUS))) { Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-04-17 15:25:39 UTC (rev 336) @@ -302,6 +302,7 @@ struct iscsi_pdu pdu; struct scatterlist *sg; + int sg_cnt; int bufflen; u32 r2t_sn; u32 r2t_length; @@ -312,7 +313,6 @@ u32 hdigest; u32 ddigest; - int sg_cnt; /* valid only if own_sg is 1 */ struct list_head cmd_list_entry; }; Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/nthread.c 2008-04-17 15:25:39 UTC (rev 336) @@ -90,14 +90,12 @@ sBUG_ON(cmnd->parent_req != NULL); if (cmnd->sg != NULL) { - int sg_cnt, i; + int i; - sg_cnt = get_pgcnt(cmnd->bufflen, - cmnd->sg[0].offset); - if (cmnd_get_check(cmnd)) continue; - for(i = 0; i < sg_cnt; i++) { + + for(i = 0; i < cmnd->sg_cnt; i++) { struct page *page = sg_page(&cmnd->sg[i]); TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, " "_count %d", page, page->net_priv, @@ -125,15 +123,12 @@ atomic_read(&rsp->net_ref_cnt), rsp->sg); if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) { - int sg_cnt, i; + int i; - sg_cnt = get_pgcnt(rsp->bufflen, - rsp->sg[0].offset); - sBUG_ON(rsp->sg_cnt != sg_cnt); - if (cmnd_get_check(rsp)) continue; - for(i = 0; i < sg_cnt; i++) { + + for(i = 0; i < rsp->sg_cnt; i++) { struct page *page = sg_page(&rsp->sg[i]); TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, " "_count %d", page, page->net_priv, @@ -383,10 +378,8 @@ TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", atomic_read(&cmnd->net_ref_cnt), cmnd->sg); if (cmnd->sg != NULL) { - int sg_cnt, i; - sg_cnt = get_pgcnt(cmnd->bufflen, - cmnd->sg[0].offset); - for(i = 0; i < sg_cnt; i++) { + int i; + for(i = 0; i < cmnd->sg_cnt; i++) { struct page *page = sg_page(&cmnd->sg[i]); TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d", page, page->net_priv, @@ -402,11 +395,8 @@ "sg %p", rsp, atomic_read(&rsp->ref_cnt), atomic_read(&rsp->net_ref_cnt), rsp->sg); if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) { - int sg_cnt, i; - sg_cnt = get_pgcnt(rsp->bufflen, - rsp->sg[0].offset); - sBUG_ON(rsp->sg_cnt != sg_cnt); - for(i = 0; i < sg_cnt; i++) { + int i; + for(i = 0; i < rsp->sg_cnt; i++) { TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, " "_count %d", sg_page(&rsp->sg[i]), sg_page(&rsp->sg[i])->net_priv, @@ -858,45 +848,62 @@ } #ifdef NET_PAGE_CALLBACKS_DEFINED -void iscsi_get_page_callback(struct page *page) +static inline void __iscsi_get_page_callback(struct iscsi_cmnd *cmd) { - struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv; int v; - TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d", - cmd, page, atomic_read(&page->_count), - atomic_read(&cmd->net_ref_cnt)+1); + TRACE_NET_PAGE("cmd %p, new net_ref_cnt %d", + cmd, atomic_read(&cmd->net_ref_cnt)+1); v = atomic_inc_return(&cmd->net_ref_cnt); if (v == 1) { - TRACE_NET_PAGE("getting cmd %p for page %p", cmd, page); + TRACE_NET_PAGE("getting cmd %p", cmd); cmnd_get(cmd); } } -void iscsi_put_page_callback(struct page *page) +void iscsi_get_page_callback(struct page *page) { struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv; - TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d", - cmd, page, atomic_read(&page->_count), + TRACE_NET_PAGE("page %p, _count %d", page, + atomic_read(&page->_count)); + + __iscsi_get_page_callback(cmd); +} + +static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd) +{ + TRACE_NET_PAGE("cmd %p, new net_ref_cnt %d", cmd, atomic_read(&cmd->net_ref_cnt)-1); if (atomic_dec_and_test(&cmd->net_ref_cnt)) { - int i, sg_cnt = get_pgcnt(cmd->bufflen, cmd->sg[0].offset); + int i, sg_cnt = cmd->sg_cnt; for(i = 0; i < sg_cnt; i++) { - TRACE_NET_PAGE("Clearing page %p", sg_page(&cmd->sg[i])); - sg_page(&cmd->sg[i])->net_priv = NULL; + struct page *page = sg_page(&cmd->sg[i]); + TRACE_NET_PAGE("Clearing page %p", page); + if (page->net_priv == cmd) + page->net_priv = NULL; } cmnd_put(cmd); } } +void iscsi_put_page_callback(struct page *page) +{ + struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv; + + TRACE_NET_PAGE("page %p, _count %d", page, + atomic_read(&page->_count)); + + __iscsi_put_page_callback(cmd); +} + static void check_net_priv(struct iscsi_cmnd *cmd, struct page *page) { - if (atomic_read(&cmd->net_ref_cnt) == 0) { - TRACE_DBG("%s", "sendpage() not called get_page(), " - "zeroing net_priv"); + if ((atomic_read(&cmd->net_ref_cnt) == 1) && (page->net_priv == cmd)) { + TRACE_DBG("sendpage() not called get_page(), zeroing net_priv " + "%p (page %p)", page->net_priv, page); page->net_priv = NULL; } } @@ -910,6 +917,7 @@ mm_segment_t oldfs; struct file *file; struct socket *sock; + ssize_t (*sock_sendpage)(struct socket *, struct page *, int, size_t, int); ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); struct iscsi_cmnd *write_cmnd = conn->write_cmnd; struct iscsi_cmnd *ref_cmd; @@ -918,7 +926,10 @@ int saved_size, size, sendsize; int offset, idx; int flags, res, count; + bool do_put = false; + TRACE_ENTRY(); + iscsi_extracheck_is_wr_thread(conn); if (write_cmnd->own_sg == 0) @@ -967,7 +978,7 @@ set_fs(oldfs); TRACE_WRITE("%#Lx:%u: %d(%ld)", (unsigned long long)conn->session->sid, conn->cid, - res, (long) iop->iov_len); + res, (long)iop->iov_len); if (unlikely(res <= 0)) { if (res == -EAGAIN) { conn->write_iop = iop; @@ -975,7 +986,7 @@ goto out_iov; } else if (res == -EINTR) goto retry; - goto err; + goto out_err; } rest = res; @@ -1000,58 +1011,86 @@ sg = write_cmnd->sg; if (unlikely(sg == NULL)) { - PRINT_ERROR("%s", "warning data missing!"); - return 0; + PRINT_INFO("WARNING: Data missed (cmd %p)!", write_cmnd); + res = 0; + goto out; } - offset = conn->write_offset; + + /* To protect from too early transfer completion race */ + __iscsi_get_page_callback(ref_cmd); + do_put = true; + + offset = conn->write_offset + sg[0].offset; idx = offset >> PAGE_SHIFT; offset &= ~PAGE_MASK; sock = conn->sock; #ifdef NET_PAGE_CALLBACKS_DEFINED - sendpage = sock->ops->sendpage; + sock_sendpage = sock->ops->sendpage; #else if ((write_cmnd->parent_req->scst_cmd != NULL) && scst_cmd_get_data_buff_alloced(write_cmnd->parent_req->scst_cmd)) - sendpage = sock_no_sendpage; + sock_sendpage = sock_no_sendpage; else - sendpage = sock->ops->sendpage; + sock_sendpage = sock->ops->sendpage; #endif flags = MSG_DONTWAIT; while (1) { + sendpage = sock_sendpage; + #ifdef NET_PAGE_CALLBACKS_DEFINED - if (unlikely((sg_page(&sg[idx])->net_priv != NULL) && - (sg_page(&sg[idx])->net_priv != ref_cmd))) { - PRINT_CRIT_ERROR("net_priv isn't NULL and != ref_cmd " - "(write_cmnd %p, ref_cmd %p, sg %p, idx %d, " - "net_priv %p)", write_cmnd, ref_cmd, sg, idx, - sg_page(&sg[idx])->net_priv); - sBUG(); + { + static spinlock_t net_priv_lock = SPIN_LOCK_UNLOCKED; + spin_lock(&net_priv_lock); + if (sg_page(&sg[idx])->net_priv != NULL) { + if (sg_page(&sg[idx])->net_priv != ref_cmd) { + /* + * This might happen if user space supplies + * to scst_user the same pages in different + * commands or in case of zero-copy FILEIO, + * when several initiators request the same + * data simultaneously. + */ + TRACE_DBG("net_priv isn't NULL and != " + "ref_cmd (write_cmnd %p, ref_cmd %p, " + "sg %p, idx %d, page %p, net_priv %p)", + write_cmnd, ref_cmd, sg, idx, + sg_page(&sg[idx]), + sg_page(&sg[idx])->net_priv); + sendpage = sock_no_sendpage; + } + } else + sg_page(&sg[idx])->net_priv = ref_cmd; + spin_unlock(&net_priv_lock); } - sg_page(&sg[idx])->net_priv = ref_cmd; #endif sendsize = PAGE_SIZE - offset; if (size <= sendsize) { retry2: res = sendpage(sock, sg_page(&sg[idx]), offset, size, flags); - TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", - sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", + TRACE_WRITE("Final %s %#Lx:%u: %d(%lu,%u,%u, cmd %p, page %p)", + (sendpage != sock_no_sendpage) ? "sendpage" : + "sock_no_sendpage", (unsigned long long)conn->session->sid, conn->cid, - res, sg_page(&sg[idx])->index, offset, size); + res, sg_page(&sg[idx])->index, offset, size, + write_cmnd, sg_page(&sg[idx])); if (unlikely(res <= 0)) { if (res == -EINTR) goto retry2; else goto out_res; } + check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == size) { conn->write_size = 0; - return saved_size; + res = saved_size; + goto out_put; } + offset += res; size -= res; continue; @@ -1060,40 +1099,55 @@ retry1: res = sendpage(sock, sg_page(&sg[idx]), offset, sendsize, flags | MSG_MORE); - TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)", - sock->ops->sendpage ? "sendpage" : "sock_no_sendpage", - (unsigned long long ) conn->session->sid, conn->cid, - res, sg_page(&sg[idx])->index, offset, sendsize); + TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u, cmd %p, page %p)", + (sendpage != sock_no_sendpage) ? "sendpage" : + "sock_no_sendpage", + (unsigned long long)conn->session->sid, conn->cid, + res, sg_page(&sg[idx])->index, offset, sendsize, + write_cmnd, sg_page(&sg[idx])); if (unlikely(res <= 0)) { if (res == -EINTR) goto retry1; else goto out_res; } + check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == sendsize) { idx++; offset = 0; + EXTRACHECKS_BUG_ON(idx >= ref_cmd->sg_cnt); } else offset += res; + size -= res; } -out: - conn->write_offset = (idx << PAGE_SHIFT) + offset; + +out_off: + conn->write_offset = (idx << PAGE_SHIFT) + offset - sg[0].offset; + out_iov: conn->write_size = size; if ((saved_size == size) && res == -EAGAIN) - return res; + goto out_put; - return saved_size - size; + res = saved_size - size; +out_put: + if (do_put) + __iscsi_put_page_callback(ref_cmd); + +out: + TRACE_EXIT_RES(res); + return res; + out_res: check_net_priv(ref_cmd, sg_page(&sg[idx])); if (res == -EAGAIN) - goto out; + goto out_off; /* else go through */ -err: +out_err: #ifndef DEBUG if (!conn->closing) #endif @@ -1105,7 +1159,7 @@ if (ref_cmd->scst_cmd != NULL) scst_set_delivery_status(ref_cmd->scst_cmd, SCST_CMD_DELIVERY_FAILED); - return res; + goto out_put; } static int exit_tx(struct iscsi_conn *conn, int res) Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/include/scst_debug.h 2008-04-17 15:25:39 UTC (rev 336) @@ -124,8 +124,8 @@ #define TRACE_ALL 0xffffffff /* Flags 0xXXXX0000 are local for users */ -#define PRINT(log_flag, format, args...) printk(log_flag format "\n", ## args); -#define PRINTN(log_flag, format, args...) printk(log_flag format, ## args); +#define PRINT(log_flag, format, args...) printk("%s" format "\n", log_flag, ## args); +#define PRINTN(log_flag, format, args...) printk("%s" format, log_flag, ## args); #ifdef LOG_PREFIX #define __LOG_PREFIX LOG_PREFIX @@ -141,17 +141,18 @@ #define ___unlikely(a) unlikely(a) #endif -extern int debug_print_prefix(unsigned long trace_flag, const char *prefix, - const char *func, int line); -extern void debug_print_buffer(const void *data, int len); +extern int debug_print_prefix(unsigned long trace_flag, const char *log_level, + const char *prefix, const char *func, int line); +extern void debug_print_buffer(const char *log_level, const void *data, + int len); #define TRACE(trace, format, args...) \ do { \ if (___unlikely(trace_flag & (trace))) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __tflag, __LOG_PREFIX, \ + __FUNCTION__, __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -162,21 +163,21 @@ #define PRINT_BUFFER(message, buff, len) \ do { \ PRINT(NO_FLAG, "%s:", message); \ - debug_print_buffer(buff, len); \ + debug_print_buffer(INFO_FLAG, buff, len); \ } while(0) #define PRINT_BUFF_FLAG(flag, message, buff, len) \ do { \ if (___unlikely(trace_flag & (flag))) \ { \ - char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + char *__tflag = INFO_FLAG; \ + if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ + debug_print_buffer(INFO_FLAG, buff, len); \ } \ } while(0) @@ -195,7 +196,7 @@ if (trace_flag & (trace)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ @@ -216,13 +217,13 @@ if (trace_flag & TRACE_BUFF) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ + debug_print_buffer(LOG_FLAG, buff, len); \ } \ } while(0) @@ -231,21 +232,21 @@ if (trace_flag & (flag)) \ { \ char *__tflag = LOG_FLAG; \ - if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \ + if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \ __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ PRINT(NO_FLAG, "%s%s:", __tflag, message); \ - debug_print_buffer(buff, len); \ + debug_print_buffer(LOG_FLAG, buff, len); \ } \ } while(0) #define PRINT_LOG_FLAG(log_flag, format, args...) \ do { \ char *__tflag = log_flag; \ - if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \ - __LINE__) > 0) \ + if (debug_print_prefix(trace_flag, __tflag, __LOG_PREFIX, \ + __FUNCTION__, __LINE__) > 0) \ { \ __tflag = NO_FLAG; \ } \ @@ -263,14 +264,13 @@ #define PRINT_CRIT_ERROR(format, args...) \ do { \ - if (strcmp(CRIT_FLAG, LOG_FLAG)) \ +/* if (strcmp(CRIT_FLAG, LOG_FLAG)) \ { \ PRINT_LOG_FLAG(LOG_FLAG, "***CRITICAL ERROR*** " format, args); \ - } \ + }*/ \ PRINT_LOG_FLAG(CRIT_FLAG, "***CRITICAL ERROR*** " format, args); \ } while(0) - #define PRINT_INFO(format, args...) \ do { \ if (strcmp(INFO_FLAG, LOG_FLAG)) \ Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-04-17 15:25:39 UTC (rev 336) @@ -328,6 +328,7 @@ gfp_t gfp_mask, void *priv) { struct scst_user_cmd *ucmd = (struct scst_user_cmd*)priv; + int offset = 0; TRACE_ENTRY(); @@ -339,7 +340,7 @@ if (ucmd->cur_data_page == 0) { TRACE_MEM("ucmd->first_page_offset %d", ucmd->first_page_offset); - sg->offset = ucmd->first_page_offset; + offset = ucmd->first_page_offset; ucmd_get(ucmd, 0); } @@ -347,10 +348,11 @@ goto out; sg_set_page(sg, ucmd->data_pages[ucmd->cur_data_page], - PAGE_SIZE - sg->offset, 0); + PAGE_SIZE - offset, offset); ucmd->cur_data_page++; - TRACE_MEM("page=%p, length=%d", sg_page(sg), sg->length); + TRACE_MEM("page=%p, length=%d, offset=%d", sg_page(sg), sg->length, + sg->offset); TRACE_BUFFER("Page data", sg_virt(sg), sg->length); out: @@ -498,10 +500,6 @@ ucmd->ubuff = buf_ucmd->ubuff; ucmd->buf_ucmd = buf_ucmd; - TRACE_MEM("Buf alloced (ucmd %p, cached_buff %d, ubuff %lx, " - "last_len %d, l %d)", ucmd, cached_buff, ucmd->ubuff, - last_len, cmd->sg[cmd->sg_cnt-1].length); - EXTRACHECKS_BUG_ON((ucmd->data_pages != NULL) && (ucmd != buf_ucmd)); @@ -510,6 +508,10 @@ cmd->sg[cmd->sg_cnt-1].length = last_len; } + TRACE_MEM("Buf alloced (ucmd %p, cached_buff %d, ubuff %lx, " + "last_len %d, l %d)", ucmd, cached_buff, ucmd->ubuff, + last_len, cmd->sg[cmd->sg_cnt-1].length); + if (unlikely(cmd->sg_cnt > cmd->tgt_dev->max_sg_cnt)) { static int ll; if (ll < 10) { Modified: trunk/scst/src/scst_debug.c =================================================================== --- trunk/scst/src/scst_debug.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/scst_debug.c 2008-04-17 15:25:39 UTC (rev 336) @@ -28,9 +28,19 @@ static char trace_buf[TRACE_BUF_SIZE]; static spinlock_t trace_buf_lock = SPIN_LOCK_UNLOCKED; -int debug_print_prefix(unsigned long trace_flag, const char *prefix, - const char *func, int line) +static inline int get_current_tid(void) { + /* Code should be the same as in sys_gettid() */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + return current->pid; +#else + return task_pid_vnr(current); +#endif +} + +int debug_print_prefix(unsigned long trace_flag, const char *log_level, + const char *prefix, const char *func, int line) +{ int i = 0; unsigned long flags; @@ -38,7 +48,7 @@ if (trace_flag & TRACE_PID) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE, "[%d]: ", - current->pid); + get_current_tid()); if (prefix != NULL) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s: ", prefix); if (trace_flag & TRACE_FUNCTION) @@ -47,14 +57,14 @@ i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); if (i > 0) - PRINTN(LOG_FLAG, "%s", trace_buf); + PRINTN(log_level, "%s", trace_buf); spin_unlock_irqrestore(&trace_buf_lock, flags); return i; } -void debug_print_buffer(const void *data, int len) +void debug_print_buffer(const char *log_level, const void *data, int len) { int z, z1, i; const unsigned char *buf = (const unsigned char *) data; @@ -100,7 +110,7 @@ } trace_buf[i] = '\0'; if (f) { - PRINT(LOG_FLAG, "%s", trace_buf) + PRINT(log_level, "%s", trace_buf) } else { PRINT(NO_FLAG, "%s", trace_buf); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/scst_targ.c 2008-04-17 15:25:39 UTC (rev 336) @@ -658,7 +658,10 @@ } alloc: - r = scst_alloc_space(cmd); + if (!cmd->data_buf_alloced) + r = scst_alloc_space(cmd); + else + TRACE_MEM("%s", "data_buf_alloced set, returning"); check: if (r != 0) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-04-17 17:35:40
|
Revision: 337 http://scst.svn.sourceforge.net/scst/?rev=337&view=rev Author: vlnb Date: 2008-04-17 10:35:37 -0700 (Thu, 17 Apr 2008) Log Message: ----------- scsi_tgt.h renamed to scst.h Modified Paths: -------------- trunk/doc/scst_pg.sgml trunk/iscsi-scst/kernel/iscsi.h trunk/mpt/mpt_scst.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla_isp/linux/isp_scst.c trunk/scst/README trunk/scst/src/Makefile trunk/scst/src/dev_handlers/scst_cdrom.c trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_disk.c trunk/scst/src/dev_handlers/scst_modisk.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_debug.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_module.c trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c trunk/srpt/src/ib_srpt.h Added Paths: ----------- trunk/scst/include/scst.h Removed Paths: ------------- trunk/scst/include/scsi_tgt.h Modified: trunk/doc/scst_pg.sgml =================================================================== --- trunk/doc/scst_pg.sgml 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/doc/scst_pg.sgml 2008-04-17 17:35:37 UTC (rev 337) @@ -99,7 +99,7 @@ University of New Hampshire Interoperability Labs (UNH IOL). All described below data structures and function could be found in -<bf/scsi_tgt.h/. The SCST's Internet page is +<bf/scst.h/. The SCST's Internet page is <url url="http://scst.sourceforge.net">. <sect>Terms and Definitions Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-04-17 17:35:37 UTC (rev 337) @@ -23,7 +23,7 @@ #include <linux/net.h> #include <net/sock.h> -#include <scsi_tgt.h> +#include <scst.h> #include "iscsi_hdr.h" #include "iscsi_u.h" Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/mpt/mpt_scst.c 2008-04-17 17:35:37 UTC (rev 337) @@ -36,7 +36,7 @@ #include <linux/pci.h> #endif -#include "scsi_tgt.h" +#include "scst.h" #include <scst_debug.h> Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-04-17 17:35:37 UTC (rev 337) @@ -31,7 +31,7 @@ #include <linux/seq_file.h> #include <linux/list.h> -#include <scsi_tgt.h> +#include <scst.h> /* Necessary to have equal structures with the initiator */ #if defined(FC_IP_SUPPORT) Modified: trunk/qla_isp/linux/isp_scst.c =================================================================== --- trunk/qla_isp/linux/isp_scst.c 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/qla_isp/linux/isp_scst.c 2008-04-17 17:35:37 UTC (rev 337) @@ -88,7 +88,7 @@ #include <linux/seq_file.h> #include <scsi/scsi_host.h> -#include <scsi_tgt.h> +#include <scst.h> #include <scst_debug.h> #ifdef min Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/scst/README 2008-04-17 17:35:37 UTC (rev 337) @@ -62,7 +62,7 @@ To compile SCST type 'make scst'. It will build SCST itself and its device handlers. To install them type 'make scst_install'. The driver modules will be installed in '/lib/modules/`you_kernel_version`/extra'. -In addition, scsi_tgt.h, scst_debug.h as well as Module.symvers or +In addition, scst.h, scst_debug.h as well as Module.symvers or Modules.symvers will be copied to '/usr/local/include/scst'. The first file contains all SCST's public data definition, which are used by target drivers. The other ones support debug messages logging and build Deleted: trunk/scst/include/scsi_tgt.h =================================================================== --- trunk/scst/include/scsi_tgt.h 2008-04-17 15:25:39 UTC (rev 336) +++ trunk/scst/include/scsi_tgt.h 2008-04-17 17:35:37 UTC (rev 337) @@ -1,2734 +0,0 @@ -/* - * include/scsi_tgt.h - * - * Copyright (C) 2004-2007 Vladislav Bolkhovitin <vs...@vl...> - * and Leonid Stoljar - * - * Main SCSI target mid-level include file. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 - * of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __SCST_H -#define __SCST_H - -#include <linux/types.h> -#include <linux/version.h> -#include <linux/blkdev.h> -#include <linux/interrupt.h> -#include <linux/proc_fs.h> - -#ifdef SCST_HIGHMEM -#include <asm/kmap_types.h> -#endif -#include <scsi/scsi_cmnd.h> -#include <scsi/scsi_device.h> -#include <scsi/scsi_eh.h> -#include <scsi/scsi.h> - -#include <scst_const.h> - -#ifndef DECLARE_MUTEX_LOCKED -#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name, 0) -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -typedef _Bool bool; -#endif - -/* Version numbers, the same as for the kernel */ -#define SCST_VERSION_CODE 0x00090601 -#define SCST_VERSION(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + d) -#define SCST_VERSION_STRING "0.9.6-rc1" -#define SCST_INTERFACE_VERSION SCST_VERSION_STRING "$Revision$" SCST_CONST_VERSION - -/************************************************************* - ** States of command processing state machine. At first, - ** "active" states, then - "passive" ones. This is to have - ** more efficient generated code of the corresponding - ** "switch" statements. - *************************************************************/ - -/* Internal parsing */ -#define SCST_CMD_STATE_PRE_PARSE 0 - -/* Dev handler's parse() is going to be called */ -#define SCST_CMD_STATE_DEV_PARSE 1 - -/* Allocation of the cmd's data buffer */ -#define SCST_CMD_STATE_PREPARE_SPACE 2 - -/* Target driver's rdy_to_xfer() is going to be called */ -#define SCST_CMD_STATE_RDY_TO_XFER 3 - -/* Target driver's pre_exec() is going to be called */ -#define SCST_CMD_STATE_TGT_PRE_EXEC 4 - -/* CDB is going to be sent to SCSI mid-level for execution */ -#define SCST_CMD_STATE_SEND_TO_MIDLEV 5 - -/* Internal pos-exec checks */ -#define SCST_CMD_STATE_PRE_DEV_DONE 6 - -/* Internal MODE SELECT pages related checks */ -#define SCST_CMD_STATE_MODE_SELECT_CHECKS 7 - -/* Dev handler's dev_done() is going to be called */ -#define SCST_CMD_STATE_DEV_DONE 8 - -/* Target driver's xmit_response() is going to be called */ -#define SCST_CMD_STATE_PRE_XMIT_RESP 9 - -/* Target driver's xmit_response() is going to be called */ -#define SCST_CMD_STATE_XMIT_RESP 10 - -/* The cmd finished */ -#define SCST_CMD_STATE_FINISHED 11 - -#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED+100) - - -/* A cmd is created, but scst_cmd_init_done() not called */ -#define SCST_CMD_STATE_INIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+1) - -/* LUN translation (cmd->tgt_dev assignment) */ -#define SCST_CMD_STATE_INIT (SCST_CMD_STATE_LAST_ACTIVE+2) - -/* Allocation of the cmd's data buffer */ -#define SCST_CMD_STATE_PREPROCESS_DONE (SCST_CMD_STATE_LAST_ACTIVE+3) - -/* Waiting for data from the initiator (until scst_rx_data() called) */ -#define SCST_CMD_STATE_DATA_WAIT (SCST_CMD_STATE_LAST_ACTIVE+4) - -/* Waiting for CDB's execution finish */ -#define SCST_CMD_STATE_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+5) - -/* Waiting for response's transmission finish */ -#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+6) - -/************************************************************* - * Can be retuned instead of cmd's state by dev handlers' - * functions, if the command's state should be set by default - *************************************************************/ -#define SCST_CMD_STATE_DEFAULT 500 - -/************************************************************* - * Can be retuned instead of cmd's state by dev handlers' - * functions, if it is impossible to complete requested - * task in atomic context. The cmd will be restarted in thread - * context. - *************************************************************/ -#define SCST_CMD_STATE_NEED_THREAD_CTX 1000 - -/************************************************************* - * Can be retuned instead of cmd's state by dev handlers' - * parse function, if the cmd processing should be stopped - * for now. The cmd will be restarted by dev handlers itself. - *************************************************************/ -#define SCST_CMD_STATE_STOP 1001 - -/************************************************************* - ** States of mgmt command processing state machine - *************************************************************/ - -/* LUN translation (mcmd->tgt_dev assignment) */ -#define SCST_MGMT_CMD_STATE_INIT 0 - -/* Mgmt cmd is ready for processing */ -#define SCST_MGMT_CMD_STATE_READY 1 - -/* Mgmt cmd is being executing */ -#define SCST_MGMT_CMD_STATE_EXECUTING 2 - -/* Reservations are going to be cleared, if necessary */ -#define SCST_MGMT_CMD_STATE_CHECK_NEXUS_LOSS 3 - -/* Target driver's task_mgmt_fn_done() is going to be called */ -#define SCST_MGMT_CMD_STATE_DONE 4 - -/* The mcmd finished */ -#define SCST_MGMT_CMD_STATE_FINISHED 5 - -/************************************************************* - ** Constants for "atomic" parameter of SCST's functions - *************************************************************/ -#define SCST_NON_ATOMIC 0 -#define SCST_ATOMIC 1 - -/************************************************************* - ** Values for pref_context parameter of scst_cmd_init_done() and - ** scst_rx_data() - *************************************************************/ - -/* - * Direct cmd's processing (i.e. regular function calls in the current - * context) sleeping is not allowed - */ -#define SCST_CONTEXT_DIRECT_ATOMIC 0 - -/* - * Direct cmd's processing (i.e. regular function calls in the current - * context), sleeping is allowed, no restrictions - */ -#define SCST_CONTEXT_DIRECT 1 - -/* Tasklet or thread context required for cmd's processing */ -#define SCST_CONTEXT_TASKLET 2 - -/* Thread context required for cmd's processing */ -#define SCST_CONTEXT_THREAD 3 - -/* - * SCST internal flag, which specifies that context is processable, i.e. the - * next command in the active list will be processed after the current one. - * - * Target drivers must never use it!! - */ -#define SCST_CONTEXT_PROCESSABLE 0x100 - -/************************************************************* - ** Values for status parameter of scst_rx_data() - *************************************************************/ - -/* Success */ -#define SCST_RX_STATUS_SUCCESS 0 - -/* - * Data receiving finished with error, so set the sense and - * finish the command, including xmit_response() call - */ -#define SCST_RX_STATUS_ERROR 1 - -/* - * Data receiving finished with error and the sense is set, - * so finish the command, including xmit_response() call - */ -#define SCST_RX_STATUS_ERROR_SENSE_SET 2 - -/* - * Data receiving finished with fatal error, so finish the command, - * but don't call xmit_response() - */ -#define SCST_RX_STATUS_ERROR_FATAL 3 - -/************************************************************* - ** Values for status parameter of scst_restart_cmd() - *************************************************************/ - -/* Success */ -#define SCST_PREPROCESS_STATUS_SUCCESS 0 - -/* - * Command's processing finished with error, so set the sense and - * finish the command, including xmit_response() call - */ -#define SCST_PREPROCESS_STATUS_ERROR 1 - -/* - * Command's processing finished with error and the sense is set, - * so finish the command, including xmit_response() call - */ -#define SCST_PREPROCESS_STATUS_ERROR_SENSE_SET 2 - -/* - * Command's processing finished with fatal error, so finish the command, - * but don't call xmit_response() - */ -#define SCST_PREPROCESS_STATUS_ERROR_FATAL 3 - -/* Thread context requested */ -#define SCST_PREPROCESS_STATUS_NEED_THREAD 4 - -/************************************************************* - ** Allowed return codes for xmit_response(), rdy_to_xfer(), - ** report_aen() - *************************************************************/ - -/* Success */ -#define SCST_TGT_RES_SUCCESS 0 - -/* Internal device queue is full, retry again later */ -#define SCST_TGT_RES_QUEUE_FULL -1 - -/* - * It is impossible to complete requested task in atomic context. - * The cmd will be restarted in thread context. - */ -#define SCST_TGT_RES_NEED_THREAD_CTX -2 - -/* - * Fatal error, if returned by xmit_response() the cmd will - * be destroyed, if by any other function, xmit_response() - * will be called with HARDWARE ERROR sense data - */ -#define SCST_TGT_RES_FATAL_ERROR -3 - -/************************************************************* - ** Allowed return codes for dev handler's exec() - *************************************************************/ - -/* The cmd is done, go to other ones */ -#define SCST_EXEC_COMPLETED 0 - -/* The cmd should be sent to SCSI mid-level */ -#define SCST_EXEC_NOT_COMPLETED 1 - -/* - * Thread context is required to execute the command. - * Exec() will be called again in the thread context. - */ -#define SCST_EXEC_NEED_THREAD 2 - -/************************************************************* - ** Default timeout for cmd's CDB execution - ** by SCSI mid-level (cmd's "timeout" field). - *************************************************************/ -#define SCST_DEFAULT_TIMEOUT (30*HZ) - -/************************************************************* - ** Flags of cmd->tgt_resp_flags - *************************************************************/ - -/* - * Set if cmd is finished and there is status/sense to be sent. - * The status should be not sent (i.e. the flag not set) if the - * possibility to perform a command in "chunks" (i.e. with multiple - * xmit_response()/rdy_to_xfer()) is used (not implemented and, - * probably, will never be). - */ -#define SCST_TSC_FLAG_STATUS 0x2 - -/************************************************************* - ** Additional return code for dev handler's task_mgmt_fn() - *************************************************************/ - -/* Regular standard actions for the command should be done */ -#define SCST_DEV_TM_NOT_COMPLETED 1 - -/************************************************************* - ** Session initialization phases - *************************************************************/ - -/* Set if session is being initialized */ -#define SCST_SESS_IPH_INITING 0 - -/* Set if the session is successfully initialized */ -#define SCST_SESS_IPH_SUCCESS 1 - -/* Set if the session initialization failed */ -#define SCST_SESS_IPH_FAILED 2 - -/* Set if session is initialized and ready */ -#define SCST_SESS_IPH_READY 3 - -/************************************************************* - ** Session shutdown phases - *************************************************************/ - -/* Set if session is initialized and ready */ -#define SCST_SESS_SPH_READY 0 - -/* Set if session is on calling pre_unreg_sess() phase */ -#define SCST_SESS_SPH_PRE_UNREG 1 - -/* Set if session is shutting down */ -#define SCST_SESS_SPH_SHUTDOWN 2 - -/************************************************************* - ** Cmd's async (atomic) flags - *************************************************************/ - -/* Set if the cmd is aborted and ABORTED sense will be sent as the result */ -#define SCST_CMD_ABORTED 0 - -/* Set if the cmd is aborted by other initiator */ -#define SCST_CMD_ABORTED_OTHER 1 - -/* Set if no response should be sent to the target about this cmd */ -#define SCST_CMD_NO_RESP 2 - -/* Set if the cmd is dead and can be destroyed at any time */ -#define SCST_CMD_CAN_BE_DESTROYED 3 - -/************************************************************* - ** Tgt_dev's flags (tgt_dev_flags) - *************************************************************/ - -/* Set if tgt_dev has Unit Attention sense */ -#define SCST_TGT_DEV_UA_PENDING 0 - -/* Set if tgt_dev is RESERVED by another session */ -#define SCST_TGT_DEV_RESERVED 1 - -/* Set if the corresponding context is atomic */ -#define SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC 5 -#define SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC 6 -#define SCST_TGT_DEV_AFTER_RESTART_WR_ATOMIC 7 -#define SCST_TGT_DEV_AFTER_RESTART_OTH_ATOMIC 8 -#define SCST_TGT_DEV_AFTER_RX_DATA_ATOMIC 9 -#define SCST_TGT_DEV_AFTER_EXEC_ATOMIC 10 - -#ifdef DEBUG_TM -#define SCST_TGT_DEV_UNDER_TM_DBG 20 -#endif - -/************************************************************* - ** Name of the entry in /proc - *************************************************************/ -#define SCST_PROC_ENTRY_NAME "scsi_tgt" - -/************************************************************* - ** Kernel cache creation helper - *************************************************************/ -#ifndef KMEM_CACHE -#define KMEM_CACHE(__struct, __flags) kmem_cache_create(#__struct,\ - sizeof(struct __struct), __alignof__(struct __struct),\ - (__flags), NULL, NULL) -#endif - -/************************************************************* - * TYPES - *************************************************************/ - -struct scst_tgt; -struct scst_session; -struct scst_cmd; -struct scst_mgmt_cmd; -struct scst_device; -struct scst_tgt_dev; -struct scst_dev_type; -struct scst_acg; -struct scst_acg_dev; -struct scst_acn; - -typedef uint64_t lun_t; - -typedef enum dma_data_direction scst_data_direction; - -enum scst_cdb_flags -{ - SCST_TRANSFER_LEN_TYPE_FIXED = 0x01, /* must be equviv 1 (FIXED_BIT in cdb) */ - SCST_SMALL_TIMEOUT = 0x02, - SCST_LONG_TIMEOUT = 0x04, - SCST_UNKNOWN_LENGTH = 0x08, - SCST_INFO_INVALID = 0x10, -}; - -/* - * Scsi_Target_Template: defines what functions a target driver will - * have to provide in order to work with the target mid-level. - * MUST HAVEs define functions that are expected to be in order to work. - * OPTIONAL says that there is a choice. - * Also, pay attention to the fact that a command is BLOCKING or NON-BLOCKING. - * NON-BLOCKING means that a function returns immediately and will not wait - * for actual data transfer to finish. Blocking in such command could have - * negative impact on overall system performance. If blocking is necessary, - * it is worth to consider creating dedicated thread(s) in target driver, to - * which the commands would be passed and which would perform blocking - * operations instead of SCST. - * If the function allowed to sleep or not is determined by its last - * argument, which is true, if sleeping is not allowed. In this case, - * if the function requires sleeping, it can return - * SCST_TGT_RES_NEED_THREAD_CTX, and it will be recalled in the thread context, - * where sleeping is allowed. - */ -struct scst_tgt_template -{ - /* public: */ - - /* - * SG tablesize allows to check whether scatter/gather can be used - * or not. - */ - int sg_tablesize; - - /* - * True, if this target adapter uses unchecked DMA onto an ISA bus. - */ - unsigned unchecked_isa_dma:1; - - /* - * True, if this target adapter can benefit from using SG-vector - * clustering (i.e. smaller number of segments). - */ - unsigned use_clustering:1; - - /* - * True, if this target adapter doesn't support SG-vector clustering - */ - unsigned no_clustering:1; - - /* - * True, if corresponding function supports execution in - * the atomic (non-sleeping) context - */ - unsigned xmit_response_atomic:1; - unsigned rdy_to_xfer_atomic:1; - unsigned preprocessing_done_atomic:1; - - /* True, if the template doesn't need the entry in /proc */ - unsigned no_proc_entry:1; - - /* - * This function is equivalent to the SCSI - * queuecommand. The target should transmit the response - * buffer and the status in the scst_cmd struct. - * The expectation is that this executing this command is NON-BLOCKING. - * - * After the response is actually transmitted, the target - * should call the scst_tgt_cmd_done() function of the - * mid-level, which will allow it to free up the command. - * Returns one of the SCST_TGT_RES_* constants. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * MUST HAVE - */ - int (*xmit_response) (struct scst_cmd *cmd); - - /* - * This function informs the driver that data - * buffer corresponding to the said command have now been - * allocated and it is OK to receive data for this command. - * This function is necessary because a SCSI target does not - * have any control over the commands it receives. Most lower - * level protocols have a corresponding function which informs - * the initiator that buffers have been allocated e.g., XFER_ - * RDY in Fibre Channel. After the data is actually received - * the low-level driver needs to call scst_rx_data() in order to - * continue processing this command. - * Returns one of the SCST_TGT_RES_* constants. - * This command is expected to be NON-BLOCKING. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * OPTIONAL - */ - int (*rdy_to_xfer) (struct scst_cmd *cmd); - - /* - * Called to notify the driver that the command is about to be freed. - * Necessary, because for aborted commands xmit_response() could not - * be called. Could be called on IRQ context. - * - * OPTIONAL - */ - void (*on_free_cmd) (struct scst_cmd *cmd); - - /* - * This function allows target driver to handle data buffer - * allocations on its own. - * - * Target driver doesn't have to always allocate buffer in this - * function, but if it decide to do it, it must check that - * scst_cmd_get_data_buff_alloced() returns 0, otherwise to avoid - * double buffer allocation and memory leaks alloc_data_buf() shall - * fail. - * - * Shall return 0 in case of success or < 0 (preferrably -ENOMEM) - * in case of error, or > 0 if the regular SCST allocation should be - * done. In case of returning successfully, scst_cmd->data_buf_alloced - * will be set by SCST. - * - * If allocation in atomic context - cf. scst_cmd_atomic() - is not - * desired or fails and consequently < 0 is returned, this function - * will be re-called in thread context. - * - * Please note that the driver will have to handle itself all relevant - * details such as scatterlist setup, highmem, freeing the allocated - * memory, etc. - * - * OPTIONAL. - */ - int (*alloc_data_buf) (struct scst_cmd *cmd); - - /* - * This function informs the driver that data - * buffer corresponding to the said command have now been - * allocated and other preprocessing tasks have been done. - * A target driver could need to do some actions at this stage. - * After the target driver done the needed actions, it shall call - * scst_restart_cmd() in order to continue processing this command. - * - * Called only if the cmd is queued using scst_cmd_init_stage1_done() - * instead of scst_cmd_init_done(). - * - * Returns void, the result is expected to be returned using - * scst_restart_cmd(). - * - * This command is expected to be NON-BLOCKING. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * OPTIONAL. - */ - void (*preprocessing_done) (struct scst_cmd *cmd); - - /* - * This function informs the driver that the said command is about - * to be executed. - * - * Returns one of the SCST_PREPROCESS_* constants. - * - * This command is expected to be NON-BLOCKING. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * OPTIONAL - */ - int (*pre_exec) (struct scst_cmd *cmd); - - /* - * This function informs the driver that a - * received task management function has been completed. This - * function is necessary because low-level protocols have some - * means of informing the initiator about the completion of a - * Task Management function. This function being called will - * signify that a Task Management function is completed as far - * as the mid-level is concerned. Any information that must be - * stored about the command is the responsibility of the low- - * level driver. No return value expected. - * This function is expected to be NON-BLOCKING - * - * Called without any locks held from a thread context. - * - * MUST HAVE if the target supports ABORTs - */ - void (*task_mgmt_fn_done) (struct scst_mgmt_cmd *mgmt_cmd); - - /* - * This function should detect the target adapters that - * are present in the system. The function should return a value - * >= 0 to signify the number of detected target adapters. - * A negative value should be returned whenever there is - * an error. - * - * MUST HAVE - */ - int (*detect) (struct scst_tgt_template *tgt_template); - - /* - * This function should free up the resources allocated to the device. - * The function should return 0 to indicate successful release - * or a negative value if there are some issues with the release. - * In the current version the return value is ignored. - * - * MUST HAVE - */ - int (*release) (struct scst_tgt *tgt); - - /* - * This function is used for Asynchronous Event Notification. - * It is the responsibility of the driver to notify any/all - * initiators about the Asynchronous Event reported. - * Returns one of the SCST_TGT_RES_* constants. - * This command is expected to be NON-BLOCKING, but can sleep. - * - * MUST HAVE if low-level protocol supports AEN - * - * ToDo - */ - int (*report_aen) (int mgmt_fn, const uint8_t *lun, int lun_len); - - /* - * Those functions can be used to export the driver's statistics and - * other infos to the world outside the kernel as well as to get some - * management commands from it. - * - * OPTIONAL - */ - int (*read_proc) (struct seq_file *seq, struct scst_tgt *tgt); - int (*write_proc) (char *buffer, char **start, off_t offset, - int length, int *eof, struct scst_tgt *tgt); - - /* - * Name of the template. Must be unique to identify - * the template. MUST HAVE - */ - const char name[50]; - - /* - * Number of additional threads to the pool of dedicated threads. - * Used if xmit_response() or rdy_to_xfer() is blocking. - * It is the target driver's duty to ensure that not more, than that - * number of threads, are blocked in those functions at any time. - */ - int threads_num; - - /* Private, must be inited to 0 by memset() */ - - /* List of targets per template, protected by scst_mutex */ - struct list_head tgt_list; - - /* List entry of global templates list */ - struct list_head scst_template_list_entry; - - /* The pointer to the /proc directory entry */ - struct proc_dir_entry *proc_tgt_root; - - /* Device number in /proc */ - int proc_dev_num; -}; - -struct scst_dev_type -{ - /* SCSI type of the supported device. MUST HAVE */ - int type; - - /* - * True, if corresponding function supports execution in - * the atomic (non-sleeping) context - */ - unsigned parse_atomic:1; - unsigned exec_atomic:1; - unsigned dev_done_atomic:1; - - /* Set, if no /proc files should be automatically created by SCST */ - unsigned no_proc:1; - - /* Set, if exec() is synchronous */ - unsigned exec_sync:1; - - /* - * Called to parse CDB from the cmd and initialize - * cmd->bufflen and cmd->data_direction (both - REQUIRED). - * Returns the command's next state or SCST_CMD_STATE_DEFAULT, - * if the next default state should be used, or - * SCST_CMD_STATE_NEED_THREAD_CTX if the function called in atomic - * context, but requires sleeping, or SCST_CMD_STATE_STOP if the - * command should not be further processed for now. In the - * SCST_CMD_STATE_NEED_THREAD_CTX case the function - * will be recalled in the thread context, where sleeping is allowed. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * MUST HAVE - */ - int (*parse) (struct scst_cmd *cmd); - - /* - * Called to execute CDB. Useful, for instance, to implement - * data caching. The result of CDB execution is reported via - * cmd->scst_cmd_done() callback. - * Returns: - * - SCST_EXEC_COMPLETED - the cmd is done, go to other ones - * - SCST_EXEC_NEED_THREAD - thread context is required to execute - * the command. Exec() will be called again in the thread context. - * - SCST_EXEC_NOT_COMPLETED - the cmd should be sent to SCSI mid-level. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - * - * If this function provides sync execution, you must set above - * exec_sync flag and should consider to setup dedicated threads by - * setting threads_num > 0. - * - * !! If this function is implemented, scst_check_local_events() shall !! - * !! be called inside it just before the actual command's execution. !! - * - * OPTIONAL, if not set, the commands will be sent directly to SCSI - * device. - */ - int (*exec) (struct scst_cmd *cmd); - - /* - * Called to notify dev handler about the result of cmd execution - * and perform some post processing. Cmd's fields tgt_resp_flags and - * resp_data_len should be set by this function, but SCST offers good - * defaults. - * Returns the command's next state or SCST_CMD_STATE_DEFAULT, - * if the next default state should be used, or - * SCST_CMD_STATE_NEED_THREAD_CTX if the function called in atomic - * context, but requires sleeping. In the last case, the function - * will be recalled in the thread context, where sleeping is allowed. - * - * Pay attention to "atomic" attribute of the cmd, which can be get - * by scst_cmd_atomic(): it is true if the function called in the - * atomic (non-sleeping) context. - */ - int (*dev_done) (struct scst_cmd *cmd); - - /* - * Called to notify dev hander that the command is about to be freed. - * Could be called on IRQ context. - */ - void (*on_free_cmd) (struct scst_cmd *cmd); - - /* - * Called to execute a task management command. - * Returns: - * - SCST_MGMT_STATUS_SUCCESS - the command is done with success, - * no firther actions required - * - The SCST_MGMT_STATUS_* error code if the command is failed and - * no firther actions required - * - SCST_DEV_TM_NOT_COMPLETED - regular standard actions for the command - * should be done - * - * Called without any locks held from a thread context. - */ - int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd, - struct scst_tgt_dev *tgt_dev); - - /* - * Called when new device is attaching to the dev handler - * Returns 0 on success, error code otherwise. - */ - int (*attach) (struct scst_device *dev); - - /* Called when new device is detaching from the dev handler */ - void (*detach) (struct scst_device *dev); - - /* - * Called when new tgt_dev (session) is attaching to the dev handler. - * Returns 0 on success, error code otherwise. - */ - int (*attach_tgt) (struct scst_tgt_dev *tgt_dev); - - /* - * Called when a session, corresponding to a tgt_dev, is about to be - * unregistered and the tgt_dev - detached. Supposed to be used to - * clean out "stalled" commands, which otherwise could prevent SCST - * from entering into the suspended activity state and, so, - * unregistering the device. - */ - void (*pre_unreg_sess) (struct scst_tgt_dev *tgt_dev); - - /* Called when tgt_dev (session) is detaching from the dev handler */ - void (*detach_tgt) (struct scst_tgt_dev *tgt_dev); - - /* - * Those functions can be used to export the handler's statistics and - * other infos to the world outside the kernel as well as to get some - * management commands from it. - * - * OPTIONAL - */ - int (*read_proc) (struct seq_file *seq, struct scst_dev_type *dev_type); - int (*write_proc) (char *buffer, char **start, off_t offset, - int length, int *eof, struct scst_dev_type *dev_type); - - /* Name of the dev handler. Must be unique. MUST HAVE */ - char name[15]; - - /* - * Number of dedicated threads. If 0 - no dedicated threads will - * be created, if <0 - creation of dedicated threads is prohibited. - */ - int threads_num; - - struct module *module; - - /* private: */ - - /* list entry in scst_dev_type_list */ - struct list_head dev_type_list_entry; - - /* The pointer to the /proc directory entry */ - struct proc_dir_entry *proc_dev_type_root; -}; - -struct scst_tgt -{ - /* List of remote sessions per target, protected by scst_mutex */ - struct list_head sess_list; - - /* List entry of targets per template (tgts_list) */ - struct list_head tgt_list_entry; - - struct scst_tgt_template *tgtt; /* corresponding target template */ - - /* Used to wait until session finished to unregister */ - wait_queue_head_t unreg_waitQ; - - /* Device number in /proc */ - int proc_num; - - /* - * The following fields used to store and retry cmds if - * target's internal queue is full, so the target is unable to accept - * the cmd returning QUEUE FULL - */ - atomic_t finished_cmds; - int retry_cmds; /* protected by tgt_lock */ - spinlock_t tgt_lock; - struct list_head retry_cmd_list; /* protected by tgt_lock */ - struct timer_list retry_timer; - int retry_timer_active; - - /* - * Maximum SG table size. Needed here, since different cards on the - * same target template can have different SG table limitations. - */ - int sg_tablesize; - - /* Used for storage of target driver private stuff */ - void *tgt_priv; - - /* Name on the default security group ("Default_target_name") */ - char *default_group_name; -}; - -/* Hash size and hash fn for hash based lun translation */ -#define TGT_DEV_HASH_SHIFT 5 -#define TGT_DEV_HASH_SIZE (1<<TGT_DEV_HASH_SHIFT) -#define HASH_VAL(_val) (_val & (TGT_DEV_HASH_SIZE - 1)) - -struct scst_session -{ - /* - * Initialization phase, one of SCST_SESS_IPH_* constants, protected by - * sess_list_lock - */ - int init_phase; - - atomic_t refcnt; /* get/put counter */ - - /**************************************************************/ - - /* Alive commands for this session. ToDo: make it part of the common IO flow control */ - atomic_t sess_cmd_count; - - spinlock_t sess_list_lock; /* protects search_cmd_list, etc */ - - /* - * List of cmds in this session. Used to find a cmd in the - * session. Protected by sess_list_lock. - */ - struct list_head search_cmd_list; - - /* - * Hash list of tgt_dev's for this session, protected by scst_mutex - * and suspended activity - */ - struct list_head sess_tgt_dev_list_hash[TGT_DEV_HASH_SIZE]; - - /* Access control for this session and list entry there */ - struct scst_acg *acg; - - /* List entry for the sessions list inside ACG */ - struct list_head acg_sess_list_entry; - - struct scst_tgt *tgt; /* corresponding target */ - - /* Used for storage of target driver private stuff */ - void *tgt_priv; - - /* Name of attached initiator */ - const char *initiator_name; - - /* List entry of sessions per target */ - struct list_head sess_list_entry; - - /* List entry for the list that keeps session, waiting for the init */ - struct list_head sess_init_list_entry; - - /* List entry for the list that keeps session, waiting for the shutdown */ - struct list_head sess_shut_list_entry; - - /* - * Lists of deffered during session initialization commands. - * Protected by sess_list_lock. - */ - struct list_head init_deferred_cmd_list; - struct list_head init_deferred_mcmd_list; - - /* - * Shutdown phase, one of SCST_SESS_SPH_* constants, unprotected. - * Async. relating to init_phase, must be a separate variable, because - * session could be unregistered before async. registration is finished. - */ - unsigned long shut_phase; - - /* Used if scst_unregister_session() called in wait mode */ - struct completion *shutdown_compl; - - /* - * Functions and data for user callbacks from scst_register_session() - * and scst_unregister_session() - */ - void *reg_sess_data; - void (*init_result_fn) (struct scst_session *sess, void *data, - int result); - void (*unreg_done_fn) (struct scst_session *sess); - void (*unreg_cmds_done_fn) (struct scst_session *sess); - -#ifdef MEASURE_LATENCY /* must be last */ - spinlock_t meas_lock; - uint64_t scst_time, processing_time; - unsigned int processed_cmds; -#endif -}; - -struct scst_cmd_lists -{ - spinlock_t cmd_list_lock; - struct list_head active_cmd_list; - wait_queue_head_t cmd_list_waitQ; - struct list_head lists_list_entry; -}; - -struct scst_cmd -{ - /* List entry for below *_cmd_lists */ - struct list_head cmd_list_entry; - - /* Pointer to lists of commands with the lock */ - struct scst_cmd_lists *cmd_lists; - - atomic_t cmd_ref; - - struct scst_session *sess; /* corresponding session */ - - /* Cmd state, one of SCST_CMD_STATE_* constants */ - int state; - - /************************************************************* - ** Cmd's flags - *************************************************************/ - /* - * Set if expected_sn was incremented, i.e. cmd was sent to - * SCSI mid-level for execution - */ - unsigned int sent_to_midlev:1; - - /* Set if scst_local_exec() was already called for this cmd */ - unsigned int local_exec_done:1; - - /* Set if the cmd's action is completed */ - unsigned int completed:1; - - /* Set if we should ignore Unit Attention in scst_check_sense() */ - unsigned int ua_ignore:1; - - /* Set if cmd is being processed in atomic context */ - unsigned int atomic:1; - - /* - * Set if the cmd is being processed in the processable context. See - * comment for SCST_CONTEXT_PROCESSABLE for what it means. - */ - unsigned int context_processable:1; - - /* Set if cmd is internally generated */ - unsigned int internal:1; - - /* Set if cmd is being retried */ - unsigned int retry:1; - - /* Set if the device was blocked by scst_inc_on_dev_cmd() (for debug) */ - unsigned int inc_blocking:1; - - /* Set if the device should be unblocked after cmd's finish */ - unsigned int needs_unblocking:1; - - /* Set if scst_dec_on_dev_cmd() call is needed on the cmd's finish */ - unsigned int dec_on_dev_needed:1; - - /* - * Set if the target driver wants to alloc data buffers on its own. - * In this case alloc_data_buf() must be provided in the target driver - * template. - */ - unsigned int data_buf_tgt_alloc:1; - - /* - * Set by SCST if the custom data buffer allocation by the target driver - * succeeded. - */ - unsigned int data_buf_alloced:1; - - /* Set if the target driver called scst_set_expected() */ - unsigned int expected_values_set:1; - - /* - * Set if the cmd was delayed by task management debugging code. - * Used only if DEBUG_TM is on. - */ - unsigned int tm_dbg_delayed:1; - - /* - * Set if the cmd must be ignored by task management debugging code. - * Used only if DEBUG_TM is on. - */ - unsigned int tm_dbg_immut:1; - - /* - * Set if the SG buffer was modified by scst_set_resp_data_len() - */ - unsigned int sg_buff_modified:1; - - /* - * Set if scst_cmd_init_stage1_done() called and the target - * want that preprocessing_done() will be called - */ - unsigned int preprocessing_only:1; - - /* Set if cmd's SN was set */ - unsigned int sn_set:1; - - /* Set if hq_cmd_count was incremented */ - unsigned int hq_cmd_inced:1; - - /* - * Set if scst_cmd_init_stage1_done() called and the target wants - * that the SN for the cmd won't be assigned until scst_restart_cmd() - */ - unsigned int set_sn_on_restart_cmd:1; - - /* Set if the cmd's must not use sgv cache for data buffer */ - unsigned int no_sgv:1; - - /* - * Set if target driver may need to call dma_sync_sg() or similar - * function before transferring cmd' data to the target device - * via DMA. - */ - unsigned int may_need_dma_sync:1; - - /* Set if the cmd was done or aborted out of its SN */ - unsigned int out_of_sn:1; - - /* Set if increment expected_sn in cmd->scst_cmd_done() */ - unsigned int inc_expected_sn_on_done:1; - - /* - * Set if xmit_response() is going to need a considerable processing - * time. Processing time is considerable, if it's > context switch time - * (about 1 usec on modern systems). It's needed to trigger other - * threads to start processing other outstanding commands without - * waiting XMIT for the current one to finish. E.g., it should be set - * if iSCSI data digest used and cmd has READ direction. - */ - unsigned int long_xmit:1; - - /* Set if tgt_sn field is valid */ - unsigned int tgt_sn_set:1; - - /* Set if cmd is done */ - unsigned int done:1; - - /* Set if cmd is finished */ - unsigned int finished:1; - - /**************************************************************/ - - unsigned long cmd_flags; /* cmd's async flags */ - - /* Keeps status of cmd's status/data delivery to remote initiator */ - int delivery_status; - - struct scst_tgt_template *tgtt; /* to save extra dereferences */ - struct scst_tgt *tgt; /* to save extra dereferences */ - struct scst_device *dev; /* to save extra dereferences */ - - struct scst_tgt_dev *tgt_dev; /* corresponding device for this cmd */ - - lun_t lun; /* LUN for this cmd */ - - unsigned long start_time; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) - struct scsi_request *scsi_req; /* SCSI request */ -#endif - - /* List entry for tgt_dev's SN related lists */ - struct list_head sn_cmd_list_entry; - - /* Cmd's serial number, used to execute cmd's in order of arrival */ - unsigned long sn; - - /* The corresponding sn_slot in tgt_dev->sn_slots */ - atomic_t *sn_slot; - - /* List entry for session's search_cmd_list */ - struct list_head search_cmd_list_entry; - - /* - * Used to found the cmd by scst_find_cmd_by_tag(). Set by the - * target driver on the cmd's initialization time - */ - uint64_t tag; - - uint32_t tgt_sn; /* SN set by target driver (for TM purposes) */ - - /* CDB and its len */ - uint8_t cdb[SCST_MAX_CDB_SIZE]; - int cdb_len; - - enum scst_cdb_flags op_flags; - const char *op_name; - - enum scst_cmd_queue_type queue_type; - - int timeout; /* CDB execution timeout */ - int retries; /* Amount of retries that will be done by SCSI mid-level */ - - /* SCSI data direction, one of SCST_DATA_* constants */ - scst_data_direction data_direction; - - /* Remote initiator supplied values, if any */ - scst_data_direction expected_data_direction; - int expected_transfer_len; - - /* - * Cmd data length. Could be different from bufflen for commands like - * VERIFY, which transfer different amount of data (if any), than - * processed. - */ - int data_len; - - /* Completition routine */ - void (*scst_cmd_done) (struct scst_cmd *cmd, int next_state); - - struct sgv_pool_obj *sgv; /* sgv object */ - - int bufflen; /* cmd buffer length */ - struct scatterlist *sg; /* cmd data buffer SG vector */ - int sg_cnt; /* SG segments count */ - - /* scst_get_sg_buf_[first,next]() support */ - int get_sg_buf_entry_num; - - /* - * The following two fields should be corrected by the dev_done(), - * if necessary - */ - int tgt_resp_flags; /* response flags (SCST_TSC_FLAG_* constants) */ - - /* - * Response data length in data buffer. This field must not be set - * directly, use scst_set_resp_data_len() for that - */ - int resp_data_len; - - uint8_t status; /* status byte from target device */ - uint8_t msg_status; /* return status from host adapter itself */ - uint8_t host_status; /* set by low-level driver to indicate status */ - uint8_t driver_status; /* set by mid-level */ - - uint8_t *sense; /* pointer to sense buffer */ - - /* Used for storage of target driver private stuff */ - void *tgt_priv; - - /* Used for storage of dev handler private stuff */ - void *dh_priv; - - /* - * Used to restore the SG vector if it was modified by - * scst_set_resp_data_len() - */ - int orig_sg_cnt, orig_sg_entry, orig_entry_len; - - /* List corresponding mgmt cmd, if any, protected by sess_list_lock */ - struct list_head mgmt_cmd_list; - - /* List entry for dev's blocked_cmd_list */ - struct list_head blocked_cmd_list_entry; - - struct scst_cmd *orig_cmd; /* Used to issue REQUEST SENSE */ - -#ifdef MEASURE_LATENCY /* must be last */ - uint64_t start, pre_exec_finish, post_exec_start; -#endif -}; - -struct scst_rx_mgmt_params -{ - int fn; - uint64_t tag; - const uint8_t *lun; - int lun_len; - uint32_t cmd_sn; - int atomic; - void *tgt_priv; - unsigned char tag_set; - unsigned char lun_set; - unsigned char cmd_sn_set; -}; - -struct scst_mgmt_cmd_stub -{ - struct scst_mgmt_cmd *mcmd; - - /* List entry in cmd->mgmt_cmd_list */ - struct list_head cmd_mgmt_cmd_list_entry; -}; - -struct scst_mgmt_cmd -{ - /* List entry for *_mgmt_cmd_list */ - struct list_head mgmt_cmd_list_entry; - - struct scst_session *sess; - - /* Mgmt cmd state, one of SCST_MGMT_CMD_STATE_* constants */ - int state; - - int fn; - - unsigned int completed:1; /* set, if the mcmd is completed */ - /* Set if device(s) should be unblocked after mcmd's finish */ - unsigned int needs_unblocking:1; - unsigned int lun_set:1; /* set, if lun field is valid */ - unsigned int cmd_sn_set:1; /* set, if cmd_sn field is valid */ - unsigned int nexus_loss_check_done:1; /* set, if nexus loss check is done */ - - /* - * Number of commands to finish before sending response, - * protected by scst_mcmd_lock - */ - int cmd_finish_wait_count; - - /* - * Number of commands to complete (done) before resetting reservation, - * protected by scst_mcmd_lock - */ - int cmd_done_wait_count; - - /* Number of completed commands, protected by scst_mcmd_lock */ - int completed_cmd_count; - - lun_t lun; /* LUN for this mgmt cmd */ - /* or (and for iSCSI) */ - uint64_t tag; /* tag of the corresponding cmd */ - - uint32_t cmd_sn; /* affected command's highest SN */ - - /* corresponding cmd (to be aborted, found by tag) */ - struct scst_cmd *cmd_to_abort; - - /* corresponding device for this mgmt cmd (found by lun) */ - struct scst_tgt_dev *mcmd_tgt_dev; - - /* completition status, one of the SCST_MGMT_STATUS_* constants */ - int status; - - /* Used for storage of target driver private stuff */ - void *tgt_priv; -}; - -struct scst_device -{ - struct scst_dev_type *handler; /* corresponding dev handler */ - - /* Pointer to lists of commands with the lock */ - struct scst_cmd_lists *p_cmd_lists; - - /* Lists of commands with lock, if dedicated threads are used */ - struct scst_cmd_lists cmd_lists; - - /* How many cmds alive on this dev */ - atomic_t dev_cmd_count; - - unsigned short type; /* SCSI type of the device */ - - /************************************************************* - ** Dev's flags. Updates serialized by dev_lock or suspended - ** activity - *************************************************************/ - - /* Set if dev is RESERVED */ - unsigned short dev_reserved:1; - - /* Set if dev accepts only one command at time */ - unsigned short dev_serialized:1; - - /* Set if double reset UA is possible */ - unsigned short dev_double_ua_possible:1; - - /* Set if reset UA sent (to avoid double reset UAs) */ - unsigned short dev_reset_ua_sent:1; - - /**************************************************************/ - - /************************************************************* - ** Dev's control mode page related values. Updates serialized - ** by scst_block_dev(). It's long to not interfere with the - ** above flags. - *************************************************************/ - - unsigned long queue_alg:4; - unsigned long tst:3; - unsigned long tas:1; - unsigned long swp:1; - - /* - * Set if device implements own ordered commands management. If not set - * and queue_alg is SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER, - * expected_sn will be incremented only after commands finished. - */ - unsigned long has_own_order_mgmt:1; - - /**************************************************************/ - - spinlock_t dev_lock; /* device lock */ - - /* - * How many times device was blocked for new cmds execution. - * Protected by dev_lock - */ - int block_count; - - /* - * How many there are "on_dev" commands, i.e. ones those are being - * executed by the underlying SCSI/virtual device. - */ - atomic_t on_dev_count; - - struct list_head blocked_cmd_list; /* protected by dev_lock */ - - /* Used for storage of dev handler private stuff */ - void *dh_priv; - - /* Used to translate SCSI's cmd to SCST's cmd */ - struct gendisk *rq_disk; - - /* Corresponding real SCSI device, could be NULL for virtual devices */ - struct scsi_device *scsi_dev; - - /* Used to wait for requested amount of "on_dev" commands */ - wait_queue_head_t on_dev_waitQ; - - /* A list entry used during TM, protected by scst_mutex */ - struct list_head tm_dev_list_entry; - - /* Virtual device internal ID */ - int virt_id; - - /* Pointer to virtual device name, for convenience only */ - const char *virt_name; - - /* List entry in global devices list */ - struct list_head dev_list_entry; - - /* - * List of tgt_dev's, one per session, protected by scst_mutex or - * dev_lock for reads and both for writes - */ - struct list_head dev_tgt_dev_list; - - /* List of acg_dev's, one per acg, protected by scst_mutex */ - struct list_head dev_acg_dev_list; - - /* List of dedicated threads, protected by scst_mutex */ - struct list_head threads_list; - - /* Device number */ - int dev_num; -}; - -/* - * Used to store threads local tgt_dev specific data - */ -struct scst_thr_data_hdr -{ - /* List entry in tgt_dev->thr_data_list */ - struct list_head thr_data_list_entry; - pid_t pid; /* PID of the owner thread */ - atomic_t ref; - /* Function that will be called on the tgt_dev destruction */ - void (*free_fn) (struct scst_thr_data_hdr *data); -}; - -/* - * Used to store per-session specific device information - */ -struct scst_tgt_dev -{ - /* List entry in sess->sess_tgt_dev_list_hash */ - struct list_head sess_tgt_dev_list_entry; - - struct scst_device *dev; /* to save extra dereferences */ - lun_t lun; /* to save extra dereferences */ - - /* How many cmds alive on this dev in this session */ - atomic_t tgt_dev_cmd_count; - - int gfp_mask; - struct sgv_pool *pool; - int max_sg_cnt; - - unsigned long tgt_dev_flags; /* tgt_dev's async flags */ - - /* - * Used to execute cmd's in order of arrival, honoring SCSI task - * attributes. - * - * Protected by sn_lock, except expected_sn, which is protected by - * itself. Curr_sn must have the same size as expected_sn to - * overflow simultaneously. - */ - int def_cmd_count; - spinlock_t sn_lock; - unsigned long expected_sn; - unsigned long curr_sn; - int hq_cmd_count; - struct list_head deferred_cmd_list; - struct list_head skipped_sn_list; - - /* - * Set if the prev cmd was ORDERED. Size must allow unprotected - * modifications - */ - unsigned long prev_cmd_ordered; - - int num_free_sn_slots; /* if it's <0, then all slots are busy */ - atomic_t *cur_sn_slot; - atomic_t sn_slots[15]; - - /* Used for storage of dev handler private stuff */ - void *dh_priv; - - /* List of scst_thr_data_hdr and lock */ - spinlock_t thr_data_lock; - struct list_head thr_data_list; - - spinlock_t tgt_dev_lock; /* per-session device lock */ - - /* List of UA's for this device, protected by tgt_dev_lock */ - struct list_head UA_list; - - struct scst_session *sess; /* corresponding session */ - struct scst_acg_dev *acg_dev; /* corresponding acg_dev */ - - /* list entry in dev->dev_tgt_dev_list */ - struct list_head dev_tgt_dev_list_entry; - - /* internal tmp list entry */ - struct list_head extra_tgt_dev_list_entry; -}; - -/* - * Used to store ACG-specific device information, like LUN - */ -struct scst_acg_dev -{ - struct scst_device *dev; /* corresponding device */ - lun_t lun; /* device's LUN in this acg */ - unsigned int rd_only_flag:1; /* if != 0, then read only */ - struct scst_acg *acg; /* parent acg */ - - /* list entry in dev->dev_acg_dev_list */ - struct list_head dev_acg_dev_list_entry; - - /* list entry in acg->acg_dev_list */ - struct list_head acg_dev_list_entry; -}; - -/* - * ACG - access control group. Used to store group related - * control information. - */ -struct scst_acg -{ - /* List of acg_dev's in this acg, protected by scst_mutex */ - struct list_head acg_dev_list; - - /* List of attached sessions, protected by scst_mutex */ - struct list_head acg_sess_list; - - /* List of attached acn's, protected by scst_mutex */ - struct list_head acn_list; - - /* List entry in scst_acg_list */ - struct list_head scst_acg_list_entry; - - /* Name of this acg */ - const char *acg_name; - - /* The pointer to the /proc directory entry */ - struct proc_dir_entry *acg_proc_root; -}; - -/* - * ACN - access control name. Used to store names, by which - * incoming sessions will be assigned to appropriate ACG. - */ -struct scst_acn -{ - /* Initiator's name */ - const char *name; - /* List entry in acg->acn_list */ - struct list_head acn_list_entry; -}; - -/* - * Used to store per-session UNIT ATTENTIONs - */ -struct scst_tgt_dev_UA -{ - /* List entry in tgt_dev->UA_list */ - struct list_head UA_list_entry; - /* Unit Attention sense */ - uint8_t UA_sense_buffer[SCST_SENSE_BUFFERSIZE]; -}; - -#ifndef smp_mb__after_set_bit -/* There is no smp_mb__after_set_bit() in the kernel */ -#define smp_mb__after_set_bit() smp_mb(); -#endif - -/* - * Registers target template - * Returns 0 on success or appropriate error code otherwise - */ -int __scst_register_target_template(struct scst_tgt_template *vtt, - const char *version); -static inline int scst_register_target_template(struct scst_tgt_template *vtt) -{ - return __scst_register_target_template(vtt, SCST_INTERFACE_VERSION); -} - -/* - * Unregisters target template - */ -void scst_unregister_target_template(struct scst_tgt_template *vtt); - -/* - * Registers and returns target adapter - * Returns new target structure on success or NULL otherwise. - * - * If parameter "target_name" isn't NULL, then security group with name - * "Default_##target_name", if created, will be used as the default - * instead of "Default" one for all initiators not assigned to any other group. - */ -struct scst_tgt *scst_register(struct scst_tgt_template *vtt, - const char *target_name); - -/* - * Unregisters target adapter - */ -void scst_unregister(struct scst_tgt *tgt); - -/* - * Registers and returns a session - * - * Returns new session on success or NULL otherwise - * - * Parameters: - * tgt - target - * atomic - true, if the function called in the atomic context - * initiator_name - remote initiator's name, any NULL-terminated string, - * e.g. iSCSI name, which used as the key to found appropriate access - * control group. Could be NULL, then "default" group is used. - * The groups are set up via /proc interface. - * data - any target driver supplied data - * result_fn - pointer to the function that will be - * asynchronously called when session initialization finishes. - * Can be NULL. Parameters: - * - sess - session - * - data - target driver supplied to scst_register_session() data - * - result - session initialization result, 0 on success or - * appropriate error code otherwise - * - * Note: A session creation and initialization is a complex task, - * which requires sleeping state, so it can't be fully done - * in interrupt context. Therefore the "bottom half" of it, if - * scst_register_session() is called from atomic context, will be - * done in SCST thread context. In this case scst_register_session() - * will return not completely initialized session, but the target - * driver can supply commands to this session via scst_rx_cmd(). - * Those commands processing will be delayed inside SCST until - * the session initialization is finished, then their processing - * will be restarted. The target driver will be notified about - * finish of the session initialization by function result_fn(). - * On success the target driver could do nothing, but if the - * initialization fails, the target driver must ensure that - * no more new commands being sent or will be sent to SCST after - * result_fn() returns. All already sent to SCST commands for - * failed session will be returned in xmit_response() with BUSY status. - * In case of failure the driver shall call scst_unregister_session() - * inside result_fn(), it will NOT be called automatically. - */ -struct scst_session *scst_register_session(struct scst_tgt *tgt, int atomic, - const char *initiator_name, void *data, - void (*result_fn) (struct scst_session *sess, void *data, int result)); - -/* - * Unregisters a session. - * Parameters: - * sess - session to be unregistered - * wait - if true, instructs to wait until all commands, which - * currently is being executed and belonged to the session, finished. - * Otherwise, target driver should be prepared to receive - * xmit_response() for the session's command after - * scst_unregister_session() returns. - * unreg_done_fn - pointer to the function that will be - * asynchronously called when the last session's command finishes and - * the session is about to be completely freed. Can be NULL. - * Parameter: - * - sess - session - * unreg_cmds_done_fn - pointer to the function that will be - * asynchronously called when the last session's command completes, i.e. - * goes to XMIT stage. Can be NULL. - * Parameter: - * - sess - session - * - * Notes: - * - * - All outstanding commands will be finished regularly. After - * scst_unregister_session() returned no new commands must be sent to - * SCST via scst_rx_cmd(). - * - * - The caller must ensure that no scst_rx_cmd() or scst_rx_mgmt_fn_*() is - * called in paralell with scst_unregister_session(). - * - * - Can be called before result_fn() of scst_register_session() called, - * i.e. during the session registration/initialization. - * - * - It is highly recommended to call scst_unregister_session() as soon as it - * gets clear that session will be unregistered and not to wait until all - * related commands finished. This function provides the wait functionality, - * but it also starts recovering stuck commands, if there are any. - * Otherwise, your target driver could wait for those commands forever. - */ -void scst_unregister_session_ex(struct scst_session *sess, int wait, - void (*unreg_done_fn) (struct scst_session *sess), - void (*unreg_cmds_done_fn) (struct scst_session *sess)); - -static inline void scst_unregister_session(struct scst_session *sess, int wait, - void (*unreg_done_fn) (struct scst_session *sess)) -{ - scst_unregister_session_ex(sess, wait, unreg_done_fn, NULL); -} - -/* - * Registers dev handler driver - * Returns 0 on success or appropriate error code otherwise - */ -int __scst_register_dev_driver(struct scst_dev_type *dev_type, - const char *version); -static inline int scst_register_dev_driver(struct scst_dev_type *dev_type) -{ - return __scst_register_dev_driver(dev_type, SCST_INTERFACE_VERSION); -} - -/* - * Unregisters dev handler driver - */ -void scst_unregister_dev_driver(struct scst_dev_type *dev_type); - -/* - * Registers dev handler driver for virtual devices (eg VDISK) - * Returns 0 on success or appropriate error code oth... [truncated message content] |
From: <vl...@us...> - 2008-04-18 16:57:25
|
Revision: 339 http://scst.svn.sourceforge.net/scst/?rev=339&view=rev Author: vlnb Date: 2008-04-18 09:42:10 -0700 (Fri, 18 Apr 2008) Log Message: ----------- More svn:ignore fixes Property Changed: ---------------- trunk/ trunk/doc/ trunk/iscsi-scst/ trunk/iscsi-scst/doc/ trunk/iscsi-scst/doc/manpages/ trunk/iscsi-scst/etc/ trunk/iscsi-scst/etc/initd/ trunk/iscsi-scst/include/ trunk/iscsi-scst/kernel/ trunk/iscsi-scst/kernel/patches/ trunk/iscsi-scst/usr/ trunk/mpt/ trunk/mpt/in-tree/ trunk/qla2x00t/ trunk/qla2x00t/qla2x00-target/ trunk/qla_isp/ trunk/qla_isp/common/ trunk/qla_isp/doc/ trunk/qla_isp/firmware/ trunk/qla_isp/linux/ trunk/qla_isp/linux-2.6/ trunk/qla_isp/linux-2.6/build/ trunk/scst/ trunk/scst/include/ trunk/scst/kernel/ trunk/scst/kernel/in-tree/ trunk/scst/kernel/old_unsupported/ trunk/scst/src/ trunk/scst/src/dev_handlers/ trunk/scstadmin/ trunk/scstadmin/SCST/ trunk/scstadmin/examples/ trunk/scstadmin/init.d/ trunk/scstadmin/scst_db/ trunk/srpt/ trunk/srpt/patches/ trunk/srpt/src/ trunk/usr/ trunk/usr/fileio/ trunk/www/ Property changes on: trunk ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/doc/manpages ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/etc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/etc/initd ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/include ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/kernel ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/kernel/patches ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/iscsi-scst/usr ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/mpt ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/mpt/in-tree ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla2x00t ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla2x00t/qla2x00-target ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/common ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/firmware ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/linux ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/linux-2.6 ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/qla_isp/linux-2.6/build ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/include ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/kernel ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/kernel/in-tree ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/kernel/old_unsupported ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/src ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scst/src/dev_handlers ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scstadmin ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scstadmin/SCST ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scstadmin/examples ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scstadmin/init.d ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/scstadmin/scst_db ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/srpt ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/srpt/patches ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/srpt/src ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/usr ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/usr/fileio ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt Property changes on: trunk/www ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-04-21 16:35:00
|
Revision: 347 http://scst.svn.sourceforge.net/scst/?rev=347&view=rev Author: vlnb Date: 2008-04-21 09:34:55 -0700 (Mon, 21 Apr 2008) Log Message: ----------- Fixes compilation brokenness on kernels below 2.6.24 Modified Paths: -------------- trunk/iscsi-scst/kernel/digest.c trunk/scst/include/scst.h Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2008-04-21 15:04:10 UTC (rev 346) +++ trunk/iscsi-scst/kernel/digest.c 2008-04-21 16:34:55 UTC (rev 347) @@ -16,7 +16,7 @@ */ #include <asm/types.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include "iscsi.h" #include "digest.h" Modified: trunk/scst/include/scst.h =================================================================== --- trunk/scst/include/scst.h 2008-04-21 15:04:10 UTC (rev 346) +++ trunk/scst/include/scst.h 2008-04-21 16:34:55 UTC (rev 347) @@ -2353,12 +2353,6 @@ sg->length = len; } -static inline void sg_set_buf(struct scatterlist *sg, const void *buf, - unsigned int buflen) -{ - sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); -} - #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ static inline void sg_clear(struct scatterlist *sg) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-04-22 10:31:00
|
Revision: 350 http://scst.svn.sourceforge.net/scst/?rev=350&view=rev Author: vlnb Date: 2008-04-22 03:30:53 -0700 (Tue, 22 Apr 2008) Log Message: ----------- The bunch of pending changes. Sorry, it's quite big. - "RECEIVE DIAGNOSTIC RESULTS" command handling fixed - Obtaining device queue parameters in scst_obtain_device_parameters() changed to handle NOT READY sense - Fixed possible dev_cmd_count underflow - Minor iSCSI-SCST connection closing cleanups and fixes - Semantic of other *_atomic flags changed a bit. Now they are intended only to allow SCST to optimize execution context. The corresponing functions now can *always* be called on atomic context and, if necessary, should manually determine that using scst_cmd_atomic() function and restart using corresponding *_NEED_THREAD_* return value. - scst_cmd_get_tgt_resp_flags() and SCST_TSC_FLAG_STATUS flag made obsolete and replaced by scst_cmd_get_is_send_status(). All in-tree drivers updated accordingly - Cleanup: preprocessing_done_atomic removed, now preprocessing_done() callback always called on thread context - 64-bit cleanups - Documented that iscsi-scst-adm is currently broken and explained why - In user space Makefile's added possibility to specify external linker flags - Minor performance optimizations - Other minor cleanups Modified Paths: -------------- trunk/iscsi-scst/README trunk/iscsi-scst/ToDo trunk/iscsi-scst/include/iscsi_u.h trunk/iscsi-scst/kernel/config.c trunk/iscsi-scst/kernel/conn.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/nthread.c trunk/iscsi-scst/kernel/session.c trunk/iscsi-scst/usr/Makefile trunk/mpt/mpt_scst.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla_isp/linux/isp_scst.c trunk/scst/README trunk/scst/include/scst.h trunk/scst/src/dev_handlers/scst_changer.c trunk/scst/src/dev_handlers/scst_processor.c trunk/scst/src/dev_handlers/scst_raid.c trunk/scst/src/dev_handlers/scst_tape.c trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_cdbprobe.h trunk/scst/src/scst_lib.c trunk/scst/src/scst_main.c trunk/scst/src/scst_mem.c trunk/scst/src/scst_mem.h trunk/scst/src/scst_targ.c trunk/usr/fileio/Makefile trunk/usr/fileio/common.c trunk/usr/fileio/fileio.c Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/README 2008-04-22 10:30:53 UTC (rev 350) @@ -118,7 +118,6 @@ CAUTION: Working of target and initiator on the same host isn't ======== supported. See SCST README file for details. - Compilation options ------------------- @@ -136,6 +135,19 @@ - DEBUG_DIGEST_FAILURES - simulates digest failures in random places. +Known issues +------------ + +Currently some iscsi-scst-adm functionality is broken. But, from one +side, at the moment I don't have time to look at it and and, from other +side, in contrast to IET, in iSCSI-SCST this utility doesn't worth much, +since all devices management is done using SCST's /proc interface. +What's remained for iscsi-scst-adm is managing iSCSI targets and their +parameters, but in any case changing of any negotiable iSCSI parameter +needs renegotiation, i.e. the corresponding session restart, i.e. +iSCSI-SCST restart. But, if you decide to fix iscsi-scst-adm, I will +appreciate your patches. + Creating version of put_page_callback patch for your kernel ----------------------------------------------------------- Modified: trunk/iscsi-scst/ToDo =================================================================== --- trunk/iscsi-scst/ToDo 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/ToDo 2008-04-22 10:30:53 UTC (rev 350) @@ -21,6 +21,8 @@ for adding support for ranges in the negotiation keys, so it needs to be fixed as well. + - Fix iscsi-scst-adm. + - Fix SNACK command handling. Currently it violates iSCSI RFC. - Consider better integration with TCP internals on receive path to Modified: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/include/iscsi_u.h 2008-04-22 10:30:53 UTC (rev 350) @@ -30,7 +30,7 @@ #define SCSI_ID_LEN 24 #ifndef aligned_u64 -#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#define aligned_u64 uint64_t __attribute__((aligned(8))) #endif struct target_info { Modified: trunk/iscsi-scst/kernel/config.c =================================================================== --- trunk/iscsi-scst/kernel/config.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/kernel/config.c 2008-04-22 10:30:53 UTC (rev 350) @@ -50,8 +50,8 @@ return res; } -static int iscsi_proc_log_entry_write(struct file *file, const char __user *buf, - size_t length, loff_t *off) +static ssize_t iscsi_proc_log_entry_write(struct file *file, + const char __user *buf, size_t length, loff_t *off) { int res = 0; @@ -475,10 +475,10 @@ { if (trace_flag & TRACE_D_IOV) { int i; - printk("%p, %d\n", msg->msg_iov, msg->msg_iovlen); + printk("%p, %zd\n", msg->msg_iov, msg->msg_iovlen); for (i = 0; i < min_t(size_t, msg->msg_iovlen, ISCSI_CONN_IOV_MAX); i++) { - printk("%d: %p,%d\n", i, msg->msg_iov[i].iov_base, + printk("%d: %p,%zd\n", i, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); } } @@ -520,7 +520,7 @@ int i; buf = (void *)&pdu->bhs; - printk("BHS: (%p,%d)\n", buf, sizeof(pdu->bhs)); + printk("BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs)); for (i = 0; i < sizeof(pdu->bhs); i++) iscsi_dump_char(*buf++); iscsi_dump_char(-1); Modified: trunk/iscsi-scst/kernel/conn.c =================================================================== --- trunk/iscsi-scst/kernel/conn.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/kernel/conn.c 2008-04-22 10:30:53 UTC (rev 350) @@ -281,7 +281,7 @@ mm_segment_t oldfs; struct iscsi_session *session = conn->session; - TRACE_DBG("%llu", (unsigned long long) session->sid); + TRACE_DBG("%llu", session->sid); conn->sock = SOCKET_I(conn->file->f_dentry->d_inode); @@ -324,8 +324,7 @@ int conn_free(struct iscsi_conn *conn) { TRACE_MGMT_DBG("Freeing conn %p (sess=%p, %#Lx %u)", conn, - conn->session, (unsigned long long)conn->session->sid, - conn->cid); + conn->session, conn->session->sid, conn->cid); del_timer_sync(&conn->rsp_timer); @@ -360,7 +359,7 @@ } TRACE_MGMT_DBG("Creating connection %p for sid %#Lx, cid %u", conn, - (unsigned long long)session->sid, info->cid); + session->sid, info->cid); /* Changing it, change ISCSI_CONN_IOV_MAX as well !! */ conn->read_iov = (struct iovec *)get_zeroed_page(GFP_KERNEL); Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-04-22 10:30:53 UTC (rev 350) @@ -1036,7 +1036,7 @@ break; } conn->read_iov[i].iov_len = PAGE_SIZE - offset; - TRACE_DBG("idx=%d, offset=%u, size=%d, iov_len=%d, addr=%p", + TRACE_DBG("idx=%d, offset=%u, size=%d, iov_len=%zd, addr=%p", idx, offset, size, conn->read_iov[i].iov_len, addr); size -= conn->read_iov[i].iov_len; offset = 0; @@ -1050,7 +1050,7 @@ } idx++; } - TRACE_DBG("msg_iov=%p, msg_iovlen=%d", + TRACE_DBG("msg_iov=%p, msg_iovlen=%zd", conn->read_msg.msg_iov, conn->read_msg.msg_iovlen); out: @@ -1244,7 +1244,7 @@ } sBUG_ON(size == 0); conn->read_msg.msg_iovlen = i; - TRACE_DBG("msg_iov=%p, msg_iovlen=%d", conn->read_msg.msg_iov, + TRACE_DBG("msg_iov=%p, msg_iovlen=%zd", conn->read_msg.msg_iov, conn->read_msg.msg_iovlen); } out: @@ -2493,7 +2493,7 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd) { - int resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); + int is_send_status = scst_cmd_get_is_send_status(scst_cmd); struct iscsi_cmnd *req = (struct iscsi_cmnd*) scst_cmd_get_tgt_priv(scst_cmd); struct iscsi_conn *conn = req->conn; @@ -2507,6 +2507,9 @@ bool single_only = 0; #endif + if (scst_cmd_atomic(scst_cmd)) + return SCST_TGT_RES_NEED_THREAD_CTX; + scst_cmd_set_tgt_priv(scst_cmd, NULL); req->tmfabort |= scst_cmd_aborted(scst_cmd) ? 1 : 0; @@ -2541,34 +2544,31 @@ req->sg = scst_cmd_get_sg(scst_cmd); req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd); - TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p, " - "req->sg_cnt %d", req, resp_flags, req->bufflen, req->sg, + TRACE_DBG("req %p, is_send_status=%x, req->bufflen=%d, req->sg=%p, " + "req->sg_cnt %d", req, is_send_status, req->bufflen, req->sg, req->sg_cnt); - if (unlikely((req->bufflen != 0) && - !(resp_flags & SCST_TSC_FLAG_STATUS))) { + if (unlikely((req->bufflen != 0) && !is_send_status)) { PRINT_CRIT_ERROR("%s", "Sending DATA without STATUS is unsupported"); scst_set_cmd_error(scst_cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); - resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); sBUG(); } if (req->bufflen != 0) { /* - * Check above makes sure that SCST_TSC_FLAG_STATUS is set, + * Check above makes sure that is_send_status is set, * so status is valid here, but in future that could change. * ToDo */ if (status != SAM_STAT_CHECK_CONDITION) { - send_data_rsp(req, status, - resp_flags & SCST_TSC_FLAG_STATUS); + send_data_rsp(req, status, is_send_status); } else { struct iscsi_cmnd *rsp; struct iscsi_scsi_rsp_hdr *rsp_hdr; int resid; send_data_rsp(req, 0, 0); - if (resp_flags & SCST_TSC_FLAG_STATUS) { + if (is_send_status) { rsp = create_status_rsp(req, status, sense, sense_len); rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; @@ -2586,7 +2586,7 @@ ISCSI_INIT_WRITE_REMOVE_HASH); } } - } else if (resp_flags & SCST_TSC_FLAG_STATUS) { + } else if (is_send_status) { struct iscsi_cmnd *rsp; struct iscsi_scsi_rsp_hdr *rsp_hdr; u32 resid; @@ -2781,7 +2781,6 @@ .threads_num = 0, .no_clustering = 1, .xmit_response_atomic = 0, - .preprocessing_done_atomic = 1, .detect = iscsi_target_detect, .release = iscsi_target_release, .xmit_response = iscsi_xmit_response, Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/kernel/nthread.c 2008-04-22 10:30:53 UTC (rev 350) @@ -183,10 +183,15 @@ { struct iscsi_session *session = conn->session; struct iscsi_target *target = conn->target; - unsigned long start_waiting = jiffies; - unsigned long shut_start_waiting = start_waiting; + typeof(jiffies) start_waiting = jiffies; + typeof(jiffies) shut_start_waiting = start_waiting; bool pending_reported = 0, wait_expired = 0, shut_expired = 0; +#define CONN_PENDING_TIMEOUT ((typeof(jiffies))10*HZ) +#define CONN_WAIT_TIMEOUT ((typeof(jiffies))10*HZ) +#define CONN_REG_SHUT_TIMEOUT ((typeof(jiffies))125*HZ) +#define CONN_DEL_SHUT_TIMEOUT ((typeof(jiffies))10*HZ) + TRACE_ENTRY(); TRACE_CONN_CLOSE("Closing connection %p (conn_ref_cnt=%d)", conn, @@ -291,7 +296,7 @@ } while(req_freed); spin_unlock(&session->sn_lock); - if (time_after(jiffies, start_waiting + 10*HZ)) { + if (time_after(jiffies, start_waiting + CONN_PENDING_TIMEOUT)) { if (!pending_reported) { TRACE_CONN_CLOSE("%s", "Pending wait time expired"); pending_reported = 1; @@ -331,7 +336,9 @@ iscsi_make_conn_wr_active(conn); - if (time_after(jiffies, start_waiting + 10*HZ) && !wait_expired) { + /* That's for active close only, actually */ + if (time_after(jiffies, start_waiting + CONN_WAIT_TIMEOUT) && + !wait_expired) { TRACE_CONN_CLOSE("Wait time expired (conn %p, " "sk_state %d)", conn, conn->sock->sk->sk_state); conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN); @@ -339,17 +346,20 @@ shut_start_waiting = jiffies; } - if (conn->deleting) { - if (wait_expired && !shut_expired && - time_after(jiffies, shut_start_waiting + 10*HZ)) { - TRACE_CONN_CLOSE("Wait time after shutdown expired " - "(conn %p, sk_state %d)", conn, - conn->sock->sk->sk_state); - conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); - shut_expired = 1; - } + if (wait_expired && !shut_expired && + time_after(jiffies, shut_start_waiting + + conn->deleting ? CONN_DEL_SHUT_TIMEOUT : + CONN_REG_SHUT_TIMEOUT)) { + TRACE_CONN_CLOSE("Wait time after shutdown expired " + "(conn %p, sk_state %d)", conn, + conn->sock->sk->sk_state); + conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0); + shut_expired = 1; + } + + if (conn->deleting) msleep(200); - } else + else msleep(1000); TRACE_CONN_CLOSE_DBG("conn %p, conn_ref_cnt %d left, wr_state %d, " @@ -362,7 +372,7 @@ #endif #if 0 - if (time_after(jiffies, start_waiting+10*HZ)) + if (time_after(jiffies, start_waiting + 10*HZ)) trace_flag |= TRACE_CONN_OC_DBG; #endif @@ -924,7 +934,7 @@ struct scatterlist *sg; struct iovec *iop; int saved_size, size, sendsize; - int offset, idx; + int offset, idx, sg_offset; int flags, res, count; bool do_put = false; @@ -947,7 +957,6 @@ spin_unlock_bh(&conn->write_list_lock); } -#if 0 /* temp. ToDo */ if (!timer_pending(&conn->rsp_timer)) { sBUG_ON(!ref_cmd->on_written_list); spin_lock_bh(&conn->write_list_lock); @@ -959,7 +968,6 @@ } spin_unlock_bh(&conn->write_list_lock); } -#endif file = conn->file; saved_size = size = conn->write_size; @@ -976,8 +984,7 @@ set_fs(KERNEL_DS); res = vfs_writev(file, (struct iovec __user *)iop, count, &off); set_fs(oldfs); - TRACE_WRITE("%#Lx:%u: %d(%ld)", - (unsigned long long)conn->session->sid, conn->cid, + TRACE_WRITE("%#Lx:%u: %d(%ld)", conn->session->sid, conn->cid, res, (long)iop->iov_len); if (unlikely(res <= 0)) { if (res == -EAGAIN) { @@ -1020,7 +1027,8 @@ __iscsi_get_page_callback(ref_cmd); do_put = true; - offset = conn->write_offset + sg[0].offset; + sg_offset = sg[0].offset; + offset = conn->write_offset + sg_offset; idx = offset >> PAGE_SHIFT; offset &= ~PAGE_MASK; @@ -1074,7 +1082,7 @@ TRACE_WRITE("Final %s %#Lx:%u: %d(%lu,%u,%u, cmd %p, page %p)", (sendpage != sock_no_sendpage) ? "sendpage" : "sock_no_sendpage", - (unsigned long long)conn->session->sid, conn->cid, + conn->session->sid, conn->cid, res, sg_page(&sg[idx])->index, offset, size, write_cmnd, sg_page(&sg[idx])); if (unlikely(res <= 0)) { @@ -1124,7 +1132,7 @@ } out_off: - conn->write_offset = (idx << PAGE_SHIFT) + offset - sg[0].offset; + conn->write_offset = (idx << PAGE_SHIFT) + offset - sg_offset; out_iov: conn->write_size = size; @@ -1153,8 +1161,7 @@ #endif { PRINT_ERROR("error %d at sid:cid %#Lx:%u, cmnd %p", res, - (unsigned long long)conn->session->sid, conn->cid, - conn->write_cmnd); + conn->session->sid, conn->cid, conn->write_cmnd); } if (ref_cmd->scst_cmd != NULL) scst_set_delivery_status(ref_cmd->scst_cmd, Modified: trunk/iscsi-scst/kernel/session.c =================================================================== --- trunk/iscsi-scst/kernel/session.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/kernel/session.c 2008-04-22 10:30:53 UTC (rev 350) @@ -94,7 +94,7 @@ list_add(&session->session_list_entry, &target->session_list); TRACE_MGMT_DBG("Session %p created: target %p, tid %u, sid %#Lx", - session, target, target->tid, (unsigned long long) info->sid); + session, target, target->tid, info->sid); return 0; err: @@ -129,8 +129,7 @@ { int i; - TRACE_MGMT_DBG("Freeing session %p:%#Lx", session, - (unsigned long long)session->sid); + TRACE_MGMT_DBG("Freeing session %p:%#Lx", session, session->sid); sBUG_ON(!list_empty(&session->conn_list)); if (unlikely(atomic_read(&session->active_cmds) != 0)) { @@ -163,8 +162,7 @@ return -ENOENT; if (!list_empty(&session->conn_list)) { - PRINT_ERROR("%llu still have connections", - (unsigned long long)session->sid); + PRINT_ERROR("%llu still have connections", session->sid); return -EBUSY; } @@ -178,8 +176,8 @@ list_for_each_entry(session, &target->session_list, session_list_entry) { seq_printf(seq, "\tsid:%llu initiator:%s shutting down %d\n", - (unsigned long long)session->sid, - session->initiator_name, session->shutting_down); + session->sid, session->initiator_name, + session->shutting_down); conn_info_show(seq, session); } } Modified: trunk/iscsi-scst/usr/Makefile =================================================================== --- trunk/iscsi-scst/usr/Makefile 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/iscsi-scst/usr/Makefile 2008-04-22 10:30:53 UTC (rev 350) @@ -28,10 +28,10 @@ all: $(PROGRAMS) iscsi-scstd: .depend_d $(OBJS_D) - $(CC) $(OBJS_D) $(LIBS) -o $@ + $(CC) $(OBJS_D) $(LIBS) $(LOCAL_LD_FLAGS) -o $@ iscsi-scst-adm: .depend_adm $(OBJS_ADM) - $(CC) $(OBJS_ADM) $(LIBS) -o $@ + $(CC) $(OBJS_ADM) $(LIBS) $(LOCAL_LD_FLAGS) -o $@ ifeq (.depend_d,$(wildcard .depend_d)) -include .depend_d Modified: trunk/mpt/mpt_scst.c =================================================================== --- trunk/mpt/mpt_scst.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/mpt/mpt_scst.c 2008-04-22 10:30:53 UTC (rev 350) @@ -1588,11 +1588,17 @@ int res = SCST_TGT_RES_SUCCESS; struct mpt_sess *sess; struct mpt_prm prm = { 0 }; - int resp_flags; + int is_send_status; //uint16_t full_req_cnt; //int data_sense_flag = 0; TRACE_ENTRY(); + +#ifdef DEBUG_WORK_IN_THREAD + if (scst_cmd_atomic(scst_cmd)) + return SCST_TGT_RES_NEED_THREAD_CTX; +#endif + prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct mpt_sess *) scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); @@ -1607,16 +1613,16 @@ prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd); prm.tgt = sess->tgt; prm.seg_cnt = 0; - resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); + is_send_status = scst_cmd_get_is_send_status(scst_cmd); - TRACE_DBG("rq_result=%x, resp_flags=%x, %x, %d", prm.rq_result, - resp_flags, prm.bufflen, prm.sense_buffer_len); + TRACE_DBG("rq_result=%x, is_send_status=%x, %x, %d", prm.rq_result, + is_send_status, prm.bufflen, prm.sense_buffer_len); if ((prm.rq_result != 0) && (prm.sense_buffer != NULL)) TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len); - if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) { + if (!is_send_status) { /* ToDo, after it's done in SCST */ - PRINT_ERROR(MYNAM ": SCST_TSC_FLAG_STATUS not set: " + PRINT_ERROR(MYNAM ": is_send_status not set: " "feature not implemented %p", scst_cmd); res = SCST_TGT_RES_FATAL_ERROR; goto out_tgt_free; @@ -1740,6 +1746,12 @@ struct mpt_prm prm = { 0 }; TRACE_ENTRY(); + +#ifdef DEBUG_WORK_IN_THREAD + if (scst_cmd_atomic(scst_cmd)) + return SCST_TGT_RES_NEED_THREAD_CTX; +#endif + prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct mpt_sess *) scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-04-22 10:30:53 UTC (rev 350) @@ -672,7 +672,7 @@ { int res = SCST_TGT_RES_SUCCESS; struct q2t_sess *sess; - int resp_flags; + int is_send_status; unsigned long flags = 0; struct q2t_prm prm = { 0 }; int data_sense_flag = 0; @@ -681,6 +681,11 @@ TRACE_ENTRY(); TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd)); +#ifdef DEBUG_WORK_IN_THREAD + if (scst_cmd_atomic(scst_cmd)) + return SCST_TGT_RES_NEED_THREAD_CTX; +#endif + prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct q2t_sess *) scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); @@ -709,15 +714,17 @@ prm.tgt = sess->tgt; prm.seg_cnt = 0; prm.req_cnt = 1; - resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd); + is_send_status = scst_cmd_get_is_send_status(scst_cmd); - TRACE_DBG("rq_result=%x, resp_flags=%x", prm.rq_result, resp_flags); + TRACE_DBG("rq_result=%x, is_send_status=%x", prm.rq_result, + is_send_status); + if (prm.rq_result != 0) TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len); - if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) { + if (!is_send_status) { /* ToDo, after it's done in SCST */ - PRINT_ERROR("qla2x00tgt(%ld): SCST_TSC_FLAG_STATUS not set: " + PRINT_ERROR("qla2x00tgt(%ld): is_send_status not set: " "feature not implemented", prm.tgt->ha->instance); res = SCST_TGT_RES_FATAL_ERROR; goto out; @@ -827,6 +834,11 @@ TRACE_ENTRY(); TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd)); +#ifdef DEBUG_WORK_IN_THREAD + if (scst_cmd_atomic(scst_cmd)) + return SCST_TGT_RES_NEED_THREAD_CTX; +#endif + prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd); sess = (struct q2t_sess *) scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd)); @@ -2134,8 +2146,8 @@ return res; } -static int q2t_proc_log_entry_write(struct file *file, const char __user *buf, - size_t length, loff_t *off) +static ssize_t q2t_proc_log_entry_write(struct file *file, + const char __user *buf, size_t length, loff_t *off) { int res = 0; @@ -2148,7 +2160,6 @@ return res; } - static struct scst_proc_data q2t_log_proc_data = { SCST_DEF_RW_SEQ_OP(q2t_proc_log_entry_write) .show = q2t_log_info_show, Modified: trunk/qla_isp/linux/isp_scst.c =================================================================== --- trunk/qla_isp/linux/isp_scst.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/qla_isp/linux/isp_scst.c 2008-04-22 10:30:53 UTC (rev 350) @@ -1089,7 +1089,7 @@ xact->td_hflags &= ~TDFH_DATA_MASK; } - if (scst_cmd_get_tgt_resp_flags(scst_cmd) & SCST_TSC_FLAG_STATUS) { + if (scst_cmd_get_is_send_status(scst_cmd)) { xact->td_hflags |= TDFH_STSVALID; tmd->cd_scsi_status = scst_cmd_get_status(scst_cmd); Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/README 2008-04-22 10:30:53 UTC (rev 350) @@ -106,16 +106,6 @@ request to the target -> target needs memory -> problem is possible. -IMPORTANT: Experience shows that if people work with out of SCST tree target -========= drivers, like target driver for Infiniband or in case if they - downloaded and use the released versions of SCST and target - drivers, they are too often (actually, almost always) after - upgrading SCST core forget to rebuild their target drivers, - which then immediately after load crash in the hard to trace - manner. So, after you reinstalled SCST core don't forget to - rebuild and reinstall all your target drivers, custom dev - handlers and necessary user space applications. - IMPORTANT: In the current version simultaneous access to local SCSI devices ========= via standard high-level SCSI drivers (sd, st, sg, etc.) and SCST's target drivers is unsupported. Especially it is @@ -396,6 +386,9 @@ - "clear" to /proc/scsi_tgt/groups/GROUP/names clears the list of names for group "GROUP" +There must be LUN 0 in each security group, i.e. LUs numeration must not +start from, e.g., 1. + Examples: - "echo "add 1:0:1:0 0" >/proc/scsi_tgt/groups/Default/devices" will Modified: trunk/scst/include/scst.h =================================================================== --- trunk/scst/include/scst.h 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/include/scst.h 2008-04-22 10:30:53 UTC (rev 350) @@ -293,16 +293,12 @@ *************************************************************/ #define SCST_DEFAULT_TIMEOUT (30*HZ) -/************************************************************* - ** Flags of cmd->tgt_resp_flags - *************************************************************/ - /* * Set if cmd is finished and there is status/sense to be sent. * The status should be not sent (i.e. the flag not set) if the * possibility to perform a command in "chunks" (i.e. with multiple - * xmit_response()/rdy_to_xfer()) is used (not implemented and, - * probably, will never be). + * xmit_response()/rdy_to_xfer()) is used (not implemented yet). + * Obsolete, use scst_cmd_get_is_send_status() instead. */ #define SCST_TSC_FLAG_STATUS 0x2 @@ -472,7 +468,6 @@ */ unsigned xmit_response_atomic:1; unsigned rdy_to_xfer_atomic:1; - unsigned preprocessing_done_atomic:1; /* True, if the template doesn't need the entry in /proc */ unsigned no_proc_entry:1; @@ -752,7 +747,7 @@ /* * Called to notify dev handler about the result of cmd execution - * and perform some post processing. Cmd's fields tgt_resp_flags and + * and perform some post processing. Cmd's fields is_send_status and * resp_data_len should be set by this function, but SCST offers good * defaults. * Returns the command's next state or SCST_CMD_STATE_DEFAULT, @@ -1022,6 +1017,9 @@ /* Set if cmd is being processed in atomic context */ unsigned int atomic:1; + /* Set if this command contains status */ + unsigned int is_send_status:1; + /* * Set if the cmd is being processed in the processable context. See * comment for SCST_CONTEXT_PROCESSABLE for what it means. @@ -1208,12 +1206,6 @@ /* scst_get_sg_buf_[first,next]() support */ int get_sg_buf_entry_num; - /* - * The following two fields should be corrected by the dev_done(), - * if necessary - */ - int tgt_resp_flags; /* response flags (SCST_TSC_FLAG_* constants) */ - /* * Response data length in data buffer. This field must not be set * directly, use scst_set_resp_data_len() for that @@ -1340,6 +1332,9 @@ /* How many cmds alive on this dev */ atomic_t dev_cmd_count; + /* How many write cmds alive on this dev. Temporary, ToDo */ + atomic_t write_cmd_count; + unsigned short type; /* SCSI type of the device */ /************************************************************* @@ -2029,12 +2024,21 @@ return cmd->resp_data_len; } -/* Returns cmd's response flags (SCST_TSC_FLAG_* constants) */ -static inline int scst_cmd_get_tgt_resp_flags(struct scst_cmd *cmd) +/* + * Returns cmd's response flags (SCST_TSC_FLAG_* constants). Obsolete, use + * scst_cmd_get_is_send_status() instead. + */ +static inline __deprecated int scst_cmd_get_tgt_resp_flags(struct scst_cmd *cmd) { - return cmd->tgt_resp_flags; + return cmd->is_send_status ? SCST_TSC_FLAG_STATUS : 0; } +/* Returns if status should be sent for cmd */ +static inline int scst_cmd_get_is_send_status(struct scst_cmd *cmd) +{ + return cmd->is_send_status; +} + /* * Returns pointer to cmd's SG data buffer. * Modified: trunk/scst/src/dev_handlers/scst_changer.c =================================================================== --- trunk/scst/src/dev_handlers/scst_changer.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_changer.c 2008-04-22 10:30:53 UTC (rev 350) @@ -177,7 +177,7 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len + * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len * based on cmd->status and cmd->data_direction, therefore change * them only if necessary */ Modified: trunk/scst/src/dev_handlers/scst_processor.c =================================================================== --- trunk/scst/src/dev_handlers/scst_processor.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_processor.c 2008-04-22 10:30:53 UTC (rev 350) @@ -176,7 +176,7 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len + * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len * based on cmd->status and cmd->data_direction, therefore change * them only if necessary */ Modified: trunk/scst/src/dev_handlers/scst_raid.c =================================================================== --- trunk/scst/src/dev_handlers/scst_raid.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_raid.c 2008-04-22 10:30:53 UTC (rev 350) @@ -176,7 +176,7 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len + * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len * based on cmd->status and cmd->data_direction, therefore change * them only if necessary */ Modified: trunk/scst/src/dev_handlers/scst_tape.c =================================================================== --- trunk/scst/src/dev_handlers/scst_tape.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_tape.c 2008-04-22 10:30:53 UTC (rev 350) @@ -384,8 +384,8 @@ } } - TRACE_DBG("cmd->tgt_resp_flags=%x, cmd->resp_data_len=%d, " - "res=%d", cmd->tgt_resp_flags, cmd->resp_data_len, res); + TRACE_DBG("cmd->is_send_status=%x, cmd->resp_data_len=%d, " + "res=%d", cmd->is_send_status, cmd->resp_data_len, res); TRACE_EXIT_RES(res); return res; Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-04-22 10:30:53 UTC (rev 350) @@ -278,7 +278,7 @@ return NULL; } -static void cmnd_insert_hash(struct scst_user_cmd *ucmd) +static void cmd_insert_hash(struct scst_user_cmd *ucmd) { struct list_head *head; struct scst_user_dev *dev = ucmd->dev; @@ -298,7 +298,7 @@ return; } -static inline void cmnd_remove_hash(struct scst_user_cmd *ucmd) +static inline void cmd_remove_hash(struct scst_user_cmd *ucmd) { unsigned long flags; spin_lock_irqsave(&ucmd->dev->cmd_lists.cmd_list_lock, flags); @@ -315,7 +315,7 @@ TRACE_MEM("Freeing ucmd %p", ucmd); - cmnd_remove_hash(ucmd); + cmd_remove_hash(ucmd); EXTRACHECKS_BUG_ON(ucmd->cmd != NULL); kmem_cache_free(user_cmd_cachep, ucmd); @@ -630,7 +630,7 @@ ucmd->dev = dev; atomic_set(&ucmd->ucmd_ref, 1); - cmnd_insert_hash(ucmd); + cmd_insert_hash(ucmd); TRACE_MEM("ucmd %p allocated", ucmd); @@ -784,9 +784,22 @@ static int dev_user_exec(struct scst_cmd *cmd) { struct scst_user_cmd *ucmd = (struct scst_user_cmd*)cmd->dh_priv; + int res = SCST_EXEC_COMPLETED; TRACE_ENTRY(); +#if 0 /* We set exec_atomic in 0 to let SCST core know that we need a thread + * context to complete the necessary actions, but all we are going to + * do in this function is, in fact, atomic, so let's skip this check. + */ + if (scst_cmd_atomic(cmd)) { + TRACE_DBG("%s", "User exec() can not be called in atomic " + "context, rescheduling to the thread"); + res = SCST_EXEC_NEED_THREAD; + goto out; + } +#endif + TRACE_DBG("Preparing EXEC for user space (ucmd=%p, h=%d, " "bufflen %d, data_len %d, ubuff %lx)", ucmd, ucmd->h, cmd->bufflen, cmd->data_len, ucmd->ubuff); @@ -818,8 +831,8 @@ dev_user_add_to_ready(ucmd); - TRACE_EXIT(); - return SCST_EXEC_COMPLETED; + TRACE_EXIT_RES(res); + return res; } static void dev_user_free_sgv(struct scst_user_cmd *ucmd) @@ -2920,6 +2933,8 @@ } file->private_data = NULL; + TRACE(TRACE_MGMT, "Releasing dev %s", dev->name); + spin_lock(&dev_list_lock); list_del(&dev->dev_list_entry); spin_unlock(&dev_list_lock); @@ -2928,8 +2943,6 @@ down_write(&dev->dev_rwsem); - TRACE_DBG("Releasing dev %p", dev); - spin_lock(&cleanup_lock); list_add_tail(&dev->cleanup_list_entry, &cleanup_list); spin_unlock(&cleanup_lock); Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-04-22 10:30:53 UTC (rev 350) @@ -666,7 +666,7 @@ static int vdisk_do_job(struct scst_cmd *cmd) { - int rc; + int rc, res; uint64_t lba_start = 0; loff_t data_len = 0; uint8_t *cdb = cmd->cdb; @@ -681,6 +681,13 @@ TRACE_ENTRY(); + if (scst_cmd_atomic(cmd)) { + TRACE_DBG("%s", "vdisk exec() can not be done in atomic " + "context, requesting thread context"); + res = SCST_EXEC_NEED_THREAD; + goto out; + } + switch(cmd->queue_type) { case SCST_CMD_QUEUE_ORDERED: TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd); @@ -795,7 +802,7 @@ case READ_16: if (virt_dev->blockio) { blockio_exec_rw(cmd, thr, lba_start, 0); - goto out; + goto out_thr; } else vdisk_exec_read(cmd, thr, loff); break; @@ -822,7 +829,7 @@ } if (virt_dev->blockio) { blockio_exec_rw(cmd, thr, lba_start, 1); - goto out; + goto out_thr; } else vdisk_exec_write(cmd, thr, loff); /* O_SYNC flag is used for WT devices */ @@ -882,7 +889,7 @@ vdisk_fsync(thr, loff, data_len, NULL); /* ToDo: vdisk_fsync() error processing */ scst_cmd_put(cmd); - goto out; + goto out_thr; } else { vdisk_fsync(thr, loff, data_len, cmd); break; @@ -949,12 +956,15 @@ out_done: cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT); -out: +out_thr: if (likely(thr != NULL)) scst_thr_data_put(&thr->hdr); - TRACE_EXIT(); - return SCST_EXEC_COMPLETED; + res = SCST_EXEC_COMPLETED; + +out: + TRACE_EXIT_RES(res); + return res; } static int vdisk_get_block_shift(struct scst_cmd *cmd) Modified: trunk/scst/src/scst_cdbprobe.h =================================================================== --- trunk/scst/src/scst_cdbprobe.h 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_cdbprobe.h 2008-04-22 10:30:53 UTC (rev 350) @@ -197,7 +197,7 @@ {0x1B, "O OO O O ", "STOP START UNIT", SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none}, {0x1C, "OOOOOOOOOOOOOOOO", "RECEIVE DIAGNOSTIC RESULTS", - SCST_DATA_READ, FLAG_NONE, 4, get_trans_len_1}, + SCST_DATA_READ, FLAG_NONE, 3, get_trans_len_2}, {0x1D, "MMMMMMMMMMMMMMMM", "SEND DIAGNOSTIC", SCST_DATA_WRITE, FLAG_NONE, 4, get_trans_len_1}, {0x1E, "OOOOOOOOOOOOOOOO", "PREVENT ALLOW MEDIUM REMOVAL", Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_lib.c 2008-04-22 10:30:53 UTC (rev 350) @@ -94,7 +94,7 @@ cmd->host_status = DID_OK; cmd->data_direction = SCST_DATA_NONE; - cmd->tgt_resp_flags = SCST_TSC_FLAG_STATUS; + cmd->is_send_status = 1; cmd->resp_data_len = 0; cmd->completed = 1; @@ -233,6 +233,7 @@ dev->handler = &scst_null_devtype; dev->p_cmd_lists = &scst_main_cmd_lists; atomic_set(&dev->dev_cmd_count, 0); + atomic_set(&dev->write_cmd_count, 0); spin_lock_init(&dev->dev_lock); atomic_set(&dev->on_dev_count, 0); INIT_LIST_HEAD(&dev->blocked_cmd_list); @@ -474,16 +475,18 @@ atomic_set(&tgt_dev->sn_slots[i], 0); if (dev->handler->parse_atomic && - sess->tgt->tgtt->preprocessing_done_atomic) { - if (sess->tgt->tgtt->rdy_to_xfer_atomic) + (sess->tgt->tgtt->preprocessing_done == NULL)) { + if (sess->tgt->tgtt->rdy_to_xfer_atomic || + (sess->tgt->tgtt->rdy_to_xfer == NULL)) __set_bit(SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC, &tgt_dev->tgt_dev_flags); - if (dev->handler->exec_atomic) + if (dev->handler->exec_atomic || (dev->handler->exec == NULL)) __set_bit(SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC, &tgt_dev->tgt_dev_flags); } - if (dev->handler->exec_atomic) { - if (sess->tgt->tgtt->rdy_to_xfer_atomic) + if (dev->handler->exec_atomic || (dev->handler->exec == NULL)) { + if (sess->tgt->tgtt->rdy_to_xfer_atomic || + (sess->tgt->tgtt->rdy_to_xfer == NULL)) __set_bit(SCST_TGT_DEV_AFTER_RESTART_WR_ATOMIC, &tgt_dev->tgt_dev_flags); __set_bit(SCST_TGT_DEV_AFTER_RESTART_OTH_ATOMIC, @@ -491,7 +494,8 @@ __set_bit(SCST_TGT_DEV_AFTER_RX_DATA_ATOMIC, &tgt_dev->tgt_dev_flags); } - if (dev->handler->dev_done_atomic && + if ((dev->handler->dev_done_atomic || + (dev->handler->dev_done == NULL)) && sess->tgt->tgtt->xmit_response_atomic) { __set_bit(SCST_TGT_DEV_AFTER_EXEC_ATOMIC, &tgt_dev->tgt_dev_flags); @@ -1301,7 +1305,7 @@ cmd->timeout = SCST_DEFAULT_TIMEOUT; cmd->retries = 0; cmd->data_len = -1; - cmd->tgt_resp_flags = SCST_TSC_FLAG_STATUS; + cmd->is_send_status = 1; cmd->resp_data_len = -1; out: @@ -1677,7 +1681,7 @@ cmd->bufflen = 0; cmd->bufflen |= ((u32)p[0]) << 8; cmd->bufflen |= ((u32)p[1]); - + switch (cmd->cdb[1] & 0x1f) { case 0: case 1: @@ -2177,7 +2181,7 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len + * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len * based on cmd->status and cmd->data_direction, therefore change * them only if necessary */ @@ -2215,8 +2219,8 @@ } } - TRACE_DBG("cmd->tgt_resp_flags=%x, cmd->resp_data_len=%d, " - "res=%d", cmd->tgt_resp_flags, cmd->resp_data_len, res); + TRACE_DBG("cmd->is_send_status=%x, cmd->resp_data_len=%d, " + "res=%d", cmd->is_send_status, cmd->resp_data_len, res); out: TRACE_EXIT_RES(res); @@ -2234,7 +2238,7 @@ TRACE_ENTRY(); /* - * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len + * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len * based on cmd->status and cmd->data_direction, therefore change * them only if necessary */ @@ -2375,18 +2379,27 @@ #else if ( #endif - SCST_SENSE_VALID(sense_buffer) && - (sense_buffer[2] == ILLEGAL_REQUEST)) { - TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d " - "doesn't support control mode page, using " - "defaults: TST %x, QUEUE ALG %x, SWP %x, " - "TAS %x, has_own_order_mgmt %d", - dev->scsi_dev->host->host_no, - dev->scsi_dev->channel, dev->scsi_dev->id, - dev->scsi_dev->lun, dev->tst, dev->queue_alg, - dev->swp, dev->tas, dev->has_own_order_mgmt); - res = 0; - goto out; + SCST_SENSE_VALID(sense_buffer)) { + if (sense_buffer[2] == ILLEGAL_REQUEST) { + TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device " + "%d:%d:%d:%d doesn't support control " + "mode page, using defaults: TST " + "%x, QUEUE ALG %x, SWP %x, TAS %x, " + "has_own_order_mgmt %d", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun, dev->tst, dev->queue_alg, + dev->swp, dev->tas, dev->has_own_order_mgmt); + res = 0; + goto out; + } else if (sense_buffer[2] == NOT_READY) { + TRACE(TRACE_SCSI, "Device %d:%d:%d:%d not ready", + dev->scsi_dev->host->host_no, + dev->scsi_dev->channel, dev->scsi_dev->id, + dev->scsi_dev->lun); + res = 0; + goto out; + } } else { TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Internal MODE SENSE to " "device %d:%d:%d:%d failed: %x", Modified: trunk/scst/src/scst_main.c =================================================================== --- trunk/scst/src/scst_main.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_main.c 2008-04-22 10:30:53 UTC (rev 350) @@ -204,9 +204,6 @@ goto out_err; } - if (vtt->preprocessing_done == NULL) - vtt->preprocessing_done_atomic = 1; - if (mutex_lock_interruptible(&m) != 0) goto out_err; Modified: trunk/scst/src/scst_mem.c =================================================================== --- trunk/scst/src/scst_mem.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_mem.c 2008-04-22 10:30:53 UTC (rev 350) @@ -35,11 +35,10 @@ #include "scst_priv.h" #include "scst_mem.h" -#define PURGE_INTERVAL (15 * HZ) -#define PURGE_TIME_AFTER (15 * HZ) +#define PURGE_INTERVAL (60 * HZ) +#define PURGE_TIME_AFTER PURGE_INTERVAL #define SHRINK_TIME_AFTER (1 * HZ) - static struct scst_sgv_pools_manager sgv_pools_mgr; void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev) @@ -342,8 +341,7 @@ sgv_pools_mgr.mgr.thr.inactive_pages_total -= 1 << order; spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); EXTRACHECKS_BUG_ON(obj->order != order); - - return obj; + goto out; } pool->acc.cached_entries++; @@ -364,20 +362,43 @@ spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); } +out: return obj; } static void sgv_pool_cached_put(struct sgv_pool_obj *sgv) { struct sgv_pool *owner = sgv->owner_pool; + struct list_head *entry; + struct list_head *list = &owner->recycling_lists[sgv->order]; int sched = 0; spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - list_add(&sgv->recycle_entry.recycling_list_entry, - &owner->recycling_lists[sgv->order]); + TRACE_MEM("sgv %p, order %d, sg_count %d", sgv, sgv->order, + sgv->sg_count); + + if (owner->clustered) { + /* Make objects with less entries more preferred */ + __list_for_each(entry, list) { + struct sgv_pool_obj *tmp = list_entry(entry, + struct sgv_pool_obj, + recycle_entry.recycling_list_entry); + TRACE_DBG("tmp %p, order %d, sg_count %d", tmp, + tmp->order, tmp->sg_count); + if (sgv->sg_count <= tmp->sg_count) + break; + } + entry = entry->prev; + } else + entry = list; + + TRACE_DBG("Adding in %p (list %p)", entry, list); + list_add(&sgv->recycle_entry.recycling_list_entry, entry); + list_add_tail(&sgv->recycle_entry.sorted_recycling_list_entry, &sgv_pools_mgr.mgr.sorted_recycling_list); + sgv->recycle_entry.time_stamp = jiffies; sgv_pools_mgr.mgr.thr.inactive_pages_total += 1 << sgv->order; @@ -457,7 +478,7 @@ spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - pages += sgv_pools_mgr.mgr.thr.active_pages_total; + pages += atomic_read(&sgv_pools_mgr.mgr.thr.active_pages_total); pages += sgv_pools_mgr.mgr.thr.inactive_pages_total; if (unlikely((u32)pages > sgv_pools_mgr.mgr.thr.hi_wmk)) { @@ -497,7 +518,7 @@ int pages_to_alloc; struct kmem_cache *cache; int no_cached = flags & SCST_POOL_ALLOC_NO_CACHED; - int no_fail = ((gfp_mask & __GFP_NOFAIL) == __GFP_NOFAIL); + bool no_fail = ((gfp_mask & __GFP_NOFAIL) == __GFP_NOFAIL); TRACE_ENTRY(); @@ -621,9 +642,7 @@ } success: - spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - sgv_pools_mgr.mgr.thr.active_pages_total += 1 << order; - spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); + atomic_add(1 << order, &sgv_pools_mgr.mgr.thr.active_pages_total); if (cache) { int sg; @@ -725,9 +744,7 @@ kfree(sgv); } - spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - sgv_pools_mgr.mgr.thr.active_pages_total -= pages; - spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); + atomic_sub(pages, &sgv_pools_mgr.mgr.thr.active_pages_total); return; } @@ -764,9 +781,7 @@ if (*count <= 0) goto out_free; - spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - sgv_pools_mgr.mgr.thr.active_pages_total += pages; - spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); + atomic_add(pages, &sgv_pools_mgr.mgr.thr.active_pages_total); out: TRACE_MEM("Alloced sg %p (count %d)", res, *count); @@ -784,9 +799,7 @@ { TRACE_MEM("Freeing sg=%p", sg); - spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); - sgv_pools_mgr.mgr.thr.active_pages_total -= count; - spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock); + atomic_sub(count, &sgv_pools_mgr.mgr.thr.active_pages_total); scst_free_sys_sg_entries(sg, count, NULL); kfree(sg); @@ -907,15 +920,15 @@ TRACE_MEM("sgv_max_local_order %d, sgv_max_trans_order %d", pmgr->sgv_max_local_order, pmgr->sgv_max_trans_order); - TRACE_MEM("max object size with embedded sgv & ttbl %d", + TRACE_MEM("max object size with embedded sgv & ttbl %zd", (1 << pmgr->sgv_max_local_order) * (sizeof(struct trans_tbl_ent) + sizeof(struct scatterlist)) + sizeof(struct sgv_pool_obj)); - TRACE_MEM("max object size with embedded sgv (!clustered) %d", + TRACE_MEM("max object size with embedded sgv (!clustered) %zd", (1 << pmgr->sgv_max_local_order) * (sizeof(struct scatterlist)) + sizeof(struct sgv_pool_obj)); - TRACE_MEM("max object size with embedded ttbl %d", + TRACE_MEM("max object size with embedded ttbl %zd", (1 << pmgr->sgv_max_trans_order) * sizeof(struct trans_tbl_ent) + sizeof(struct sgv_pool_obj)); } @@ -1087,6 +1100,8 @@ memset(pools, 0, sizeof(*pools)); + atomic_set(&sgv_pools_mgr.mgr.thr.active_pages_total, 0); + sgv_pools_mgr.mgr.thr.hi_wmk = mem_hwmark >> PAGE_SHIFT; sgv_pools_mgr.mgr.thr.lo_wmk = mem_lwmark >> PAGE_SHIFT; @@ -1234,7 +1249,7 @@ seq_printf(seq, "%-42s %d/%d\n%-42s %d/%d\n%-42s %d/%d\n\n", "Inactive/active pages", sgv_pools_mgr.mgr.thr.inactive_pages_total, - sgv_pools_mgr.mgr.thr.active_pages_total, + atomic_read(&sgv_pools_mgr.mgr.thr.active_pages_total), "Hi/lo watermarks [pages]", sgv_pools_mgr.mgr.thr.hi_wmk, sgv_pools_mgr.mgr.thr.lo_wmk, "Hi watermark releases/failures", sgv_pools_mgr.mgr.thr.releases_on_hiwmk, Modified: trunk/scst/src/scst_mem.h =================================================================== --- trunk/scst/src/scst_mem.h 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_mem.h 2008-04-22 10:30:53 UTC (rev 350) @@ -106,7 +106,7 @@ struct sgv_mem_throttling { u32 inactive_pages_total; - u32 active_pages_total; + atomic_t active_pages_total; u32 hi_wmk; /* compared against inactive_pages_total + active_pages_total */ u32 lo_wmk; /* compared against inactive_pages_total only */ Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/scst/src/scst_targ.c 2008-04-22 10:30:53 UTC (rev 350) @@ -435,19 +435,10 @@ int res = SCST_CMD_STATE_RES_CONT_SAME; int state; struct scst_device *dev = cmd->dev; - int atomic = scst_cmd_atomic(cmd); int orig_bufflen = cmd->bufflen; TRACE_ENTRY(); - if (atomic && !dev->handler->parse_atomic) { - TRACE_DBG("Dev handler %s parse() can not be " - "called in atomic context, rescheduling to the thread", - dev->handler->name); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - if (likely(!scst_is_cmd_local(cmd))) { TRACE_DBG("Calling dev handler %s parse(%p)", dev->handler->name, cmd); @@ -676,15 +667,6 @@ prep_done: if (cmd->preprocessing_only) { - if (scst_cmd_atomic(cmd) && - !cmd->tgtt->preprocessing_done_atomic) { - TRACE_DBG("%s", "preprocessing_done() can not be " - "called in atomic context, rescheduling to " - "the thread"); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) { TRACE_MGMT_DBG("ABORTED set, returning ABORTED for " "cmd %p", cmd); @@ -741,8 +723,7 @@ #ifdef EXTRACHECKS if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) || - (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) - { + (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) { PRINT_ERROR("Wrong context %d in IRQ from target %s, use " "SCST_CONTEXT_TASKLET instead\n", pref_context, cmd->tgtt->name); @@ -847,7 +828,6 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd) { int res, rc; - int atomic = scst_cmd_atomic(cmd); TRACE_ENTRY(); @@ -862,13 +842,6 @@ goto out; } - if (atomic && !cmd->tgtt->rdy_to_xfer_atomic) { - TRACE_DBG("%s", "rdy_to_xfer() can not be " - "called in atomic context, rescheduling to the thread"); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - while (1) { int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds); @@ -1707,15 +1680,6 @@ TRACE_ENTRY(); - /* Check here to let an out of SN cmd be queued w/o context switch */ - if (scst_cmd_atomic(cmd) && !handler->exec_atomic) { - TRACE_DBG("Dev handler %s exec() can not be " - "called in atomic context, rescheduling to the thread", - handler->name); - rc = SCST_EXEC_NEED_THREAD; - goto out; - } - cmd->sent_to_midlev = 1; cmd->state = SCST_CMD_STATE_EXECUTING; cmd->scst_cmd_done = scst_cmd_done_local; @@ -1772,6 +1736,16 @@ if (unlikely(rc != 0)) goto out_done; +#ifndef ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ + if (scst_cmd_atomic(cmd)) { + TRACE_DBG("Pass-through exec() can not be called in atomic " + "context, rescheduling to the thread (handler %s)", + handler->name); + rc = SCST_EXEC_NEED_THREAD; + goto out_clear; + } +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) if (unlikely(scst_alloc_request(cmd) != 0)) { if (scst_cmd_atomic(cmd)) { @@ -2207,7 +2181,8 @@ if (likely(scsi_status_is_good(cmd->status))) { unsigned char type = cmd->dev->handler->type; - if ((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10) && + if (unlikely((cmd->cdb[0] == MODE_SENSE || + cmd->cdb[0] == MODE_SENSE_10)) && cmd->tgt_dev->acg_dev->rd_only_flag && (type == TYPE_DISK || type == TYPE_WORM || type == TYPE_MOD || type == TYPE_TAPE)) { @@ -2228,7 +2203,7 @@ * Check and clear NormACA option for the device, if necessary, * since we don't support ACA */ - if ((cmd->cdb[0] == INQUIRY) && + if (unlikely((cmd->cdb[0] == INQUIRY)) && !(cmd->cdb[1] & SCST_INQ_EVPD/* Std INQUIRY data (no EVPD) */) && (cmd->resp_data_len > SCST_INQ_BYTE3)) { uint8_t *buffer; @@ -2371,16 +2346,20 @@ } else if ((cmd->status == SAM_STAT_CHECK_CONDITION) && SCST_SENSE_VALID(cmd->sense) && scst_is_ua_sense(cmd->sense) && - (cmd->sense[12] == 0x2a) && (cmd->sense[13] == 0x01)) { + (((cmd->sense[12] == 0x2a) && (cmd->sense[13] == 0x01)) || + (cmd->sense[12] == 0x29) /* reset */ || + (cmd->sense[12] == 0x28) /* medium changed */ || + (cmd->sense[12] == 0x2F) /* cleared by another ini (just in case) */)) { if (atomic) { - TRACE_DBG("%s", "MODE PARAMETERS CHANGED UA: thread " - "context required"); + TRACE_DBG("Possible parameters changed UA %x: " + "thread context required", cmd->sense[12]); res = SCST_CMD_STATE_RES_NEED_THREAD; goto out; } - TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun %Ld): " - "getting new parameters", (uint64_t)cmd->lun); + TRACE(TRACE_SCSI, "Possible parameters changed UA %x " + "(lun %Ld): getting new parameters", cmd->sense[12], + (uint64_t)cmd->lun); scst_obtain_device_parameters(cmd->dev); } else @@ -2405,18 +2384,9 @@ { int res = SCST_CMD_STATE_RES_CONT_SAME; int state; - int atomic = scst_cmd_atomic(cmd); TRACE_ENTRY(); - if (atomic && !cmd->dev->handler->dev_done_atomic) { - TRACE_DBG("Dev handler %s dev_done() can not be " - "called in atomic context, rescheduling to the thread", - cmd->dev->handler->name); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - state = SCST_CMD_STATE_PRE_XMIT_RESP; if (likely(!scst_is_cmd_local(cmd)) && likely(cmd->dev->handler->dev_done != NULL)) @@ -2481,7 +2451,6 @@ if (cmd->inc_expected_sn_on_done && cmd->sent_to_midlev) scst_inc_check_expected_sn(cmd); -out: TRACE_EXIT_HRES(res); return res; } @@ -2508,6 +2477,9 @@ if (likely(cmd->tgt_dev != NULL)) { atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count); atomic_dec(&cmd->dev->dev_cmd_count); + /* If expected values not set, expected direction is UNKNOWN */ + if (cmd->expected_data_direction == SCST_DATA_WRITE) + atomic_dec(&cmd->dev->write_cmd_count); if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE)) scst_on_hq_cmd_response(cmd); @@ -2582,17 +2554,9 @@ static int scst_xmit_response(struct scst_cmd *cmd) { int res, rc; - int atomic = scst_cmd_atomic(cmd); TRACE_ENTRY(); - if (atomic && !cmd->tgtt->xmit_response_atomic) { - TRACE_DBG("%s", "xmit_response() can not be " - "called in atomic context, rescheduling to the thread"); - res = SCST_CMD_STATE_RES_NEED_THREAD; - goto out; - } - while (1) { int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds); @@ -2755,7 +2719,8 @@ case SCST_CMD_QUEUE_UNTAGGED: #if 1 /* temporary, ToDo */ if (scst_cmd_is_expected_set(cmd)) { - if (cmd->expected_data_direction == SCST_DATA_READ) + if ((cmd->expected_data_direction == SCST_DATA_READ) && + (atomic_read(&cmd->dev->write_cmd_count) == 0)) goto ordered; } else goto ordered; @@ -2776,7 +2741,7 @@ tgt_dev->prev_cmd_ordered = 0; } else { TRACE(TRACE_MINOR, "***WARNING*** Not enough SN slots " - "%d", ARRAY_SIZE(tgt_dev->sn_slots)); + "%zd", ARRAY_SIZE(tgt_dev->sn_slots)); goto ordered; } break; @@ -2917,23 +2882,38 @@ res = scst_translate_lun(cmd); if (likely(res == 0)) { int cnt; + bool failure = false; + cmd->state = SCST_CMD_STATE_PRE_PARSE; + cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count); if (unlikely(cnt > SCST_MAX_TGT_DEV_COMMANDS)) { TRACE(TRACE_MGMT_MINOR, "Too many pending commands (%d) in " "session, returning BUSY to initiator \"%s\"", cnt, (cmd->sess->initiator_name[0] == '\0') ? "Anonymous" : cmd->sess->initiator_name); - goto out_busy; + failure = true; } + cnt = atomic_inc_return(&cmd->dev->dev_cmd_count); if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) { - TRACE(TRACE_MGMT_MINOR, "Too many pending device commands " - "(%d), returning BUSY to initiator \"%s\"", - cnt, (cmd->sess->initiator_name[0] == '\0') ? - "Anonymous" : cmd->sess->initiator_name); - goto out_busy; + if (!failure) { + TRACE(TRACE_MGMT_MINOR, "Too many pending device " + "commands (%d), returning BUSY to " + "initiator \"%s\"", cnt, + (cmd->sess->initiator_name[0] == '\0') ? + "Anonymous" : cmd->sess->initiator_name); + failure = true; + } } + + /* If expected values not set, expected direction is UNKNOWN */ + if (cmd->expected_data_direction == SCST_DATA_WRITE) + atomic_inc(&cmd->dev->write_cmd_count); + + if (unlikely(failure)) + goto out_busy; + if (!cmd->set_sn_on_restart_cmd) scst_cmd_set_sn(cmd); } else if (res < 0) { Modified: trunk/usr/fileio/Makefile =================================================================== --- trunk/usr/fileio/Makefile 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/usr/fileio/Makefile 2008-04-22 10:30:53 UTC (rev 350) @@ -41,10 +41,10 @@ all: $(PROGS) fileio_tgt: .depend_f $(OBJS_F) - $(CC) $(OBJS_F) $(LIBS) -o $@ + $(CC) $(OBJS_F) $(LIBS) $(LOCAL_LD_FLAGS) -o $@ #cdrom_tgt: .depend_c $(OBJS_C) -# $(CC) $(OBJS_C) $(LIBS) -o $@ +# $(CC) $(OBJS_C) $(LIBS) $(LOCAL_LD_FLAGS) -o $@ ifeq (.depend_f,$(wildcard .depend_f)) -include .depend_f Modified: trunk/usr/fileio/common.c =================================================================== --- trunk/usr/fileio/common.c 2008-04-21 17:37:43 UTC (rev 349) +++ trunk/usr/fileio/common.c 2008-04-22 10:30:53 UTC (rev 350) @@ -23,6 +23,7 @@ #include <unistd.h> #include <stdint.h> #include <getopt.h> +#include <inttypes.h> #include <sys/ioctl.h> #include <sys/poll.h> @@ -224,7 +225,8 @@ else #endif cmd->pbuf = (unsigned long)dev->alloc_fn(cmd->alloc_len); - TRACE_MEM("Buf %Lx alloced, len %d", cmd->pbuf, cmd->alloc_len); + TRACE_MEM("Buf %"PRIx64" alloced, len %d", cmd->pbuf, + cmd->alloc_len); reply->pbuf = cmd->pbuf; if (cmd->pbuf == 0) { TRACE(TRACE_OUT_OF_MEM, "Unable to allocate buffer " @@ -286,12 +288,12 @@ } loff = (loff_t)lba_start << dev->block_shift; - TRACE_DBG("cmd %d, buf %Lx, lba_start %Ld, loff %Ld, data_len %Ld", - vcmd->cmd->cmd_h, cmd->pbuf, lba_start, (uint64_t)loff, - (uint64_t)data_len); + TRACE_DBG("cmd %d, buf %"PRIx64", lba_start %"PRId64", loff %"PRId64 + ", data_len %"PRId64, vcmd->cmd->cmd_h, cmd->pbuf, lba_start, + (uint64_t)loff, (uint64_t)data_len); if ((loff < 0) || (data_len < 0) || ((loff + data_len) > dev->file_size)) { PRINT_INFO("Access beyond the end of the device " - "(%lld of %lld, len %Ld)", (uint64_t)loff, + "(%"PRId64" of %"PRId64", len %"PRId64")", (uint64_t)loff, (uint64_t)dev->file_size, (uint64_t)data_len); set_cmd_error(vcmd, SCST_LOAD_SENSE( scst_sense_block_out_range_error)); @@ -304,8 +306,8 @@ case WRITE_16: fua = (cdb[1] & 0x8); if (cdb[1] & 0x8) { - TRACE(TRACE_ORDER, "FUA(%d): loff=%Ld, " - "data_len=%Ld", fua, (uint64_t)loff, + TRACE(TRACE_ORDER, "FUA(%d): loff=%"PRId64", " + "data_len=%"PRId64, fua, (uint64_t)loff, (uint64_t)data_len); } break; @@ -329,7 +331,7 @@ tgt_dev = find_tgt_dev(dev, cmd->sess_h); if (tgt_dev == NULL) { - PRINT_ERROR("Session %Lx not found", + PRINT_ERROR("Session %"PRIx64" not found", cmd->sess_h); set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); @@ -340,8 +342,8 @@ tgt_dev->last_write_cmd_queue_type = cmd->queue_type; if (need_pre_sync(cmd->queue_type, last_queue_type)) { TRACE(TRACE_ORDER, "ORDERED " - "WRITE(%d): loff=%Ld, data_len=%Ld", - cmd->queue_type, (uint64_t)loff, + "WRITE(%d): loff=%"PRId64", data_len=%" + PRId64, cmd->queue_type, (uint64_t)loff, (uint64_t)data_len); do_fsync = 1; if (exec_fsync(vcmd) != 0) @@ -368,7 +370,7 @@ tgt_dev = find_tgt_dev(dev, cmd->sess_h); if (tgt_dev == NULL) { - PRINT_ERROR("Session %Lx not found", + PRINT_ERROR("Session %"PRIx64" not found", cmd->sess_h); set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); @@ -379,9 +381,9 @@ tgt_dev->last_write_cmd_queue_type = cmd->queue_type; if (need_pre_sync(cmd->queue_type, last_queue_type)) { TRACE(TRACE_ORDER, "ORDERED " - "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld", - cmd->queue_type, (uint64_t)loff, - (uint64_t)data_len); + "WRITE_VERIFY(%d): loff=%"PRId64", " + "data_len=%"PRId64, cmd->queue_type, + (uint64_t)loff, (uint64_t)data_len); do_fsync = 1; if (exec_fsync(vcmd) != 0) goto out; @@ -403,8 +405,8 @@ { int immed = cdb[1] & 0x2; TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: " - "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff, - (uint64_t)data_len, immed); + "loff=%"PRId64", data_len=%"PRId64", immed=%d", + (uint64_t)loff, (uint64_t)data_len, immed); if (immed) { /* ToDo: backgroung exec */ exec_fsync(vcmd); @@ -478,7 +480,7 @@ TRACE_ENTRY(); - TRACE_MEM("Alloc mem (cmd %d, sess_h %Lx, cdb_len %d, " + TRACE_MEM("Alloc mem (cmd %d, sess_h %"PRIx64", cdb_len %d, " "alloc_len %d, queue_type %d, data_direction %d)", cmd->cmd_h, cmd->alloc_cmd.sess_h, cmd->alloc_cmd.cdb_len, cmd->alloc_cmd.alloc_len, cmd->alloc_cmd.queue_type, @@ -497,7 +499,7 @@ #endif reply->alloc_reply.pbuf = (unsigned long)vcmd->dev->alloc_fn( cmd->alloc_cmd.alloc_len); - TRACE_MEM("Buf %Lx alloced, len %d", reply->alloc_reply.pbuf, + TRACE_MEM("Buf %"PRIx64" alloced, len %d", reply->alloc_reply.pbuf, cmd->alloc_cmd.alloc_len); if (reply->alloc_reply.pbuf == 0) { TRACE(TRACE_OUT_OF_MEM, "Unable to allocate buffer (len %d)", @@ -516,7 +518,7 @@ TRACE_ENTRY(); - TRACE_MEM("Cached mem free (cmd %d, buf %Lx)", cmd->cmd_h, + TRACE_MEM("Cached mem free (cmd %d, buf %"PRIx64")", cmd->cmd_h, cmd->on_cached_mem_free.pbuf); free((void*)(unsigned long)cmd->on_cached_mem_free.pbuf); @@ -542,11 +544,12 @@ cmd->on_free_cmd.resp_data_len, cmd->on_free_cmd.aborted, cmd->on_free_cmd.status, cmd->on_free_cmd.delivery_status); - TRACE_MEM("On free cmd (cmd %d, buf %Lx, buffer_cached %d)", cmd->cmd_h, - cmd->on_free_cmd.pbuf, cmd->on_free_cmd.buffer_cached); + TRACE_MEM("On free cmd (cmd %d, buf %"PRIx64", buffer_cached %d)", + cmd->cmd_h, cmd->on_free_cmd.pbuf, + cmd->on_free_cmd.buffer_cached); if (!cmd->on_free_cmd.buffer_cached && (cmd->on_free_cmd.pbuf != 0)) { - TRACE_MEM("Freeing buf %Lx", cmd->on_free_cmd.pbuf); + TRACE_MEM("Freeing buf %"PRIx64, cmd->on_free_cmd.pbuf); free((void*)(unsigned long)cmd->on_free_cmd.pbuf); } @@ -567,7 +570,7 @@ TRACE_ENTRY(); TRACE((cmd->tm_cmd.fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT, - "TM fn %d (sess_h %Lx, cmd_h_to_abort %d)", cmd->tm_cmd.fn, + "TM fn %d (sess_h %"PRIx64", cmd_h_to_abort %d)", cmd->tm_cmd.fn, cmd->tm_cmd.sess_h, cmd->tm_cmd.cmd_h_to_abort)... [truncated message content] |
From: <vl...@us...> - 2008-05-13 17:18:22
|
Revision: 368 http://scst.svn.sourceforge.net/scst/?rev=368&view=rev Author: vlnb Date: 2008-05-13 10:18:07 -0700 (Tue, 13 May 2008) Log Message: ----------- - In "extraclean" target new autogenerated files added - Don't automatically build iscsi-scst-adm anymore until it will be fixed Modified Paths: -------------- trunk/iscsi-scst/Makefile trunk/iscsi-scst/usr/Makefile trunk/mpt/Makefile trunk/qla2x00t/Makefile trunk/qla2x00t/qla2x00-target/Makefile trunk/scst/src/Makefile trunk/scst/src/dev_handlers/Makefile trunk/srpt/Makefile Modified: trunk/iscsi-scst/Makefile =================================================================== --- trunk/iscsi-scst/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/iscsi-scst/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -69,7 +69,8 @@ clean: $(MAKE) -C usr clean $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel clean - rm -f kernel/Modules.symvers kernel/Module.symvers + rm -f kernel/Modules.symvers kernel/Module.symvers \ + kernel/Module.markers kernel/modules.order extraclean: clean Modified: trunk/iscsi-scst/usr/Makefile =================================================================== --- trunk/iscsi-scst/usr/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/iscsi-scst/usr/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -22,7 +22,8 @@ OBJS_ADM = $(SRCS_ADM:.c=.o) CFLAGS += -O2 -fno-inline -Wall -Wstrict-prototypes -g -I../include -PROGRAMS = iscsi-scstd iscsi-scst-adm +PROGRAMS = iscsi-scstd +# iscsi-scst-adm LIBS = -lcrypto all: $(PROGRAMS) Modified: trunk/mpt/Makefile =================================================================== --- trunk/mpt/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/mpt/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -85,7 +85,8 @@ endif clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers Module.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers \ + Module.symvers Module.markers modules.order rm -rf .tmp_versions extraclean: clean Modified: trunk/qla2x00t/Makefile =================================================================== --- trunk/qla2x00t/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/qla2x00t/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -41,7 +41,8 @@ endif clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers Module.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers \ + Module.symvers Module.markers modules.order rm -rf .tmp_versions extraclean: clean Modified: trunk/qla2x00t/qla2x00-target/Makefile =================================================================== --- trunk/qla2x00t/qla2x00-target/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/qla2x00t/qla2x00-target/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -92,7 +92,8 @@ endif clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers Module.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers \ + Module.symvers Module.markers modules.order rm -rf .tmp_versions extraclean: clean Modified: trunk/scst/src/Makefile =================================================================== --- trunk/scst/src/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/scst/src/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -144,7 +144,8 @@ #EXTRA_CFLAGS += -DSCST_HIGHMEM clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers \ + Module.symvers Module.markers modules.order rm -rf .tmp_versions cd $(DEV_HANDLERS_DIR) && $(MAKE) $@ Modified: trunk/scst/src/dev_handlers/Makefile =================================================================== --- trunk/scst/src/dev_handlers/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/scst/src/dev_handlers/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -74,7 +74,8 @@ EXTRA_CFLAGS += -DDEBUG -g clean: - rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers Module.symvers + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend Modules.symvers \ + Module.symvers Module.markers modules.order rm -rf .tmp_versions extraclean: clean Modified: trunk/srpt/Makefile =================================================================== --- trunk/srpt/Makefile 2008-05-13 10:08:21 UTC (rev 367) +++ trunk/srpt/Makefile 2008-05-13 17:18:07 UTC (rev 368) @@ -50,7 +50,8 @@ clean: $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/src clean - rm -f src/Modules.symvers src/Module.symvers + rm -f src/Modules.symvers src/Module.symvers src/Module.markers \ + src/modules.order extraclean: clean This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-05-14 10:01:32
|
Revision: 369 http://scst.svn.sourceforge.net/scst/?rev=369&view=rev Author: vlnb Date: 2008-05-14 03:01:30 -0700 (Wed, 14 May 2008) Log Message: ----------- Patch from Bart Van Assche <bar...@gm...>: The script generate-kernel-patch generates a kernel tree based on the sources and the in-tree kernel patches in the SCST Subversion repository. When I submitted the first version of the generate-kernel-patch script most but not all in-tree patches were present as separate files in the SCST Subversion repository. The patch below moves the two remaining patches that are contained inline in the generate-kernel-patch script to separate files. This should make it possible to use the script on future Linux kernels without having to modify the script itself. The patch below does not contain functional changes, it only moves two patches out of the script. Modified: * scripts/generate-kernel-patch'>scripts/generate-kernel-patch Added: * srpt/src/Makefile.infiniband.Linux-2.6.24.patch'>srpt/src/Makefile.infiniband.Linux-2.6.24.patch * srpt/src/Kconfig.infiniband.Linux-2.6.24.patch'>srpt/src/Kconfig.infiniband.Linux-2.6.24.patch Also Makefile and Kconfig files were renamed (".drivers." was replaced by ".scsi.") Modified Paths: -------------- trunk/scripts/generate-kernel-patch Added Paths: ----------- trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.24.patch trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Kconfig.scst trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.15.patch trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.24.patch trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Makefile.scst trunk/srpt/src/Kconfig.infiniband.Linux-2.6.24.patch trunk/srpt/src/Makefile.infiniband.Linux-2.6.24.patch Removed Paths: ------------- trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.24.patch trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Kconfig.scsi_tgt trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.15.patch trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.24.patch trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch trunk/scst/kernel/in-tree/Makefile.scsi_tgt Modified: trunk/scripts/generate-kernel-patch =================================================================== --- trunk/scripts/generate-kernel-patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scripts/generate-kernel-patch 2008-05-14 10:01:30 UTC (rev 369) @@ -145,30 +145,12 @@ # Directory drivers/infiniband/ulp/srpt/ -cat <<'EOF' -diff -uprN orig/linux-2.6.24/drivers/infiniband/Kconfig linux-2.6.24/drivers/infiniband/Kconfig ---- orig/linux-2.6.24/drivers/infiniband/Kconfig 2008-01-24 23:58:37.000000000 +0100 -+++ linux-2.6.24/drivers/infiniband/Kconfig 2008-05-09 13:55:27.000000000 +0200 -@@ -51,6 +51,8 @@ +add_patch "srpt/src/Kconfig.infiniband.Linux-${kernel_version}.patch" \ + "linux-${kernel_version}/drivers/infiniband/Kconfig" - source "drivers/infiniband/ulp/srp/Kconfig" +add_patch "srpt/src/Makefile.infiniband.Linux-${kernel_version}.patch" \ + "linux-${kernel_version}/drivers/infiniband/Makefile" -+source "drivers/infiniband/ulp/srpt/Kconfig" -+ - source "drivers/infiniband/ulp/iser/Kconfig" - - endif # INFINIBAND -diff -uprN orig/linux-2.6.24/drivers/infiniband/Makefile linux-2.6.24/drivers/infiniband/Makefile ---- orig/linux-2.6.24/drivers/infiniband/Makefile 2008-01-24 23:58:37.000000000 +0100 -+++ linux-2.6.24/drivers/infiniband/Makefile 2008-05-09 13:57:00.000000000 +0200 -@@ -7,4 +7,5 @@ - obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ - obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ - obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ -+obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/ - obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/ -EOF - add_file "srpt/src/Kconfig" "drivers/infiniband/ulp/srpt/Kconfig" add_file "srpt/src/Makefile.in_kernel" "drivers/infiniband/ulp/srpt/Makefile" Copied: trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.24.patch (from rev 366, trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.24.patch) =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.24.patch (rev 0) +++ trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,11 @@ +--- orig/linux-2.6.24/drivers/scsi/Kconfig 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/scsi/Kconfig 2008-05-09 13:25:39.000000000 +0200 +@@ -1351,6 +1351,8 @@ config SCSI_QLOGICPTI + source "drivers/scsi/qla2xxx/Kconfig" + source "drivers/scsi/qla4xxx/Kconfig" + ++source "drivers/scsi/scsi_tgt/Kconfig" ++ + config SCSI_LPFC + tristate "Emulex LightPulse Fibre Channel Support" + depends on PCI && SCSI Copied: trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.7.patch (from rev 362, trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch) =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.7.patch (rev 0) +++ trunk/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.7.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,11 @@ +--- Kconfig 2004-08-18 13:14:50.328907320 +0400 ++++ Kconfig.scsi 2004-08-13 18:01:13.000000000 +0400 +@@ -1261,6 +1261,8 @@ config SCSI_QLOGICPTI + + source "drivers/scsi/qla2xxx/Kconfig" + ++source "drivers/scsi/scsi_tgt/Kconfig" ++ + config SCSI_SEAGATE + tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" + depends on X86 && ISA && SCSI && BROKEN Deleted: trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.24.patch =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.24.patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -1,11 +0,0 @@ ---- orig/linux-2.6.24/drivers/scsi/Kconfig 2008-01-24 23:58:37.000000000 +0100 -+++ linux-2.6.24/drivers/scsi/Kconfig 2008-05-09 13:25:39.000000000 +0200 -@@ -1351,6 +1351,8 @@ config SCSI_QLOGICPTI - source "drivers/scsi/qla2xxx/Kconfig" - source "drivers/scsi/qla4xxx/Kconfig" - -+source "drivers/scsi/scsi_tgt/Kconfig" -+ - config SCSI_LPFC - tristate "Emulex LightPulse Fibre Channel Support" - depends on PCI && SCSI Deleted: trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Kconfig.scsi.Linux-2.6.7.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -1,11 +0,0 @@ ---- Kconfig 2004-08-18 13:14:50.328907320 +0400 -+++ Kconfig.scsi 2004-08-13 18:01:13.000000000 +0400 -@@ -1261,6 +1261,8 @@ config SCSI_QLOGICPTI - - source "drivers/scsi/qla2xxx/Kconfig" - -+source "drivers/scsi/scsi_tgt/Kconfig" -+ - config SCSI_SEAGATE - tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" - depends on X86 && ISA && SCSI && BROKEN Deleted: trunk/scst/kernel/in-tree/Kconfig.scsi_tgt =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.scsi_tgt 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Kconfig.scsi_tgt 2008-05-14 10:01:30 UTC (rev 369) @@ -1,86 +0,0 @@ -config SCSI_TARGET - tristate "SCSI target middle level support" - default SCSI - depends on SCSI && PROC_FS - ---help--- - SCSI TARGET is designed to provide unified, consistent interface - between SCSI target drivers and Linux kernel and simplify target - drivers development as much as possible. - -config SCSI_TARGET_DISK - tristate "SCSI target disk support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for disk device. - -config SCSI_TARGET_TAPE - tristate "SCSI target tape support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for tape device. - -config SCSI_TARGET_CDROM - tristate "SCSI target cdrom support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for cdrom device. - -config SCSI_TARGET_MODISK - tristate "SCSI target MO disk support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for MO disk device. - -config SCSI_TARGET_CHANGER - tristate "SCSI target changer support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for changer device. - -config SCSI_TARGET_PROCESSOR - tristate "SCSI target processor support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for processor device. - -config SCSI_TARGET_RAID - tristate "SCSI target storage array controller (raid) support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for raid storage array controller (raid) device. - -config SCSI_TARGET_VDISK - tristate "SCSI target virtual disk and/or cdrom support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for virtual disk and/or cdrom device. - -config SCSI_TARGET_USER - tristate "SCSI user space virtual target devices support" - default SCSI_TARGET - depends on SCSI && PROC_FS && SCSI_TARGET - ---help--- - SCSI TARGET handler for virtual user space device. - -config SCSI_TARGET_EXTRACHECKS - bool "Extrachecks support" - ---help--- - SCSI TARGET extrachecks. - -config SCSI_TARGET_TRACING - bool "Tracing support" - ---help--- - SCSI TARGET tracing. - -config SCSI_TARGET_DEBUG - bool "Debug support" - ---help--- - SCSI TARGET debugging. Copied: trunk/scst/kernel/in-tree/Kconfig.scst (from rev 362, trunk/scst/kernel/in-tree/Kconfig.scsi_tgt) =================================================================== --- trunk/scst/kernel/in-tree/Kconfig.scst (rev 0) +++ trunk/scst/kernel/in-tree/Kconfig.scst 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,86 @@ +config SCSI_TARGET + tristate "SCSI target middle level support" + default SCSI + depends on SCSI && PROC_FS + ---help--- + SCSI TARGET is designed to provide unified, consistent interface + between SCSI target drivers and Linux kernel and simplify target + drivers development as much as possible. + +config SCSI_TARGET_DISK + tristate "SCSI target disk support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for disk device. + +config SCSI_TARGET_TAPE + tristate "SCSI target tape support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for tape device. + +config SCSI_TARGET_CDROM + tristate "SCSI target cdrom support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for cdrom device. + +config SCSI_TARGET_MODISK + tristate "SCSI target MO disk support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for MO disk device. + +config SCSI_TARGET_CHANGER + tristate "SCSI target changer support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for changer device. + +config SCSI_TARGET_PROCESSOR + tristate "SCSI target processor support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for processor device. + +config SCSI_TARGET_RAID + tristate "SCSI target storage array controller (raid) support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for raid storage array controller (raid) device. + +config SCSI_TARGET_VDISK + tristate "SCSI target virtual disk and/or cdrom support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for virtual disk and/or cdrom device. + +config SCSI_TARGET_USER + tristate "SCSI user space virtual target devices support" + default SCSI_TARGET + depends on SCSI && PROC_FS && SCSI_TARGET + ---help--- + SCSI TARGET handler for virtual user space device. + +config SCSI_TARGET_EXTRACHECKS + bool "Extrachecks support" + ---help--- + SCSI TARGET extrachecks. + +config SCSI_TARGET_TRACING + bool "Tracing support" + ---help--- + SCSI TARGET tracing. + +config SCSI_TARGET_DEBUG + bool "Debug support" + ---help--- + SCSI TARGET debugging. Copied: trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.15.patch (from rev 362, trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.15.patch) =================================================================== --- trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.15.patch (rev 0) +++ trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.15.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,10 @@ +--- Makefile.orig 2006-12-11 14:29:39.000000000 -0700 ++++ Makefile 2006-12-11 14:29:52.000000000 -0700 +@@ -81,6 +81,7 @@ + obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o + obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o + obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ ++obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ + obj-$(CONFIG_SCSI_LPFC) += lpfc/ + obj-$(CONFIG_SCSI_PAS16) += pas16.o + obj-$(CONFIG_SCSI_SEAGATE) += seagate.o Copied: trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.24.patch (from rev 366, trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.24.patch) =================================================================== --- trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.24.patch (rev 0) +++ trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,11 @@ +diff -uprN orig/linux-2.6.24/drivers/scsi/Makefile linux-2.6.24/drivers/scsi/Makefile +--- orig/linux-2.6.24/drivers/scsi/Makefile 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/scsi/Makefile 2008-05-09 13:05:36.000000000 +0200 +@@ -88,6 +88,7 @@ obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas + obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o + obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ + obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ ++obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ + obj-$(CONFIG_SCSI_LPFC) += lpfc/ + obj-$(CONFIG_SCSI_PAS16) += pas16.o + obj-$(CONFIG_SCSI_SEAGATE) += seagate.o Copied: trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.7.patch (from rev 362, trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch) =================================================================== --- trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.7.patch (rev 0) +++ trunk/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.7.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,10 @@ +--- Makefile 2004-08-18 13:20:55.434402848 +0400 ++++ Makefile.scsi 2004-08-13 18:01:13.000000000 +0400 +@@ -81,6 +81,7 @@ obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogici + obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o + obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o + obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ ++obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ + obj-$(CONFIG_SCSI_PAS16) += pas16.o + obj-$(CONFIG_SCSI_SEAGATE) += seagate.o + obj-$(CONFIG_SCSI_FD_8xx) += seagate.o Deleted: trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.15.patch =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.15.patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.15.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -1,10 +0,0 @@ ---- Makefile.orig 2006-12-11 14:29:39.000000000 -0700 -+++ Makefile 2006-12-11 14:29:52.000000000 -0700 -@@ -81,6 +81,7 @@ - obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o - obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o - obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ -+obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ - obj-$(CONFIG_SCSI_LPFC) += lpfc/ - obj-$(CONFIG_SCSI_PAS16) += pas16.o - obj-$(CONFIG_SCSI_SEAGATE) += seagate.o Deleted: trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.24.patch =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.24.patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -1,11 +0,0 @@ -diff -uprN orig/linux-2.6.24/drivers/scsi/Makefile linux-2.6.24/drivers/scsi/Makefile ---- orig/linux-2.6.24/drivers/scsi/Makefile 2008-01-24 23:58:37.000000000 +0100 -+++ linux-2.6.24/drivers/scsi/Makefile 2008-05-09 13:05:36.000000000 +0200 -@@ -88,6 +88,7 @@ obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas - obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o - obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ - obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ -+obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ - obj-$(CONFIG_SCSI_LPFC) += lpfc/ - obj-$(CONFIG_SCSI_PAS16) += pas16.o - obj-$(CONFIG_SCSI_SEAGATE) += seagate.o Deleted: trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Makefile.scsi.Linux-2.6.7.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -1,10 +0,0 @@ ---- Makefile 2004-08-18 13:20:55.434402848 +0400 -+++ Makefile.scsi 2004-08-13 18:01:13.000000000 +0400 -@@ -81,6 +81,7 @@ obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogici - obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o - obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o - obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ -+obj-$(CONFIG_SCSI_TARGET) += scsi_tgt/ - obj-$(CONFIG_SCSI_PAS16) += pas16.o - obj-$(CONFIG_SCSI_SEAGATE) += seagate.o - obj-$(CONFIG_SCSI_FD_8xx) += seagate.o Deleted: trunk/scst/kernel/in-tree/Makefile.scsi_tgt =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scsi_tgt 2008-05-13 17:18:07 UTC (rev 368) +++ trunk/scst/kernel/in-tree/Makefile.scsi_tgt 2008-05-14 10:01:30 UTC (rev 369) @@ -1,11 +0,0 @@ -EXTRA_CFLAGS += -Iinclude/scsi_tgt -Wextra -Wno-unused-parameter - -scst-y += scst_main.o -scst-y += scst_targ.o -scst-y += scst_lib.o -scst-y += scst_proc.o -scst-y += scst_mem.o -scst-y += scst_debug.o - -obj-$(CONFIG_SCSI_TARGET) += scst.o dev_handlers/ - Copied: trunk/scst/kernel/in-tree/Makefile.scst (from rev 366, trunk/scst/kernel/in-tree/Makefile.scsi_tgt) =================================================================== --- trunk/scst/kernel/in-tree/Makefile.scst (rev 0) +++ trunk/scst/kernel/in-tree/Makefile.scst 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,11 @@ +EXTRA_CFLAGS += -Iinclude/scsi_tgt -Wextra -Wno-unused-parameter + +scst-y += scst_main.o +scst-y += scst_targ.o +scst-y += scst_lib.o +scst-y += scst_proc.o +scst-y += scst_mem.o +scst-y += scst_debug.o + +obj-$(CONFIG_SCSI_TARGET) += scst.o dev_handlers/ + Added: trunk/srpt/src/Kconfig.infiniband.Linux-2.6.24.patch =================================================================== --- trunk/srpt/src/Kconfig.infiniband.Linux-2.6.24.patch (rev 0) +++ trunk/srpt/src/Kconfig.infiniband.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,12 @@ +diff -uprN orig/linux-2.6.24/drivers/infiniband/Kconfig linux-2.6.24/drivers/infiniband/Kconfig +--- orig/linux-2.6.24/drivers/infiniband/Kconfig 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/infiniband/Kconfig 2008-05-09 13:55:27.000000000 +0200 +@@ -51,6 +51,8 @@ + + source "drivers/infiniband/ulp/srp/Kconfig" + ++source "drivers/infiniband/ulp/srpt/Kconfig" ++ + source "drivers/infiniband/ulp/iser/Kconfig" + + endif # INFINIBAND Added: trunk/srpt/src/Makefile.infiniband.Linux-2.6.24.patch =================================================================== --- trunk/srpt/src/Makefile.infiniband.Linux-2.6.24.patch (rev 0) +++ trunk/srpt/src/Makefile.infiniband.Linux-2.6.24.patch 2008-05-14 10:01:30 UTC (rev 369) @@ -0,0 +1,9 @@ +diff -uprN orig/linux-2.6.24/drivers/infiniband/Makefile linux-2.6.24/drivers/infiniband/Makefile +--- orig/linux-2.6.24/drivers/infiniband/Makefile 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/infiniband/Makefile 2008-05-09 13:57:00.000000000 +0200 +@@ -7,4 +7,5 @@ + obj-$(CONFIG_MLX4_INFINIBAND) += hw/mlx4/ + obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ + obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ ++obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/ + obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <vl...@us...> - 2008-05-14 17:20:30
|
Revision: 371 http://scst.svn.sourceforge.net/scst/?rev=371&view=rev Author: vlnb Date: 2008-05-14 10:20:20 -0700 (Wed, 14 May 2008) Log Message: ----------- Interface versioning between iSCSI-SCST kernel and user space parts, iscsi_u.h renamed to iscsi_scst.h. Property svn:ignore adjusted accordingly. Docs updated. Modified Paths: -------------- trunk/iscsi-scst/Makefile trunk/iscsi-scst/README trunk/iscsi-scst/kernel/config.c trunk/iscsi-scst/kernel/event.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/usr/ctldev.c trunk/iscsi-scst/usr/iscsi_scstd.c trunk/iscsi-scst/usr/iscsid.h Added Paths: ----------- trunk/iscsi-scst/include/iscsi_scst.h trunk/iscsi-scst/include/iscsi_scst_ver.h Removed Paths: ------------- trunk/iscsi-scst/include/iscsi_u.h Property Changed: ---------------- trunk/ trunk/doc/ trunk/iscsi-scst/ trunk/iscsi-scst/doc/ trunk/iscsi-scst/doc/manpages/ trunk/iscsi-scst/etc/ trunk/iscsi-scst/etc/initd/ trunk/iscsi-scst/include/ trunk/iscsi-scst/kernel/ trunk/iscsi-scst/kernel/patches/ trunk/iscsi-scst/usr/ trunk/mpt/ trunk/mpt/in-tree/ trunk/qla2x00t/ trunk/qla2x00t/qla2x00-target/ trunk/qla_isp/ trunk/qla_isp/common/ trunk/qla_isp/doc/ trunk/qla_isp/firmware/ trunk/qla_isp/linux/ trunk/qla_isp/linux-2.6/ trunk/qla_isp/linux-2.6/build/ trunk/scripts/ trunk/scst/ trunk/scst/include/ trunk/scst/kernel/ trunk/scst/kernel/in-tree/ trunk/scst/kernel/old_unsupported/ trunk/scst/src/ trunk/scst/src/dev_handlers/ trunk/scstadmin/ trunk/scstadmin/SCST/ trunk/scstadmin/examples/ trunk/scstadmin/init.d/ trunk/scstadmin/scst_db/ trunk/srpt/ trunk/srpt/patches/ trunk/srpt/src/ trunk/usr/ trunk/usr/fileio/ trunk/www/ Property changes on: trunk ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Modified: trunk/iscsi-scst/Makefile =================================================================== --- trunk/iscsi-scst/Makefile 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/Makefile 2008-05-14 17:20:20 UTC (rev 371) @@ -1,11 +1,9 @@ # -# Makefile for the Linux kernel device drivers. +# Makefile for iSCSI-SCST # # 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. SCST_DIR := $(shell pwd)/../scst/src SUBDIRS := $(shell pwd) @@ -21,7 +19,7 @@ KDIR ?= /lib/modules/$(KVER)/build endif -all: progs mods +all: include/iscsi_scst_itf_ver.h progs mods mods: Modules.symvers Module.symvers $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel modules @@ -29,9 +27,15 @@ progs: $(MAKE) -C usr -install: all kernel/iscsi-scst.ko usr/iscsi-scstd usr/iscsi-scst-adm +include/iscsi_scst_itf_ver.h: include/iscsi_scst.h + echo "/* Autogenerated, don't edit */" >include/iscsi_scst_itf_ver.h + echo "" >>include/iscsi_scst_itf_ver.h + echo -n "#define ISCSI_SCST_INTERFACE_VERSION " >>include/iscsi_scst_itf_ver.h + echo "\"`sha1sum include/iscsi_scst.h|awk '{printf $$1}'`\"" >>include/iscsi_scst_itf_ver.h + +install: all @install -vD usr/iscsi-scstd $(DISTDIR)/usr/local/sbin/iscsi-scstd - @install -vD usr/iscsi-scst-adm $(DISTDIR)/usr/local/sbin/iscsi-scst-adm + -@install -vD usr/iscsi-scst-adm $(DISTDIR)/usr/local/sbin/iscsi-scst-adm if [ -f /etc/debian_version ]; then \ install -vD -m 755 etc/initd/initd.debian $(DISTDIR)/etc/init.d/iscsi-scst; \ elif [ -f /etc/redhat-release ]; then \ @@ -70,7 +74,8 @@ $(MAKE) -C usr clean $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd)/kernel clean rm -f kernel/Modules.symvers kernel/Module.symvers \ - kernel/Module.markers kernel/modules.order + kernel/Module.markers kernel/modules.order \ + include/iscsi_scst_itf_ver.h extraclean: clean Modified: trunk/iscsi-scst/README =================================================================== --- trunk/iscsi-scst/README 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/README 2008-05-14 17:20:20 UTC (rev 371) @@ -32,6 +32,12 @@ Basically as in README-IET, where file names are changed as specified above. +If during compilation you see message like "*** No rule to make target +`xxx.h', needed by `yyy.o'. Stop.", then your autogenerated +dependencies don't match your compiler configuration anymore. You should +run "make extraclean" to remove them. On the next compilation they will +be regenerated. + If you experience problems during kernel module load or running, check your system and/or kernel logs (or run dmesg command for the few most recent kernel messages). Property changes on: trunk/iscsi-scst/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst/doc/manpages ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst/etc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst/etc/initd ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst/include ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Copied: trunk/iscsi-scst/include/iscsi_scst.h (from rev 370, trunk/iscsi-scst/include/iscsi_u.h) =================================================================== --- trunk/iscsi-scst/include/iscsi_scst.h (rev 0) +++ trunk/iscsi-scst/include/iscsi_scst.h 2008-05-14 17:20:20 UTC (rev 371) @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2007 Vladislav Bolkhovitin + * Copyright (C) 2007 CMS Distribution Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _ISCSI_SCST_U_H +#define _ISCSI_SCST_U_H + +#ifndef __KERNEL__ +#include <sys/uio.h> +#endif + +#include "iscsi_scst_ver.h" +#include "iscsi_scst_itf_ver.h" + +/* The maximum length of 223 bytes in the RFC. */ +#define ISCSI_NAME_LEN 256 + +#define ISCSI_LISTEN_PORT 3260 + +#define SCSI_ID_LEN 24 + +#ifndef aligned_u64 +#define aligned_u64 uint64_t __attribute__((aligned(8))) +#endif + +struct target_info { + u32 tid; + char name[ISCSI_NAME_LEN]; +}; + +struct session_info { + u32 tid; + + aligned_u64 sid; + char initiator_name[ISCSI_NAME_LEN]; + char user_name[ISCSI_NAME_LEN]; + u32 exp_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_queued_cmnds, + 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 iscsi_event_state { + E_CONN_CLOSE, +}; + +struct iscsi_event { + u32 tid; + aligned_u64 sid; + u32 cid; + u32 state; +}; + +#define DEFAULT_NR_QUEUED_CMNDS 32 +#define MIN_NR_QUEUED_CMNDS 1 +#define MAX_NR_QUEUED_CMNDS 256 + +#define MAX_DATA_SEG_LEN (4096/sizeof(struct iovec)*4096) + +#define NETLINK_ISCSI_SCST 25 + +#define REGISTER_USERD _IOW('s', 0, const char*) +#define ADD_TARGET _IOW('s', 1, struct target_info) +#define DEL_TARGET _IOW('s', 2, struct target_info) +#define ADD_SESSION _IOW('s', 3, struct session_info) +#define DEL_SESSION _IOW('s', 4, struct session_info) +#define GET_SESSION_INFO _IOWR('s', 5, struct session_info) +#define ADD_CONN _IOW('s', 6, struct conn_info) +#define DEL_CONN _IOW('s', 7, struct conn_info) +#define GET_CONN_INFO _IOWR('s', 8, struct conn_info) +#define ISCSI_PARAM_SET _IOW('s', 9, struct iscsi_param_info) +#define ISCSI_PARAM_GET _IOWR('s', 10, struct iscsi_param_info) + +static inline int iscsi_is_key_declarative(int key) +{ + switch(key) + { + case key_max_xmit_data_length: + return 1; + default: + return 0; + } +} + +#endif Added: trunk/iscsi-scst/include/iscsi_scst_ver.h =================================================================== --- trunk/iscsi-scst/include/iscsi_scst_ver.h (rev 0) +++ trunk/iscsi-scst/include/iscsi_scst_ver.h 2008-05-14 17:20:20 UTC (rev 371) @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2007 Vladislav Bolkhovitin + * Copyright (C) 2007 CMS Distribution Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define ISCSI_VERSION_STRING "0.9.6/0.4.15r148" Deleted: trunk/iscsi-scst/include/iscsi_u.h =================================================================== --- trunk/iscsi-scst/include/iscsi_u.h 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/include/iscsi_u.h 2008-05-14 17:20:20 UTC (rev 371) @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2007 Vladislav Bolkhovitin - * Copyright (C) 2007 CMS Distribution Limited - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, version 2 - * of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _ISCSI_U_H -#define _ISCSI_U_H - -#ifndef __KERNEL__ -#include <sys/uio.h> -#endif - -#define ISCSI_VERSION_STRING "0.9.6/0.4.15r148" - -/* The maximum length of 223 bytes in the RFC. */ -#define ISCSI_NAME_LEN 256 - -#define ISCSI_LISTEN_PORT 3260 - -#define SCSI_ID_LEN 24 - -#ifndef aligned_u64 -#define aligned_u64 uint64_t __attribute__((aligned(8))) -#endif - -struct target_info { - u32 tid; - char name[ISCSI_NAME_LEN]; -}; - -struct session_info { - u32 tid; - - aligned_u64 sid; - char initiator_name[ISCSI_NAME_LEN]; - char user_name[ISCSI_NAME_LEN]; - u32 exp_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_queued_cmnds, - 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 iscsi_event_state { - E_CONN_CLOSE, -}; - -struct iscsi_event { - u32 tid; - aligned_u64 sid; - u32 cid; - u32 state; -}; - -#define DEFAULT_NR_QUEUED_CMNDS 32 -#define MIN_NR_QUEUED_CMNDS 1 -#define MAX_NR_QUEUED_CMNDS 256 - -#define MAX_DATA_SEG_LEN (4096/sizeof(struct iovec)*4096) - -#define NETLINK_ISCSI_SCST 25 - -#define ADD_TARGET _IOW('i', 0, struct target_info) -#define DEL_TARGET _IOW('i', 1, struct target_info) -#define ADD_SESSION _IOW('i', 2, struct session_info) -#define DEL_SESSION _IOW('i', 3, struct session_info) -#define GET_SESSION_INFO _IOWR('i', 4, struct session_info) -#define ADD_CONN _IOW('i', 5, struct conn_info) -#define DEL_CONN _IOW('i', 6, struct conn_info) -#define GET_CONN_INFO _IOWR('i', 7, struct conn_info) -#define ISCSI_PARAM_SET _IOW('i', 8, struct iscsi_param_info) -#define ISCSI_PARAM_GET _IOWR('i', 9, struct iscsi_param_info) - -static inline int iscsi_is_key_declarative(int key) -{ - switch(key) - { - case key_max_xmit_data_length: - return 1; - default: - return 0; - } -} - -#endif Property changes on: trunk/iscsi-scst/kernel ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Modified: trunk/iscsi-scst/kernel/config.c =================================================================== --- trunk/iscsi-scst/kernel/config.c 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/kernel/config.c 2008-05-14 17:20:20 UTC (rev 371) @@ -369,12 +369,40 @@ return err; } +static int iscsi_check_version(unsigned long arg) +{ + char ver[sizeof(ISCSI_SCST_INTERFACE_VERSION)+1]; + int res; + + res = copy_from_user(ver, (void*)arg, sizeof(ver)); + if (res < 0) { + PRINT_ERROR("%s", "Unable to get version string"); + goto out; + } + ver[sizeof(ver)-1] = '\0'; + + if (strcmp(ver, ISCSI_SCST_INTERFACE_VERSION) != 0) { + PRINT_ERROR("Incorrect version of user space %s (needed %s)", + ver, ISCSI_SCST_INTERFACE_VERSION); + res = -EINVAL; + goto out; + } + +out: + return res; +} + static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct iscsi_target *target = NULL; long err; u32 id; + if (cmd == REGISTER_USERD) { + err = iscsi_check_version(arg); + goto out; + } + if ((err = get_user(id, (u32 *) arg)) != 0) goto out; @@ -441,10 +469,11 @@ case GET_CONN_INFO: err = get_conn_info(target, arg); break; - + default: PRINT_ERROR("invalid ioctl cmd %x", cmd); err = -EINVAL; + break; } mutex_unlock(&target->target_mutex); Modified: trunk/iscsi-scst/kernel/event.c =================================================================== --- trunk/iscsi-scst/kernel/event.c 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/kernel/event.c 2008-05-14 17:20:20 UTC (rev 371) @@ -18,7 +18,7 @@ */ #include <net/tcp.h> -#include "iscsi_u.h" +#include "iscsi_scst.h" #include "iscsi.h" static struct sock *nl; Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-05-14 17:20:20 UTC (rev 371) @@ -26,7 +26,7 @@ #include <scst.h> #include "iscsi_hdr.h" -#include "iscsi_u.h" +#include "iscsi_scst.h" #include "iscsi_dbg.h" Property changes on: trunk/iscsi-scst/kernel/patches ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/iscsi-scst/usr ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Modified: trunk/iscsi-scst/usr/ctldev.c =================================================================== --- trunk/iscsi-scst/usr/ctldev.c 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/usr/ctldev.c 2008-05-14 17:20:20 UTC (rev 371) @@ -40,11 +40,12 @@ char devname[256]; char buf[256]; int devn; - int ctlfd; + int ctlfd = -1; + int err; if (!(f = fopen("/proc/devices", "r"))) { perror("Cannot open control path to the driver\n"); - return -1; + goto out; } devn = 0; @@ -63,24 +64,32 @@ fclose(f); if (!devn) { - printf - ("cannot find iscsictl in /proc/devices - " + printf("cannot find iscsictl in /proc/devices - " "make sure the module is loaded\n"); - return -1; + goto out; } unlink(CTL_DEVICE); if (mknod(CTL_DEVICE, (S_IFCHR | 0600), (devn << 8))) { printf("cannot create %s %d\n", CTL_DEVICE, errno); - return -1; + goto out; } ctlfd = open(CTL_DEVICE, O_RDWR); if (ctlfd < 0) { printf("cannot open %s %d\n", CTL_DEVICE, errno); - return -1; + goto out; } + err = ioctl(ctlfd, REGISTER_USERD, ISCSI_SCST_INTERFACE_VERSION); + if (err < 0) { + log_error("Unable to register: %s\n", strerror(errno)); + close(ctlfd); + ctlfd = -1; + goto out; + } + +out: return ctlfd; } Modified: trunk/iscsi-scst/usr/iscsi_scstd.c =================================================================== --- trunk/iscsi-scst/usr/iscsi_scstd.c 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/usr/iscsi_scstd.c 2008-05-14 17:20:20 UTC (rev 371) @@ -573,10 +573,8 @@ exit(-1); }; - if ((ctrl_fd = ki->ctldev_open()) < 0) { - perror("ctldev fd\n"); + if ((ctrl_fd = ki->ctldev_open()) < 0) exit(-1); - } if ((ipc_fd = iscsi_adm_request_listen()) < 0) { perror("ipc fd\n"); Modified: trunk/iscsi-scst/usr/iscsid.h =================================================================== --- trunk/iscsi-scst/usr/iscsid.h 2008-05-14 14:58:29 UTC (rev 370) +++ trunk/iscsi-scst/usr/iscsid.h 2008-05-14 17:20:20 UTC (rev 371) @@ -22,7 +22,7 @@ #include "types.h" #include "iscsi_hdr.h" -#include "iscsi_u.h" +#include "iscsi_scst.h" #include "param.h" #include "config.h" #include "misc.h" Property changes on: trunk/mpt ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/mpt/in-tree ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla2x00t ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla2x00t/qla2x00-target ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/common ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/doc ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/firmware ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/linux ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/linux-2.6 ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/qla_isp/linux-2.6/build ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scripts ___________________________________________________________________ Name: svn:ignore + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/include ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/kernel ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/kernel/in-tree ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/kernel/old_unsupported ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/src ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scst/src/dev_handlers ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scstadmin ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scstadmin/SCST ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scstadmin/examples ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scstadmin/init.d ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/scstadmin/scst_db ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/srpt ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/srpt/patches ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/srpt/src ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/usr ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/usr/fileio ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h Property changes on: trunk/www ___________________________________________________________________ Name: svn:ignore - *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt + *.o *.mod.c *.ko *.ko.cmd *.o.cmd .tmp_versions Modules.symvers Module.symvers modules.order Module.markers .depend* iscsi-scst-adm iscsi-scstd fileio_tgt iscsi_scst_itf_ver.h This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |