diff --git a/iscsi-scst/etc/initd/initd.debian b/iscsi-scst/etc/initd/initd.debian index aff73f97d..49182e314 100644 --- a/iscsi-scst/etc/initd/initd.debian +++ b/iscsi-scst/etc/initd/initd.debian @@ -59,6 +59,7 @@ iscsi_scstd_start() echo "succeeded." else echo "failed." + rmmod iscsi-scst fi } diff --git a/iscsi-scst/etc/initd/initd.redhat b/iscsi-scst/etc/initd/initd.redhat index 6ce007619..d441ebc42 100644 --- a/iscsi-scst/etc/initd/initd.redhat +++ b/iscsi-scst/etc/initd/initd.redhat @@ -67,7 +67,6 @@ start() stop() { echo -n "Stopping iSCSI target service: " -# iscsi-scst-adm --op delete killall iscsi-scstd rmmod -w iscsi-scst RETVAL=$? diff --git a/iscsi-scst/etc/scst.conf b/iscsi-scst/etc/scst.conf index cf4cf9976..0a5fe3277 100644 --- a/iscsi-scst/etc/scst.conf +++ b/iscsi-scst/etc/scst.conf @@ -1,7 +1,7 @@ [HANDLER vdisk] #DEVICE ,,, DEVICE disk1,/path/disk1,,512 -DEVICE hdc1,/dev/hdc1,BLOCKIO,512 +DEVICE hdc1,/dev/hdc1,BIO,512 DEVICE nullio,none,NULLIO,1024 [HANDLER vcdrom] @@ -10,14 +10,11 @@ DEVICE nullio,none,NULLIO,1024 [ASSIGNMENT Default] #DEVICE , -[GROUP Default_iqn.2007-05.com.example:storage.disk2.sys1.xyz] -# This user isn't needed in this default group, but current version of -# scstadmin (0.7.1) has a problem that it refuses to create a group if -# it doesn't have at least one user. -USER NULL_USER +[ASSIGNMENT Default_iqn.2007-05.com.example:storage.disk1.sys1.xyz] +#DEVICE , +DEVICE disk1,0 +DEVICE nullio,3 [ASSIGNMENT Default_iqn.2007-05.com.example:storage.disk2.sys1.xyz] #DEVICE , -DEVICE disk1,0 -DEVICE hdc1,1 -DEVICE nullio,3 +DEVICE hdc1,0 diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index bc62b847e..1a23679dd 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1410,14 +1410,18 @@ static inline int __cmnd_abort(struct iscsi_cmnd *cmnd) goto out; TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " - "ref_cnt %d, net_ref_cnt %d, itt %x, 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), atomic_read(&cmnd->net_ref_cnt), + "ref_cnt %d, itt %x, 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->is_unsolicited_data, cmnd->outstanding_r2t); +#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); cmnd->tmfabort = 1; diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index c6fbff168..dd9fc7ba0 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -155,13 +155,14 @@ static void create_listen_socket(struct pollfd *array) exit(1); } - for (i = 0, res = res0; res && i < LISTEN_MAX; i++, res = res->ai_next) { + i = 0; + for (res = res0; res && i < LISTEN_MAX; 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!", strerror(errno), res->ai_family, res->ai_socktype, res->ai_protocol); - exit(1); + continue; } sock_set_keepalive(sock, 50); @@ -174,26 +175,34 @@ static void create_listen_socket(struct pollfd *array) if (res->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt))) { log_error("Unable to restrict IPv6 socket (%s)", strerror(errno)); - exit(1); + close(sock); + continue; } if (bind(sock, res->ai_addr, res->ai_addrlen)) { log_error("Unable to bind server socket (%s)!", strerror(errno)); - exit(1); + close(sock); + continue; } if (listen(sock, INCOMING_MAX)) { log_error("Unable to listen to server socket (%s)!", strerror(errno)); - exit(1); + close(sock); + continue; } set_non_blocking(sock); array[i].fd = sock; array[i].events = POLLIN; + + i++; } freeaddrinfo(res0); + + if (i == 0) + exit(1); } static void accept_connection(int listen) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 5f6d40778..9a9c1d361 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -2076,6 +2076,17 @@ struct blockio_work { struct scst_cmd *cmd; }; +static inline void blockio_check_finish(struct blockio_work *blockio_work) +{ + /* Decrement the bios in processing, and if zero signal completion */ + if (atomic_dec_and_test(&blockio_work->bios_inflight)) { + blockio_work->cmd->completed = 1; + blockio_work->cmd->scst_cmd_done(blockio_work->cmd, + SCST_CMD_STATE_DEFAULT); + kfree(blockio_work); + } +} + static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error) { struct blockio_work *blockio_work = bio->bi_private; @@ -2101,13 +2112,7 @@ static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error) SCST_LOAD_SENSE(scst_sense_read_error)); } - /* Decrement the bios in processing, and if zero signal completion */ - if (atomic_dec_and_test(&blockio_work->bios_inflight)) { - blockio_work->cmd->completed = 1; - blockio_work->cmd->scst_cmd_done(blockio_work->cmd, - SCST_CMD_STATE_DEFAULT); - kfree(blockio_work); - } + blockio_check_finish(blockio_work); bio_put(bio); return 0; @@ -2154,6 +2159,8 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, thislen = 0; while (len > 0) { + int rc; + if (need_new_bio) { bio = bio_alloc(GFP_KERNEL, max_nr_vecs); if (!bio) { @@ -2181,7 +2188,9 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, bytes = min_t(unsigned int, len, PAGE_SIZE - off); - if (bio_add_page(bio, page, bytes, off) < bytes) { + rc = bio_add_page(bio, page, bytes, off); + if (rc < bytes) { + sBUG_ON(rc != 0); need_new_bio = 1; lba_start += thislen >> virt_dev->block_shift; thislen = 0; @@ -2196,7 +2205,10 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, lba_start += sgl[j].length >> virt_dev->block_shift; } - atomic_set(&blockio_work->bios_inflight, bios); + + /* +1 to prevent erroneous too early command completion */ + atomic_set(&blockio_work->bios_inflight, bios+1); + smp_mb(); while (hbio) { bio = hbio; @@ -2208,6 +2220,8 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr, if (q && q->unplug_fn) q->unplug_fn(q); + blockio_check_finish(blockio_work); + out: TRACE_EXIT(); return; diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 60114a7df..c474ae712 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -1486,9 +1486,8 @@ static int __init init_scst(void) if (scst_threads == 0) scst_threads = scst_num_cpus; - if (scst_threads < scst_num_cpus) { - PRINT_ERROR("%s", "scst_threads can not be less than " - "CPUs count"); + if (scst_threads < 1) { + PRINT_ERROR("%s", "scst_threads can not be less than 1"); scst_threads = scst_num_cpus; } diff --git a/scstadmin/init.d/scst b/scstadmin/init.d/scst index 62cd796b8..98e61e1a3 100755 --- a/scstadmin/init.d/scst +++ b/scstadmin/init.d/scst @@ -5,7 +5,7 @@ SCST_CMD=/usr/local/sbin/scstadmin SCST_CFG=/etc/scst.conf # Modules to load/unload -SCST_MODULES="scst_vdisk scst_disk scst_cdrom" +SCST_MODULES="qla2x00tgt scst_vdisk scst_disk" OPTIONS="" @@ -13,9 +13,7 @@ test -x $SCST_CMD -a -f $SCST_CFG || exit 0 case "$1" in start) - echo -n "Loading and configuring SCSI Target Mid-level: scst " - - modprobe qla2x00tgt || { echo "[qla2x00tgt failed]" ; exit 1 ; } + echo -n "Loading and configuring SCSI Target Mid-level SCST " for module in ${SCST_MODULES}; do modprobe ${module} || { echo "[${module} failed]" ; exit 1 ; } @@ -33,13 +31,12 @@ case "$1" in echo "." ;; stop) - echo -n "Stopping SCSI Target Mid-level: scst " + echo -n "Stopping SCSI Target Mid-level SCST " for module in ${SCST_MODULES}; do rmmod ${module} || { echo "[${module} failed]" ; } done - rmmod qla2x00tgt || { echo "[qla2x00tgt failed]" ; } rmmod scst || { echo "[scst failed]" ; } echo "." @@ -50,7 +47,7 @@ case "$1" in $0 start ;; reload-config) - echo -n "Reloading configuration: scst " + echo -n "Reloading SCST configuration " $SCST_CMD -config $SCST_CFG diff --git a/scstadmin/scst.conf b/scstadmin/scst.conf deleted file mode 100644 index eb71ff51f..000000000 --- a/scstadmin/scst.conf +++ /dev/null @@ -1,51 +0,0 @@ -# SCST Configurator v0.2 - -# Handler devices -[HANDLER disk] -# DEVICE - -[HANDLER disk_fileio] -# DEVICE ,,, -DEVICE DISK01,/tmp/test1.dsk,READ_ONLY|WRITE_THROUGH -DEVICE DISK02,/tmp/test2.dsk -DEVICE DISK03,/tmp/test3.dsk,O_DIRECT -DEVICE DISK04,/tmp/test4.dsk,,512 - -[HANDLER disk_perf] - -[HANDLER cdrom] -# DEVICE - -[HANDLER changer] -# DEVICE - -[HANDLER modisk] -# DEVICE - -[HANDLER modisk_perf] - -[HANDLER tape] -# DEVICE - -[HANDLER tape_perf] - -# Security Group -[GROUP Test] -# USER -USER 50060b000001369d - -# Device Assignments -[ASSIGNMENT Test] -# DEVICE , -DEVICE DISK01,0 -DEVICE DISK02,1 -DEVICE DISK03 - -# Target to enable -[TARGETS enable] -HOST 50:06:0B:00:00:39:71:78 -HOST host4 - -# Targets to disable -[TARGETS disable] -HOST host5