diff --git a/scst/include/scst.h b/scst/include/scst.h index 8bbe8093b..a3453f0e9 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -1401,34 +1401,6 @@ struct scst_dev_type { void (*ext_copy_remap)(struct scst_cmd *cmd, struct scst_ext_copy_seg_descr *descr); - /* - * Called to notify dev handler that a ALUA state change is about to - * be started. Can be used to close open file handlers, which might - * prevent the state switch. - * - * Called under scst_dg_mutex and no activities on the dev handler level - * (for implicit ALUA case supposed to be done by the user space via - * "block" sysfs attribute as described in the README). - * - * OPTIONAL - */ - void (*on_alua_state_change_start)(struct scst_device *dev, - enum scst_tg_state old_state, enum scst_tg_state new_state); - - /* - * Called to notify dev handler that a ALUA state change is about to - * be finished. Can be used to (re)open file handlers closed in - * on_alua_state_change_start(). - * - * Called under scst_dg_mutex and no activities on the dev handler level - * (for implicit ALUA case supposed to be done by the user space via - * "block" sysfs attribute as described in the README). - * - * OPTIONAL - */ - void (*on_alua_state_change_finish)(struct scst_device *dev, - enum scst_tg_state old_state, enum scst_tg_state new_state); - /* * Called to notify dev handler that a task management command received * diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 31a3b3062..79a6eb4d9 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -3310,14 +3310,6 @@ static enum compl_status_e fileio_exec_async(struct vdisk_cmd_params *p) } #endif -static void blockio_on_free_cmd(struct scst_cmd *cmd) -{ - if (!scst_cmd_get_dh_data_buff_alloced(cmd)) - return; - sgv_pool_free(cmd->sgv, &cmd->dev->dev_mem_lim); - cmd->sgv = NULL; -} - static void vdisk_on_free_cmd_params(const struct vdisk_cmd_params *p) { if (!p->execute_async) { @@ -3409,29 +3401,6 @@ out: return res; } -static int blockio_alloc(struct scst_cmd *cmd) -{ - struct scst_tgt_dev *tgt_dev = cmd->tgt_dev; - struct sgv_pool *pool = tgt_dev->pools[raw_smp_processor_id()]; - int res = SCST_CMD_STATE_DEFAULT; - - if (cmd->sg && (cmd->sg->offset & 511) == 0) - return res; - - WARN_ON_ONCE(cmd->sgv); - cmd->sg = sgv_pool_alloc(pool, cmd->bufflen, cmd->cmd_gfp_mask, 0, - &cmd->sg_cnt, &cmd->sgv, - &cmd->dev->dev_mem_lim, NULL); - if (!cmd->sg) { - res = SCST_CMD_STATE_STOP; - goto out; - } - scst_cmd_set_dh_data_buff_alloced(cmd); - -out: - return res; -} - static enum scst_exec_res blockio_exec(struct scst_cmd *cmd) { struct scst_vdisk_dev *virt_dev = cmd->dev->dh_priv; @@ -6477,91 +6446,6 @@ static enum compl_status_e nullio_exec_verify(struct vdisk_cmd_params *p) return CMD_SUCCEEDED; } -static void blockio_on_alua_state_change_start(struct scst_device *dev, - enum scst_tg_state old_state, enum scst_tg_state new_state) -{ - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - - TRACE_ENTRY(); - - lockdep_assert_alua_lock_held(); - - if (!virt_dev->bind_alua_state) - return; - - /* - * As required for on_alua_state_change_* callbacks, - * no parallel fd activities could be here. - */ - - TRACE_MGMT_DBG("ALUA state change from %s to %s started, closing FD (dev %s, active %d)", - scst_alua_state_name(old_state), scst_alua_state_name(new_state), - dev->virt_name, virt_dev->dev_active); - - virt_dev->dev_active = 0; - - /* Just in case always close */ - vdisk_close_fd(virt_dev); - - TRACE_EXIT(); - return; -} - -static void blockio_on_alua_state_change_finish(struct scst_device *dev, - enum scst_tg_state old_state, enum scst_tg_state new_state) -{ - struct scst_vdisk_dev *virt_dev = dev->dh_priv; - - TRACE_ENTRY(); - - lockdep_assert_alua_lock_held(); - - if (!virt_dev->bind_alua_state) - return; - - /* - * As required for on_alua_state_change_* callbacks, - * no parallel fd activities could be here. - */ - - if (((new_state == SCST_TG_STATE_OPTIMIZED) || - (new_state == SCST_TG_STATE_NONOPTIMIZED)) && (virt_dev->fd == NULL)) { - /* Try non-optimized as well, it might be new redirection device */ - int rc = 0; - - TRACE_MGMT_DBG("ALUA state change from %s to %s finished (dev %s, active %d), " - "reopening FD", scst_alua_state_name(old_state), - scst_alua_state_name(new_state), dev->virt_name, virt_dev->dev_active); - - virt_dev->dev_active = 1; - - /* - * only reopen fd if tgt_dev_cnt is not zero, otherwise we will - * leak reference. - */ - if (virt_dev->tgt_dev_cnt) - rc = vdisk_open_fd(virt_dev, dev->dev_rd_only); - - if (rc == 0) { - if (virt_dev->reexam_pending) { - rc = vdisk_reexamine(virt_dev); - WARN_ON(rc != 0); - virt_dev->reexam_pending = 0; - } - } else { - PRINT_ERROR("Unable to open fd on ALUA state change " - "to %s (dev %s)", dev->virt_name, - scst_alua_state_name(new_state)); - } - } else - TRACE_DBG("ALUA state change from %s to %s finished (dev %s)", - scst_alua_state_name(old_state), scst_alua_state_name(new_state), - dev->virt_name); - - TRACE_EXIT(); - return; -} - static void vdisk_task_mgmt_fn_done(struct scst_mgmt_cmd *mcmd, struct scst_tgt_dev *tgt_dev) { @@ -9437,10 +9321,7 @@ static int vdev_sysfs_process_active_store( res = mutex_lock_interruptible(&scst_mutex); if (res) goto resume; - /* - * This is used to serialize against the *_on_alua_state_change_*() - * calls in scst_tg.c - */ + /* To do: verify whether this call is still necessary. */ scst_alua_lock(); /* @@ -9921,11 +9802,7 @@ static struct scst_dev_type vdisk_blk_devtype = { .attach_tgt = vdisk_attach_tgt, .detach_tgt = vdisk_detach_tgt, .parse = non_fileio_parse, - .dev_alloc_data_buf = blockio_alloc, .exec = blockio_exec, - .on_free_cmd = blockio_on_free_cmd, - .on_alua_state_change_start = blockio_on_alua_state_change_start, - .on_alua_state_change_finish = blockio_on_alua_state_change_finish, .task_mgmt_fn_done = vdisk_task_mgmt_fn_done, .get_supported_opcodes = vdisk_get_supported_opcodes, .devt_priv = (void *)blockio_ops, diff --git a/scst/src/scst_tg.c b/scst/src/scst_tg.c index 8b6b1a6f6..b316ac184 100644 --- a/scst/src/scst_tg.c +++ b/scst/src/scst_tg.c @@ -976,8 +976,6 @@ static void __scst_tg_set_state(struct scst_target_group *tg, struct scst_tgt_dev *tgt_dev; struct scst_tg_tgt *tg_tgt; struct scst_tgt *tgt; - enum scst_tg_state old_state = tg->state; - bool dev_changed; sBUG_ON(state >= ARRAY_SIZE(scst_alua_filter)); lockdep_assert_held(&scst_dg_mutex); @@ -989,11 +987,6 @@ static void __scst_tg_set_state(struct scst_target_group *tg, list_for_each_entry(dg_dev, &tg->dg->dev_list, entry) { dev = dg_dev->dev; - dev_changed = false; - if ((dev->handler->on_alua_state_change_start != NULL) && !dev_changed) { - dev->handler->on_alua_state_change_start(dev, old_state, state); - dev_changed = true; - } list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list, dev_tgt_dev_list_entry) { tgt = tgt_dev->sess->tgt; @@ -1010,8 +1003,6 @@ static void __scst_tg_set_state(struct scst_target_group *tg, } } } - if ((dev->handler->on_alua_state_change_finish != NULL) && dev_changed) - dev->handler->on_alua_state_change_finish(dev, old_state, state); } scst_check_alua_invariant(); diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm index 7419e7ccf..453a82e69 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/lib/SCST/SCST.pm @@ -513,11 +513,22 @@ sub scstAttributes { return (\%attributes, undef); } -sub setAttrFailed { - my $path = shift; - my $no_such_attr = shift; - my $is_static = shift; +# Convert e.g. EINVAL into "EINVAL". +sub my_strerror { + my ($errorcode) = @_; + return $errorcode if (!defined($errorcode)); + for my $errstr (keys(%!)) { + my $err = eval($errstr); + return $errstr if (defined($err) and $err == $errorcode); + } + return $errorcode; +} + +sub setAttrFailed { + my ($path, $bytes, $no_such_attr, $is_static) = @_; + + print STDERR "(" . my_strerror(-$bytes) . ") "; return (-f $path) && (-r $path) ? $is_static : $no_such_attr; } @@ -528,19 +539,19 @@ sub setScstAttribute { return TRUE if (!defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_ROOT_DIR(), $attribute); my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } - return setAttrFailed($path, SCST_C_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_BAD_ATTRIBUTES, SCST_C_ATTRIBUTE_STATIC); } @@ -1042,16 +1053,16 @@ sub addDriverDynamicAttribute { } $cmd .= "add_attribute $attribute $value"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1085,16 +1096,16 @@ sub removeDriverDynamicAttribute { } $cmd .= "del_attribute $attribute $value"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1192,16 +1203,16 @@ sub addVirtualTarget { } $cmd .= "add_target $target $o_string"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1327,16 +1338,16 @@ sub addTargetDynamicAttribute { } $cmd .= "add_target_attribute $target $attribute $value"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1376,16 +1387,16 @@ sub removeTargetDynamicAttribute { } $cmd .= "del_target_attribute $target $attribute $value"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1453,16 +1464,16 @@ sub removeVirtualTarget { } $cmd .= "del_target $target"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1586,16 +1597,16 @@ sub addGroup { } $cmd .= "create $group"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1633,16 +1644,16 @@ sub removeGroup { } $cmd .= "del $group"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -1675,16 +1686,16 @@ sub addDeviceGroup { } $cmd .= "create $group"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1707,16 +1718,16 @@ sub removeDeviceGroup { } $cmd .= "del $group"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1745,16 +1756,16 @@ sub addDeviceGroupDevice { } $cmd .= "add $device"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1801,16 +1812,16 @@ sub addTargetGroup { } $cmd .= "add $tgroup"; + my $bytes = -ENONENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1843,16 +1854,16 @@ sub addTargetGroupTarget { } $cmd .= "add $tgt"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1884,16 +1895,16 @@ sub removeDeviceGroupDevice { } $cmd .= "del $device"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1928,16 +1939,16 @@ sub removeTargetGroup { } $cmd .= "del $tgroup"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -1970,16 +1981,16 @@ sub removeTargetGroupTarget { } $cmd .= "del $tgt"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -2021,16 +2032,16 @@ sub addInitiator { } $cmd .= "add $initiator"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } return SCST_C_GRP_REM_INI_FAIL if (!defined($driver) || @@ -2078,16 +2089,16 @@ sub removeInitiator { } $cmd .= "del $initiator"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -2130,16 +2141,16 @@ sub moveInitiator { } $cmd .= "move $initiator $to"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -2188,16 +2199,16 @@ sub clearInitiators { } $cmd .= "clear"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -2263,16 +2274,16 @@ sub addLun { $cmd .= "add $device $lun $o_string"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } if (defined($group)) { @@ -2341,16 +2352,16 @@ sub removeLun { } $cmd .= "del $lun"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -2453,16 +2464,16 @@ sub replaceLun { } $cmd .= "replace $device $lun $o_string"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } return SCST_C_LUN_RPL_DEV_FAIL; @@ -2502,16 +2513,16 @@ sub clearLuns { } $cmd .= "clear"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -2836,23 +2847,23 @@ sub setDriverAttribute { my $path = make_path(SCST_TARGETS_DIR(), $driver, $attribute); + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); return SCST_C_DRV_NO_DRIVER if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_DRV_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_DRV_BAD_ATTRIBUTES, SCST_C_DRV_ATTRIBUTE_STATIC); } @@ -2984,16 +2995,16 @@ sub setTargetAttribute { $cmd = $value; } + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd > $path\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -3004,7 +3015,7 @@ sub setTargetAttribute { return SCST_C_TGT_NO_TARGET if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_TGT_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_TGT_BAD_ATTRIBUTES, SCST_C_TGT_ATTRIBUTE_STATIC); } @@ -3118,16 +3129,16 @@ sub setGroupAttribute { } $cmd .= $value; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd > $path\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -3142,7 +3153,7 @@ sub setGroupAttribute { return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_GRP_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_GRP_BAD_ATTRIBUTES, SCST_C_GRP_ATTRIBUTE_STATIC); } @@ -3278,16 +3289,16 @@ sub setLunAttribute { SCST_LUNS, $lun, $attribute); } + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -3421,16 +3432,16 @@ sub setInitiatorAttribute { my $path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_LUNS, $initiator, $attribute); + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->driverExists($driver); @@ -3708,20 +3719,20 @@ sub setAluaAttribute { return TRUE if (!defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_DEV_GROUP_DIR(), $attribute); my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $value > $path\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } - return setAttrFailed($path, SCST_C_ALUA_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_ALUA_BAD_ATTRIBUTES, SCST_C_ALUA_ATTRIBUTE_STATIC); } @@ -3733,25 +3744,24 @@ sub setDeviceGroupAttribute { return TRUE if (!defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_DEV_GROUP_DIR(), $group, $attribute); - my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); return SCST_C_DEV_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_DGRP_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_DGRP_BAD_ATTRIBUTES, SCST_C_DGRP_ATTRIBUTE_STATIC); } @@ -3765,18 +3775,17 @@ sub setTargetGroupAttribute { return TRUE if (!defined($group) || !defined($tgroup) || !defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $attribute); - my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -3787,7 +3796,7 @@ sub setTargetGroupAttribute { return SCST_C_DGRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_TGRP_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_TGRP_BAD_ATTRIBUTES, SCST_C_TGRP_ATTRIBUTE_STATIC); } @@ -3803,19 +3812,18 @@ sub setTargetGroupTargetAttribute { !defined($tgt) || !defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $tgt, $attribute); - my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceGroupExists($group); @@ -3830,7 +3838,7 @@ sub setTargetGroupTargetAttribute { return SCST_C_TGRP_NO_TGT if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_TGRP_TGT_BAD_ATTR, + return setAttrFailed($path, $bytes, SCST_C_TGRP_TGT_BAD_ATTR, SCST_C_TGRP_TGT_ATTR_STATIC); } @@ -3884,24 +3892,24 @@ sub setHandlerAttribute { return TRUE if (!defined($attribute) || !defined($value)); + my $bytes = -ENOENT; my $path = make_path(SCST_HANDLERS_DIR(), $handler, $attribute); my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $path -> $attribute = $value\n"; } else { $bytes = _syswrite($io, $value, length($value)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->handlerExists($handler); return SCST_C_HND_NO_HANDLER if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_HND_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_HND_BAD_ATTRIBUTES, SCST_C_HND_ATTRIBUTE_STATIC); } @@ -4184,16 +4192,16 @@ sub openDevice { } $cmd .= "add_device $device $o_string"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $errno = $!; @@ -4232,16 +4240,16 @@ sub closeDevice { } $cmd .= "del_device $device"; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $errno = $!; @@ -4275,23 +4283,23 @@ sub setDeviceAttribute { } $cmd .= $value; + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd > $path\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } my $rc = $self->deviceOpen($device); return SCST_C_DEV_NO_DEVICE if (!$rc); return $rc if ($rc > 1); - return setAttrFailed($path, SCST_C_DEV_BAD_ATTRIBUTES, + return setAttrFailed($path, $bytes, SCST_C_DEV_BAD_ATTRIBUTES, SCST_C_DEV_ATTRIBUTE_STATIC); } @@ -4801,17 +4809,17 @@ sub closeSession { my $path = make_path(SCST_TARGETS_DIR(), $driver, $target, SCST_SESSIONS, $session, 'force_close'); + my $bytes = -ENOENT; my $io = new IO::File $path, O_WRONLY; if ($io) { my $cmd = "1"; - my $bytes; if ($self->{'debug'}) { print "DBG($$): $cmd\n"; } else { $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; - return FALSE if ($self->{'debug'} || $bytes); + return FALSE if ($self->{'debug'} || $bytes > 0); } return SCST_C_SESSION_CLOSE_FAIL; } @@ -4902,7 +4910,7 @@ sub _sysread { } # Write the first $3 bytes of $2 into the SCST sysfs file $1. Return either -# the number of bytes written or undef if writing failed. +# the number of bytes written or -errno if writing failed. sub _syswrite { my $io = shift; my $cmd = shift; @@ -4912,13 +4920,14 @@ sub _syswrite { my $res_file = SCST_QUEUE_RES_PATH(); my $bytes = syswrite($io, $cmd, $length); + $bytes = -$! if (!defined($bytes)); - if (!defined($bytes) && defined($res_file) && $! == EAGAIN) { + if (defined($res_file) && $bytes == -EAGAIN) { my $res_io = new IO::File $res_file, O_RDONLY; if (!$res_io) { cluck("FATAL: Failed opening $res_file: $!"); - return undef; + return -ENOENT; } my $res_val; diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t index 8027c5a68..a47e6e5d9 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/06-cont-on-err.t @@ -24,7 +24,7 @@ BEGIN { unless(grep /blib/, @INC) { unshift(@INC, File::Spec->catdir($scstadmin_pm_dir, "lib")); } - plan tests => 5; + plan tests => 6; } use Data::Dumper; @@ -46,12 +46,15 @@ sub testRestoreConfig { "scstadmin-test-06-$$-1"); my $tmpfilename2 = File::Spec->catfile(File::Spec->tmpdir(), "scstadmin-test-06-$$-2"); + my $scstadmin_output = File::Spec->catfile(File::Spec->tmpdir(), + "scstadmin-test-06-$$-adm-out"); my $diff = File::Spec->catfile(File::Spec->tmpdir(), "scstadmin-test-06-$$-diff"); - ok(system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"), 0); - system("$scstadmin -cont_on_err -no_lip -config $to_be_restored" . - " >/dev/null"); + ok(system("$scstadmin -clear_config -force -noprompt -no_lip $redirect"), + 0); + ok(system("$scstadmin -cont_on_err -no_lip -config $to_be_restored" . + " > " . $scstadmin_output . " 2>&1"), 256); ok(system("$scstadmin -write_config $tmpfilename1 >/dev/null"), 0); ok(system("awk 'BEGIN {t = 0 } /^# Automatically generated by SCST Configurator v/ " . '{ $0 = "# Automatically generated by SCST Configurator v..." } ' . @@ -78,6 +81,8 @@ if ($_DEBUG_) { $redirect = ">/dev/null"; } +unlink("/var/lib/scst/vdev_mode_pages/disk01"); + my $SCST = eval { new SCST::SCST($_DEBUG_) }; die("Creation of SCST object failed") if (!defined($SCST)); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index a371de229..989ed72f4 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -1230,6 +1230,7 @@ static int srpt_get_desc_tbl(struct srpt_recv_ioctx *recv_ioctx, pr_warn_once("Internal error - the receive buffers are not aligned properly.\n"); return -EINVAL; } + /* Note: this sg entry may span more than one physical page. */ sg_init_one(&ioctx->imm_sg, data, len); scst_cmd_set_tgt_sg(&ioctx->cmd, &ioctx->imm_sg, 1); return 0; @@ -3615,6 +3616,10 @@ static int srpt_xfer_data(struct srpt_rdma_ch *ch, SRPT_STATE_DATA_IN); BUG_ON(!res); WARN_ON_ONCE(!scst_cmd_get_tgt_data_buff_alloced(cmd)); + if (cmd->tgt_i_data_buf_alloced && cmd->dh_data_buf_alloced && + scst_cmd_get_data_direction(cmd) & SCST_DATA_WRITE) { + scst_copy_sg(cmd, SCST_SG_COPY_FROM_TARGET); + } scst_rx_data(cmd, SCST_RX_STATUS_SUCCESS, in_irq() ? SCST_CONTEXT_TASKLET : in_softirq() ? SCST_CONTEXT_DIRECT_ATOMIC : @@ -3760,6 +3765,10 @@ static int srpt_xmit_response(struct scst_cmd *cmd) dir = scst_cmd_get_data_direction(cmd); + if (cmd->tgt_i_data_buf_alloced && cmd->dh_data_buf_alloced && + dir & SCST_DATA_READ) + scst_copy_sg(cmd, SCST_SG_COPY_TO_TARGET); + /* For read commands, transfer the data to the initiator. */ if (dir == SCST_DATA_READ && scst_cmd_get_adjusted_resp_data_len(cmd)) {