Forwarding targets attribute added

See the patch for description



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@6209 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2015-05-21 01:36:34 +00:00
parent a422ba3cc9
commit e0887beef6
7 changed files with 126 additions and 0 deletions

View File

@@ -665,6 +665,10 @@ Every target should have at least the following entries:
until rel_tgt_id becomes unique. This attribute initialized unique by
SCST by default.
- forwarding - if set this target is forwarding target, i.e. does not check
any local SCSI events (reservations, etc.). Those event supposed to
be checked on the another, requester's side.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. Those attributes have speaking names
built from parts:

View File

@@ -541,6 +541,10 @@ Every target should have at least the following entries:
until rel_tgt_id becomes unique. This attribute initialized unique by
SCST by default.
- forwarding - if set this target is forwarding target, i.e. does not check
any local SCSI events (reservations, etc.). Those event supposed to
be checked on the another, requester's side.
- *count*, e.g. read_io_count_kb, - statistics about executed
commands and transferred data. Those attributes have speaking names
built from parts:

View File

@@ -702,6 +702,9 @@ enum scst_exec_context {
/* Cache of acg->acg_black_hole_type */
#define SCST_TGT_DEV_BLACK_HOLE 1
/* Cache of tgt->tgt_forwarding */
#define SCST_TGT_DEV_FORWARDING 5
/*************************************************************
** I/O grouping types. Changing them don't forget to change
** the corresponding *_STR values in scst_const.h!
@@ -1926,6 +1929,13 @@ struct scst_tgt {
struct list_head tgt_acg_list; /* target ACG groups */
#endif
/*
* Set, if this target is forwarding target, i.e. does not check
* any local SCSI events (reservations, etc.). Those event supposed
* to be checked on the another, requester's side.
*/
unsigned tgt_forwarding:1;
/* Per target analog of the corresponding driver's fields */
unsigned tgt_dif_supported:1;
unsigned tgt_hw_dif_type1_supported:1;

View File

@@ -4858,6 +4858,10 @@ static int scst_alloc_add_tgt_dev(struct scst_session *sess,
tgt_dev->lun = acg_dev->lun;
tgt_dev->acg_dev = acg_dev;
tgt_dev->tgt_dev_rd_only = acg_dev->acg_dev_rd_only || dev->dev_rd_only;
if (sess->tgt->tgt_forwarding)
set_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags);
else
clear_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags);
tgt_dev->hw_dif_same_sg_layout_required = sess->tgt->tgt_hw_dif_same_sg_layout_required;
tgt_dev->tgt_dev_dif_guard_format = acg_dev->acg_dev_dif_guard_format;
if (tgt_dev->tgt_dev_dif_guard_format == SCST_DIF_GUARD_FORMAT_IP)

View File

@@ -1535,6 +1535,11 @@ static int scst_pr_register_all_tg_pt(struct scst_cmd *cmd, uint8_t *buffer,
continue;
if (tgt->rel_tgt_id == 0)
continue;
if (tgt->tgt_forwarding) {
TRACE_PR("ALL_TG_PT: skipping forwarding "
"target %s", tgt->tgt_name);
continue;
}
TRACE_PR("tgt %s, rel_tgt_id %d", tgt->tgt_name,
tgt->rel_tgt_id);
res = scst_pr_register_on_tgt_id(cmd, tgt->rel_tgt_id,

View File

@@ -2498,6 +2498,95 @@ static struct kobj_attribute scst_rel_tgt_id =
__ATTR(rel_tgt_id, S_IRUGO | S_IWUSR, scst_rel_tgt_id_show,
scst_rel_tgt_id_store);
static ssize_t scst_tgt_forwarding_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct scst_tgt *tgt;
int res;
TRACE_ENTRY();
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
res = sprintf(buf, "%d\n%s", tgt->tgt_forwarding,
tgt->tgt_forwarding ? SCST_SYSFS_KEY_MARK "\n" : "");
TRACE_EXIT_RES(res);
return res;
}
static ssize_t scst_tgt_forwarding_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int res = 0;
struct scst_tgt *tgt;
struct scst_session *sess;
int old;
TRACE_ENTRY();
if ((buf == NULL) || (count == 0)) {
res = 0;
goto out;
}
tgt = container_of(kobj, struct scst_tgt, tgt_kobj);
mutex_lock(&scst_mutex);
old = tgt->tgt_forwarding;
switch (buf[0]) {
case '0':
tgt->tgt_forwarding = 0;
break;
case '1':
tgt->tgt_forwarding = 1;
break;
default:
PRINT_ERROR("%s: Requested action not understood: %s",
__func__, buf);
res = -EINVAL;
goto out_unlock;
}
if (tgt->tgt_forwarding == old)
goto out_unlock;
list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) {
int i;
for (i = 0; i < SESS_TGT_DEV_LIST_HASH_SIZE; i++) {
struct list_head *head = &sess->sess_tgt_dev_list[i];
struct scst_tgt_dev *tgt_dev;
list_for_each_entry(tgt_dev, head, sess_tgt_dev_list_entry) {
if (tgt->tgt_forwarding)
set_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags);
else
clear_bit(SCST_TGT_DEV_FORWARDING, &tgt_dev->tgt_dev_flags);
}
}
}
if (tgt->tgt_forwarding)
PRINT_INFO("Set target %s as forwarding", tgt->tgt_name);
else
PRINT_INFO("Clear target %s as forwarding", tgt->tgt_name);
out_unlock:
mutex_unlock(&scst_mutex);
if (res == 0)
res = count;
out:
TRACE_EXIT_RES(res);
return res;
}
static struct kobj_attribute scst_tgt_forwarding =
__ATTR(forwarding, S_IRUGO | S_IWUSR, scst_tgt_forwarding_show,
scst_tgt_forwarding_store);
static ssize_t scst_tgt_comment_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
@@ -2769,6 +2858,7 @@ SCST_TGT_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, >> 0);
static struct attribute *scst_tgt_attrs[] = {
&scst_rel_tgt_id.attr,
&scst_tgt_forwarding.attr,
&scst_tgt_comment.attr,
&scst_tgt_addr_method.attr,
&scst_tgt_io_grouping_type.attr,

View File

@@ -2789,6 +2789,15 @@ int __scst_check_local_events(struct scst_cmd *cmd, bool preempt_tests_only)
goto out;
}
if (unlikely(test_bit(SCST_TGT_DEV_FORWARDING, &cmd->tgt_dev->tgt_dev_flags))) {
/*
* All the checks are supposed to be done on the
* forwarding requester's side.
*/
res = 0;
goto out;
}
/*
* There's no race here, because we need to trace commands sent
* *after* dev_double_ua_possible flag was set.