scst: improve thin provisioning support

This patch adds gen_tp_soft_threshold_reached_UA attribute for thin
provisioned devices that allows to generate THIN PROVISIONING SOFT
THRESHOLD REACHED Unit Attention.



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7071 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2016-12-20 06:07:55 +00:00
parent 5040dd22a4
commit 4e1dc1b526
6 changed files with 97 additions and 13 deletions

View File

@@ -1246,6 +1246,11 @@ Each vdisk_fileio's device has the following attributes in
- thin_provisioned - contains thin provisioning status of this virtual
device.
- gen_tp_soft_threshold_reached_UA - for thin provisioned devices
writing of anything into this write-only attribute will generate THIN
PROVISIONING SOFT THRESHOLD REACHED Unit Attention to all connected
to this device initiators.
- removable - contains removable status of this virtual device.
- rotational - contains rotational status of this virtual device.
@@ -1347,8 +1352,9 @@ 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, rotational, size_mb, t10_dev_id,
thin_provisioned, threads_num, threads_pool_type, tst, type, usn. See
above description of those parameters.
thin_provisioned, gen_tp_soft_threshold_reached_UA, threads_num,
threads_pool_type, tst, type, usn. See above description of those
parameters.
Each vdisk_nullio's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: blocksize, read_only,

View File

@@ -1106,6 +1106,11 @@ Each vdisk_fileio's device has the following attributes in
- thin_provisioned - contains thin provisioning status of this virtual
device.
- gen_tp_soft_threshold_reached_UA - for thin provisioned devices
writing of anything into this write-only attribute will generate THIN
PROVISIONING SOFT THRESHOLD REACHED Unit Attention to all connected
to this device initiators.
- removable - contains removable status of this virtual device.
- rotational - contains rotational status of this virtual device.
@@ -1205,8 +1210,9 @@ 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, rotational, size_mb, t10_dev_id,
thin_provisioned, threads_num, threads_pool_type, tst, type, usn. See
above description of those parameters.
thin_provisioned, gen_tp_soft_threshold_reached_UA, threads_num,
threads_pool_type, tst, type, usn. See above description of those
parameters.
Each vdisk_nullio's device has the following attributes in
/sys/kernel/scst_tgt/devices/device_name: blocksize, read_only,

View File

@@ -5665,6 +5665,8 @@ void scst_path_put(struct nameidata *nd);
#endif
int scst_remove_file(const char *name);
void scst_set_tp_soft_threshold_reached_UA(struct scst_tgt_dev *tgt_dev);
int scst_pr_set_cluster_mode(struct scst_device *dev, bool cluster_mode,
const char *cl_dev_id);
int scst_pr_init_dev(struct scst_device *dev);

View File

@@ -337,11 +337,13 @@ static inline int scst_sense_response_code(const uint8_t *sense)
#define scst_sense_asym_access_state_changed UNIT_ATTENTION, 0x2A, 0x06
#define scst_sense_capacity_data_changed UNIT_ATTENTION, 0x2A, 0x9
#define scst_sense_cleared_by_another_ini_UA UNIT_ATTENTION, 0x2F, 0
#define scst_sense_tp_soft_threshold_reached UNIT_ATTENTION, 0x38, 0x7
#define scst_sense_inquiry_data_changed UNIT_ATTENTION, 0x3F, 0x3
#define scst_sense_reported_luns_data_changed UNIT_ATTENTION, 0x3F, 0xE
/* DATA_PROTECT is 7 */
#define scst_sense_data_protect DATA_PROTECT, 0x27, 0
#define scst_sense_data_protect DATA_PROTECT, 0x00, 0
#define scst_space_allocation_failed_write_protect DATA_PROTECT, 0x27, 7
/* ABORTED_COMMAND is 0xb */
#define scst_sense_aborted_command ABORTED_COMMAND, 0x00, 0

View File

@@ -399,6 +399,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_gen_tp_soft_threshold_reached_UA(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count);
static ssize_t vdisk_sysfs_tst_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf);
static ssize_t vdisk_sysfs_rotational_show(struct kobject *kobj,
@@ -495,6 +497,9 @@ 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 gen_tp_soft_threshold_reached_UA_attr =
__ATTR(gen_tp_soft_threshold_reached_UA, S_IWUSR, NULL,
vdisk_sysfs_gen_tp_soft_threshold_reached_UA);
static struct kobj_attribute vdisk_tst_attr =
__ATTR(tst, S_IRUGO, vdisk_sysfs_tst_show, NULL);
static struct kobj_attribute vdisk_rotational_attr =
@@ -1054,6 +1059,17 @@ check:
if (virt_dev->thin_provisioned) {
int block_shift = virt_dev->dev->block_shift;
#ifndef CONFIG_SCST_PROC
int rc;
rc = sysfs_create_file(&virt_dev->dev->dev_kobj,
&gen_tp_soft_threshold_reached_UA_attr.attr);
if (rc != 0) {
PRINT_ERROR("Can't create attr %s for dev %s",
gen_tp_soft_threshold_reached_UA_attr.attr.name,
virt_dev->name);
}
#endif
if (virt_dev->blockio) {
struct request_queue *q;
@@ -6362,10 +6378,13 @@ restart:
full_len);
if (err == -EAGAIN)
scst_set_busy(cmd);
else {
else if (err == -ENOSPC) {
WARN_ON(!virt_dev->thin_provisioned);
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_space_allocation_failed_write_protect));
} else
scst_set_cmd_error(cmd,
SCST_LOAD_SENSE(scst_sense_write_error));
}
goto out_set_fs;
} else if (err < full_len) {
/*
@@ -6520,15 +6539,21 @@ static void blockio_endio(struct bio *bio)
spin_lock_irqsave(&vdev_err_lock, flags);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
if (bio->bi_rw & (1 << BIO_RW))
if (bio->bi_rw & (1 << BIO_RW)) {
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
if (bio->bi_rw & REQ_WRITE)
if (bio->bi_rw & REQ_WRITE) {
#else
if (op_is_write(bio_op(bio)))
if (op_is_write(bio_op(bio))) {
#endif
scst_set_cmd_error(blockio_work->cmd,
SCST_LOAD_SENSE(scst_sense_write_error));
else
if (error == -ENOSPC) {
struct scst_vdisk_dev *virt_dev = blockio_work->cmd->dev->dh_priv;
WARN_ON(!virt_dev->thin_provisioned);
scst_set_cmd_error(blockio_work->cmd,
SCST_LOAD_SENSE(scst_space_allocation_failed_write_protect));
} else
scst_set_cmd_error(blockio_work->cmd,
SCST_LOAD_SENSE(scst_sense_write_error));
} else
scst_set_cmd_error(blockio_work->cmd,
SCST_LOAD_SENSE(scst_sense_read_error));
@@ -8902,6 +8927,32 @@ static ssize_t vdisk_sysfs_tp_show(struct kobject *kobj,
return pos;
}
static ssize_t vdisk_sysfs_gen_tp_soft_threshold_reached_UA(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
struct scst_device *dev;
struct scst_vdisk_dev *virt_dev;
struct scst_tgt_dev *tgt_dev;
TRACE_ENTRY();
dev = container_of(kobj, struct scst_device, dev_kobj);
virt_dev = dev->dh_priv;
if (!virt_dev->thin_provisioned)
return -EINVAL;
spin_lock_bh(&dev->dev_lock);
list_for_each_entry(tgt_dev, &dev->dev_tgt_dev_list,
dev_tgt_dev_list_entry) {
scst_set_tp_soft_threshold_reached_UA(tgt_dev);
}
spin_unlock_bh(&dev->dev_lock);
TRACE_EXIT_RES(count);
return count;
}
static ssize_t vdisk_sysfs_expl_alua_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)

View File

@@ -12813,6 +12813,23 @@ void scst_dev_check_set_UA(struct scst_device *dev,
return;
}
void scst_set_tp_soft_threshold_reached_UA(struct scst_tgt_dev *tgt_dev)
{
uint8_t sense[SCST_STANDARD_SENSE_LEN];
int len;
TRACE_ENTRY();
len = scst_set_sense(sense, sizeof(sense), tgt_dev->dev->d_sense,
SCST_LOAD_SENSE(scst_sense_tp_soft_threshold_reached));
scst_check_set_UA(tgt_dev, sense, len, 0);
TRACE_EXIT();
return;
}
EXPORT_SYMBOL_GPL(scst_set_tp_soft_threshold_reached_UA);
/* Called under tgt_dev_lock or when tgt_dev is unused */
static void scst_free_all_UA(struct scst_tgt_dev *tgt_dev)
{