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