aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-10-16 03:12:53 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-10-16 18:41:26 -0400
commitfb2b2844743bc3d84ce1033167210e5fe3963455 (patch)
tree1b201f28602ef120a018c008aa98149bedd0adc6 /drivers/target
parent1ec59fee296d798b83a11f888981531dae16bfe8 (diff)
tcm_loop: Implement transport offline
Add attribute 'transport_status' to simulate link failure. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/loopback/tcm_loop.c53
-rw-r--r--drivers/target/loopback/tcm_loop.h4
2 files changed, 56 insertions, 1 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 21b49f351723..a00ad27940b7 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -178,7 +178,10 @@ static void tcm_loop_submission_work(struct work_struct *work)
178 set_host_byte(sc, DID_NO_CONNECT); 178 set_host_byte(sc, DID_NO_CONNECT);
179 goto out_done; 179 goto out_done;
180 } 180 }
181 181 if (tl_tpg->tl_transport_status == TCM_TRANSPORT_OFFLINE) {
182 set_host_byte(sc, DID_TRANSPORT_DISRUPTED);
183 goto out_done;
184 }
182 tl_nexus = tl_hba->tl_nexus; 185 tl_nexus = tl_hba->tl_nexus;
183 if (!tl_nexus) { 186 if (!tl_nexus) {
184 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" 187 scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus"
@@ -1064,8 +1067,56 @@ check_newline:
1064 1067
1065TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR); 1068TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR);
1066 1069
1070static ssize_t tcm_loop_tpg_show_transport_status(
1071 struct se_portal_group *se_tpg,
1072 char *page)
1073{
1074 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1075 struct tcm_loop_tpg, tl_se_tpg);
1076 const char *status = NULL;
1077 ssize_t ret = -EINVAL;
1078
1079 switch (tl_tpg->tl_transport_status) {
1080 case TCM_TRANSPORT_ONLINE:
1081 status = "online";
1082 break;
1083 case TCM_TRANSPORT_OFFLINE:
1084 status = "offline";
1085 break;
1086 default:
1087 break;
1088 }
1089
1090 if (status)
1091 ret = snprintf(page, PAGE_SIZE, "%s\n", status);
1092
1093 return ret;
1094}
1095
1096static ssize_t tcm_loop_tpg_store_transport_status(
1097 struct se_portal_group *se_tpg,
1098 const char *page,
1099 size_t count)
1100{
1101 struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
1102 struct tcm_loop_tpg, tl_se_tpg);
1103
1104 if (!strncmp(page, "online", 6)) {
1105 tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
1106 return count;
1107 }
1108 if (!strncmp(page, "offline", 7)) {
1109 tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE;
1110 return count;
1111 }
1112 return -EINVAL;
1113}
1114
1115TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR);
1116
1067static struct configfs_attribute *tcm_loop_tpg_attrs[] = { 1117static struct configfs_attribute *tcm_loop_tpg_attrs[] = {
1068 &tcm_loop_tpg_nexus.attr, 1118 &tcm_loop_tpg_nexus.attr,
1119 &tcm_loop_tpg_transport_status.attr,
1069 NULL, 1120 NULL,
1070}; 1121};
1071 1122
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h
index dd7a84ee78e1..56528f7dafae 100644
--- a/drivers/target/loopback/tcm_loop.h
+++ b/drivers/target/loopback/tcm_loop.h
@@ -40,8 +40,12 @@ struct tcm_loop_nacl {
40 struct se_node_acl se_node_acl; 40 struct se_node_acl se_node_acl;
41}; 41};
42 42
43#define TCM_TRANSPORT_ONLINE 0
44#define TCM_TRANSPORT_OFFLINE 1
45
43struct tcm_loop_tpg { 46struct tcm_loop_tpg {
44 unsigned short tl_tpgt; 47 unsigned short tl_tpgt;
48 unsigned short tl_transport_status;
45 atomic_t tl_tpg_port_count; 49 atomic_t tl_tpg_port_count;
46 struct se_portal_group tl_se_tpg; 50 struct se_portal_group tl_se_tpg;
47 struct tcm_loop_hba *tl_hba; 51 struct tcm_loop_hba *tl_hba;