scst_vdisk: enable bind_alua_state for fileio devices

Wire the on_alua_state_change_{start,finish} callbacks into
vdisk_file_devtype and expose bind_alua_state as a sysfs attribute
and create-time parameter for fileio. The callback bodies were
already backing-agnostic; rename them from blockio_* to vdev_* to
match.

Default bind_alua_state=0 for fileio (vs. 1 for blockio) to preserve
existing behavior on upgrade. Adjust the sysfs show function to
compare against the per-backing default so scstadmin persists
explicit settings correctly.
This commit is contained in:
Brian M
2026-05-14 10:11:39 -07:00
committed by Gleb Chesnokov
parent c259c7abb8
commit e2c57de2d5
3 changed files with 54 additions and 35 deletions

View File

@@ -1273,24 +1273,29 @@ blocksize, nv_cache, read_only, removable, rotational, thin_provisioned,
tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See
vdisk_fileio above for description of those parameters.
vdisk_blockio devices have the following two additional attributes:
vdisk_fileio and vdisk_blockio devices have the following two additional
attributes:
- active - if this flag is set (the default), the backing block device
- active - if this flag is set (the default), the backing device or file
will be opened when the SCST device is added/opened. If a SCST device
is opened with active=0 then the backing block device will not be
is opened with active=0 then the backing device or file will not be
opened, allowing for an active/passive SCST configuration. In addition,
this attribute is writable via sysfs allowing the user to open/close the
backing block device on the fly, or via a script.
backing device or file on the fly, or via a script.
- bind_alua_state - if this flag is set (the default), when the device is
associated with an ALUA device group, and a target group ALUA state
changes to the active/nonoptimized state, the active attribute will be
set to 1 which attempts to open the backing block device. If the target
group ALUA state changes to a value other than active/nonoptimized, the
backing device will be closed (active=0). If bind_alua_state=0 for a
- bind_alua_state - if this flag is set, when the device is associated
with an ALUA device group, and a target group ALUA state changes to
the active/optimized or active/nonoptimized state, the active attribute
will be set to 1 which attempts to open the backing device or file. If
the target group ALUA state changes to any other value, the backing
device or file will be closed (active=0). If bind_alua_state=0 for a
device the ALUA state changes have NO effect on the active attribute,
it is left up to the user to use a script, or manually set the active
attribute to open/close the backing block device.
attribute to open/close the backing device or file.
The default differs by backing type: vdisk_blockio defaults to
bind_alua_state=1, vdisk_fileio defaults to bind_alua_state=0
(preserves the historical fileio behavior on upgrade).
Handler vdisk_nullio provides NULLIO mode to create virtual devices. In
this mode no real I/O is done, but success returned to initiators.
@@ -1768,14 +1773,14 @@ DEVICE_GROUP dgroup2 {
}
}
Note, if you are using "active" BLOCKIO device attribute to prevent open
of the backend block device on the passive node, it is not recommended
to set both active ("active", "nonoptimized") and passive ("standby",
etc.) ALUA states for the same device if "bind_alua_state=1" is used, as
shown above to keep internal "active" state of the BLOCKIO device consistent.
Note, if you are using the "active" device attribute to prevent open of
the backend device or file on the passive node, it is not recommended to
set both active ("active", "nonoptimized") and passive ("standby", etc.)
ALUA states for the same device if "bind_alua_state=1" is used, as shown
above to keep the internal "active" state of the device consistent.
If using the "active" BLOCKIO device attribute and multiple target groups
exist per device on a SCST instance then "bind_alua_state=0" should be used
If using the "active" device attribute and multiple target groups exist
per device on a SCST instance then "bind_alua_state=0" should be used
and it is left up to the user to modify the "active" attribute value.
Explicit ALUA
@@ -1795,20 +1800,22 @@ DRBD as well as other replication/failover SW does not allow to open its
device on the secondary as well as does not allow to perform primary to
secondary transition, if this device is open.
SCST BLOCKIO handler has necessary support for such behavior:
SCST BLOCKIO and FILEIO handlers have necessary support for such behavior:
1. If you need to prevent an SCST BLOCKIO device from opening its block
device, you need to create it with parameter "active=0". In case of DRBD
1. If you need to prevent an SCST device from opening its backing device
or file, you need to create it with parameter "active=0". In case of DRBD
it would be done automatically, you don't have to use the "active"
attribute.
2. By default, if you write new ALUA state in the "state" attribute and
"bind_alua_state=1" for the device, SCST BLOCKIO handler before transition
2. If you write new ALUA state in the "state" attribute and
"bind_alua_state=1" for the device, the SCST handler before transition
closes open handles on all affected SCST devices and after transition
reopens them, if the new state is active or nonoptimized. Alternatively,
set "bind_alua_state=0" for SCST BLOCKIO devices and ALUA state changes
will not open/close the backing block device, the user will need to handle
this manually or via a cluster RA in an HA setup.
set "bind_alua_state=0" for SCST devices and ALUA state changes will not
open/close the backing device or file; the user will need to handle this
manually or via a cluster RA in an HA setup. Note that BLOCKIO defaults
to "bind_alua_state=1" while FILEIO defaults to "bind_alua_state=0";
enable it explicitly on FILEIO devices that should participate.
Thus, the recommended implicit ALUA state change procedure for primary
to secondary transition is:

View File

@@ -6217,9 +6217,9 @@ 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)
static void vdev_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;
const bool close = virt_dev->dev_active &&
@@ -6246,9 +6246,9 @@ static void blockio_on_alua_state_change_start(struct scst_device *dev,
TRACE_EXIT();
}
static void blockio_on_alua_state_change_finish(struct scst_device *dev,
enum scst_tg_state old_state,
enum scst_tg_state new_state)
static void vdev_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;
const bool open = !virt_dev->dev_active &&
@@ -7052,6 +7052,8 @@ static int vdev_fileio_add_device(const char *device_name, char *params)
virt_dev->wt_flag = DEF_WRITE_THROUGH;
virt_dev->nv_cache = DEF_NV_CACHE;
virt_dev->o_direct_flag = DEF_O_DIRECT;
/* Opt-in for fileio; preserves pre-existing behavior on upgrade. */
virt_dev->bind_alua_state = 0;
res = vdev_parse_add_dev_params(virt_dev, params, NULL);
if (res != 0)
@@ -9263,7 +9265,12 @@ static ssize_t vdev_sysfs_bind_alua_state_show(struct kobject *kobj,
ret = sysfs_emit(buf, "%d\n", bind_alua_state);
if (bind_alua_state != DEF_BIND_ALUA_STATE)
/*
* Per-backing default: blockio defaults to 1 (close/reopen FD on ALUA
* state change), fileio defaults to 0 (opt-in). Mark non-default so
* scstadmin knows to persist explicit settings.
*/
if (bind_alua_state != (virt_dev->blockio ? 1 : 0))
ret += sysfs_emit_at(buf, ret, "%s\n", SCST_SYSFS_KEY_MARK);
TRACE_EXIT_RES(ret);
@@ -9502,6 +9509,7 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = {
static const struct attribute *vdisk_fileio_attrs[] = {
&vdev_active_attr.attr,
&vdev_bind_alua_state_attr.attr,
&vdev_size_ro_attr.attr,
&vdev_size_mb_ro_attr.attr,
&vdisk_blocksize_attr.attr,
@@ -9537,6 +9545,7 @@ static const struct attribute *vdisk_fileio_attrs[] = {
static const char *const fileio_add_dev_params[] = {
"active",
"async",
"bind_alua_state",
"blocksize",
"cluster_mode",
"dif_filename",
@@ -9576,6 +9585,8 @@ static struct scst_dev_type vdisk_file_devtype = {
.parse = fileio_parse,
.exec = fileio_exec,
.on_free_cmd = fileio_on_free_cmd,
.on_alua_state_change_start = vdev_on_alua_state_change_start,
.on_alua_state_change_finish = vdev_on_alua_state_change_finish,
.task_mgmt_fn_done = vdisk_task_mgmt_fn_done,
#ifdef CONFIG_DEBUG_EXT_COPY_REMAP
.ext_copy_remap = vdev_ext_copy_remap,
@@ -9662,8 +9673,8 @@ static struct scst_dev_type vdisk_blk_devtype = {
.detach_tgt = vdisk_detach_tgt,
.parse = non_fileio_parse,
.exec = blockio_exec,
.on_alua_state_change_start = blockio_on_alua_state_change_start,
.on_alua_state_change_finish = blockio_on_alua_state_change_finish,
.on_alua_state_change_start = vdev_on_alua_state_change_start,
.on_alua_state_change_finish = vdev_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,

View File

@@ -393,6 +393,7 @@ Collecting current configuration: done.
Device CREATE attributes available
----------------------------------
async
bind_alua_state
blocksize
cluster_mode
dif_filename