diff --git a/scst/README b/scst/README index 0226eb2a6..631d1ff35 100644 --- a/scst/README +++ b/scst/README @@ -883,6 +883,9 @@ cache. The following parameters possible for vdisk_fileio: - removable - with this flag set the device is reported to remote initiators as removable. + - rotational - if set, this device reported as rotational. Otherwise, + it is reported as non-ratational (SSD, etc.) + Handler vdisk_blockio provides BLOCKIO mode to create virtual devices. This mode performs direct block I/O with a block device, bypassing the page cache for all operations. This mode works ideally with high-end @@ -891,8 +894,8 @@ between application and disk or need the large block throughput. See below for more info. The following parameters possible for vdisk_blockio: filename, -blocksize, nv_cache, read_only, removable, thin_provisioned. See -vdisk_fileio above for description of those parameters. +blocksize, nv_cache, read_only, removable, rotational, thin_provisioned. +See vdisk_fileio above for description of those parameters. Handler vdisk_nullio provides NULLIO mode to create virtual devices. In this mode no real I/O is done, but success returned to initiators. @@ -928,10 +931,12 @@ Each vdisk_fileio's device has the following attributes in - nv_cache - contains NV_CACHE status of this virtual device. - thin_provisioned - contains thin provisioning status of this virtual - device + device. - removable - contains removable status of this virtual device. + - rotational - contains rotational status of this virtual device. + - size_mb - contains size of this virtual device in MB. - t10_dev_id - contains and allows to set T10 vendor specific @@ -969,6 +974,7 @@ For example: |-- read_only |-- removable |-- resync_size +|-- rotational |-- size_mb |-- t10_dev_id |-- thin_provisioned @@ -980,7 +986,7 @@ For example: Each vdisk_blockio's device has the following attributes in /sys/kernel/scst_tgt/devices/device_name: blocksize, filename, nv_cache, -read_only, removable, resync_size, size_mb, t10_dev_id, +read_only, removable, resync_size, rotational, size_mb, t10_dev_id, thin_provisioned, threads_num, threads_pool_type, type, usn. See above description of those parameters. diff --git a/scst/README_in-tree b/scst/README_in-tree index 5b3ffed17..a9e8f60cf 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -747,6 +747,9 @@ cache. The following parameters possible for vdisk_fileio: - removable - with this flag set the device is reported to remote initiators as removable. + - rotational - if set, this device reported as rotational. Otherwise, + it is reported as non-ratational (SSD, etc.) + Handler vdisk_blockio provides BLOCKIO mode to create virtual devices. This mode performs direct block I/O with a block device, bypassing the page cache for all operations. This mode works ideally with high-end @@ -755,8 +758,8 @@ between application and disk or need the large block throughput. See below for more info. The following parameters possible for vdisk_blockio: filename, -blocksize, nv_cache, read_only, removable, thin_provisioned. See -vdisk_fileio above for description of those parameters. +blocksize, nv_cache, read_only, removable, rotational, thin_provisioned. +See vdisk_fileio above for description of those parameters. Handler vdisk_nullio provides NULLIO mode to create virtual devices. In this mode no real I/O is done, but success returned to initiators. @@ -792,10 +795,12 @@ Each vdisk_fileio's device has the following attributes in - nv_cache - contains NV_CACHE status of this virtual device. - thin_provisioned - contains thin provisioning status of this virtual - device + device. - removable - contains removable status of this virtual device. + - rotational - contains rotational status of this virtual device. + - size_mb - contains size of this virtual device in MB. - t10_dev_id - contains and allows to set T10 vendor specific @@ -831,6 +836,7 @@ For example: |-- read_only |-- removable |-- resync_size +|-- rotational |-- size_mb |-- t10_dev_id |-- thin_provisioned @@ -842,7 +848,7 @@ For example: Each vdisk_blockio's device has the following attributes in /sys/kernel/scst_tgt/devices/device_name: blocksize, filename, nv_cache, -read_only, removable, resync_size, size_mb, t10_dev_id, +read_only, removable, resync_size, rotational, size_mb, t10_dev_id, thin_provisioned, threads_num, threads_pool_type, type, usn. See above description of those parameters. diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 679593a50..1c1eec304 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -105,6 +105,7 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = { #define DEF_NV_CACHE 0 #define DEF_O_DIRECT 0 #define DEF_REMOVABLE 0 +#define DEF_ROTATIONAL 1 #define DEF_THIN_PROVISIONED 0 #define VDISK_NULLIO_SIZE (3LL*1024*1024*1024*1024/2) @@ -156,7 +157,7 @@ struct scst_vdisk_dev { unsigned int thin_provisioned:1; unsigned int thin_provisioned_manually_set:1; unsigned int dev_thin_provisioned:1; - + unsigned int rotational:1; int virt_id; char name[16+1]; /* Name of the virtual device, @@ -262,6 +263,8 @@ static ssize_t vdisk_sysfs_wt_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); static ssize_t vdisk_sysfs_tp_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t vdisk_sysfs_rotational_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf); static ssize_t vdisk_sysfs_nv_cache_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); static ssize_t vdisk_sysfs_o_direct_show(struct kobject *kobj, @@ -294,6 +297,8 @@ static struct kobj_attribute vdisk_wt_attr = __ATTR(write_through, S_IRUGO, vdisk_sysfs_wt_show, NULL); static struct kobj_attribute vdisk_tp_attr = __ATTR(thin_provisioned, S_IRUGO, vdisk_sysfs_tp_show, NULL); +static struct kobj_attribute vdisk_rotational_attr = + __ATTR(rotational, S_IRUGO, vdisk_sysfs_rotational_show, NULL); static struct kobj_attribute vdisk_nv_cache_attr = __ATTR(nv_cache, S_IRUGO, vdisk_sysfs_nv_cache_show, NULL); static struct kobj_attribute vdisk_o_direct_attr = @@ -320,6 +325,7 @@ static const struct attribute *vdisk_fileio_attrs[] = { &vdisk_rd_only_attr.attr, &vdisk_wt_attr.attr, &vdisk_tp_attr.attr, + &vdisk_rotational_attr.attr, &vdisk_nv_cache_attr.attr, &vdisk_o_direct_attr.attr, &vdisk_removable_attr.attr, @@ -336,6 +342,7 @@ static const struct attribute *vdisk_blockio_attrs[] = { &vdisk_rd_only_attr.attr, &vdisk_nv_cache_attr.attr, &vdisk_removable_attr.attr, + &vdisk_rotational_attr.attr, &vdisk_filename_attr.attr, &vdisk_resync_size_attr.attr, &vdev_t10_dev_id_attr.attr, @@ -351,6 +358,7 @@ static const struct attribute *vdisk_nullio_attrs[] = { &vdisk_removable_attr.attr, &vdev_t10_dev_id_attr.attr, &vdev_usn_attr.attr, + &vdisk_rotational_attr.attr, NULL, }; @@ -402,7 +410,8 @@ static struct scst_dev_type vdisk_file_devtype = { .del_device = vdisk_del_device, .dev_attrs = vdisk_fileio_attrs, .add_device_parameters = "filename, blocksize, write_through, " - "nv_cache, o_direct, read_only, removable, thin_provisioned", + "nv_cache, o_direct, read_only, removable, rotational, " + "thin_provisioned", #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -437,7 +446,7 @@ static struct scst_dev_type vdisk_blk_devtype = { .del_device = vdisk_del_device, .dev_attrs = vdisk_blockio_attrs, .add_device_parameters = "filename, blocksize, nv_cache, read_only, " - "removable, thin_provisioned", + "removable, rotational, thin_provisioned", #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -469,7 +478,7 @@ static struct scst_dev_type vdisk_null_devtype = { .add_device = vdisk_add_nullio_device, .del_device = vdisk_del_device, .dev_attrs = vdisk_nullio_attrs, - .add_device_parameters = "blocksize, read_only, removable", + .add_device_parameters = "blocksize, read_only, removable, rotational", #endif #if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) .default_trace_flags = SCST_DEFAULT_DEV_LOG_FLAGS, @@ -1486,11 +1495,12 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd) buf[5] = 0x80; /* unit serial number */ buf[6] = 0x83; /* device identification */ if (virt_dev->dev->type == TYPE_DISK) { - buf[3] += 1; + buf[3] += 2; buf[7] = 0xB0; /* block limits */ + buf[8] = 0xB1; /* block limits */ if (virt_dev->thin_provisioned) { buf[3] += 1; - buf[8] = 0xB2; /* thin provisioning */ + buf[9] = 0xB2; /* thin provisioning */ } } resp_len = buf[3] + 4; @@ -1649,6 +1659,18 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd) } } resp_len = buf[3] + 4; + } else if ((0xB1 == cmd->cdb[2]) && + (virt_dev->dev->type == TYPE_DISK)) { + /* Block Device Characteristics */ + buf[1] = 0xB1; + buf[3] = 0x3C; + if (virt_dev->rotational) { + /* 15K RPM */ + put_unaligned(cpu_to_be16(0x3A98), + (uint16_t *)&buf[4]); + } else + put_unaligned(cpu_to_be16(1), (uint16_t *)&buf[4]); + resp_len = buf[3] + 4; } else if ((0xB2 == cmd->cdb[2]) && (virt_dev->dev->type == TYPE_DISK) && virt_dev->thin_provisioned) { @@ -3364,6 +3386,10 @@ static void vdisk_report_registering(const struct scst_vdisk_dev *virt_dev) i += snprintf(&buf[i], sizeof(buf) - i, "%sREMOVABLE", (j == i) ? "(" : ", "); + if (virt_dev->rotational) + i += snprintf(&buf[i], sizeof(buf) - i, "%sROTATIONAL", + (j == i) ? "(" : ", "); + if (virt_dev->thin_provisioned) i += snprintf(&buf[i], sizeof(buf) - i, "%sTHIN PROVISIONED", (j == i) ? "(" : ", "); @@ -3440,6 +3466,7 @@ static int vdev_create(struct scst_dev_type *devt, virt_dev->rd_only = DEF_RD_ONLY; virt_dev->removable = DEF_REMOVABLE; + virt_dev->rotational = DEF_ROTATIONAL; virt_dev->thin_provisioned = DEF_THIN_PROVISIONED; virt_dev->block_size = DEF_DISK_BLOCKSIZE; @@ -3603,6 +3630,9 @@ static int vdev_parse_add_dev_params(struct scst_vdisk_dev *virt_dev, } else if (!strcasecmp("removable", p)) { virt_dev->removable = val; TRACE_DBG("REMOVABLE %d", virt_dev->removable); + } else if (!strcasecmp("rotational", p)) { + virt_dev->rotational = val; + TRACE_DBG("ROTATIONAL %d", virt_dev->rotational); } else if (!strcasecmp("thin_provisioned", p)) { virt_dev->thin_provisioned = val; virt_dev->thin_provisioned_manually_set = 1; @@ -3698,7 +3728,7 @@ static int vdev_blockio_add_device(const char *device_name, char *params) { int res = 0; const char *allowed_params[] = { "filename", "read_only", "removable", - "blocksize", "nv_cache", + "blocksize", "nv_cache", "rotational", "thin_provisioned", NULL }; struct scst_vdisk_dev *virt_dev; @@ -3753,7 +3783,7 @@ static int vdev_nullio_add_device(const char *device_name, char *params) { int res = 0; const char *allowed_params[] = { "read_only", "removable", - "blocksize", NULL }; + "blocksize", "rotational", NULL }; struct scst_vdisk_dev *virt_dev; TRACE_ENTRY(); @@ -4355,6 +4385,27 @@ static ssize_t vdisk_sysfs_removable_show(struct kobject *kobj, return pos; } +static ssize_t vdisk_sysfs_rotational_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + int pos = 0; + struct scst_device *dev; + struct scst_vdisk_dev *virt_dev; + + TRACE_ENTRY(); + + dev = container_of(kobj, struct scst_device, dev_kobj); + virt_dev = dev->dh_priv; + + pos = sprintf(buf, "%d\n", virt_dev->rotational ? 1 : 0); + + if (virt_dev->rotational != DEF_ROTATIONAL) + pos += sprintf(&buf[pos], "%s\n", SCST_SYSFS_KEY_MARK); + + TRACE_EXIT_RES(pos); + return pos; +} + static int vdev_sysfs_process_get_filename(struct scst_sysfs_work_item *work) { int res = 0;