mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-18 03:01:26 +00:00
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:
10
scst/README
10
scst/README
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user