You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger:
"It's been a busy development cycle for target-core in a number of
different areas.
The fabric API usage for se_node_acl allocation is now within
target-core code, dropping the external API callers for all fabric
drivers tree-wide.
There is a new conversion to RCU hlists for se_node_acl and
se_portal_group LUN mappings, that turns fast-past LUN lookup into a
completely lockless code-path. It also removes the original
hard-coded limitation of 256 LUNs per fabric endpoint.
The configfs attributes for backends can now be shared between core
and driver code, allowing existing drivers to use common code while
still allowing flexibility for new backend provided attributes.
The highlights include:
- Merge sbc_verify_dif_* into common code (sagi)
- Remove iscsi-target support for obsolete IFMarker/OFMarker
(Christophe Vu-Brugier)
- Add bidi support in target/user backend (ilias + vangelis + agover)
- Move se_node_acl allocation into target-core code (hch)
- Add crc_t10dif_update common helper (akinobu + mkp)
- Handle target-core odd SGL mapping for data transfer memory
(akinobu)
- Move transport ID handling into target-core (hch)
- Move task tag into struct se_cmd + support 64-bit tags (bart)
- Convert se_node_acl->device_list[] to RCU hlist (nab + hch +
paulmck)
- Convert se_portal_group->tpg_lun_list[] to RCU hlist (nab + hch +
paulmck)
- Simplify target backend driver registration (hch)
- Consolidate + simplify target backend attribute implementations
(hch + nab)
- Subsume se_port + t10_alua_tg_pt_gp_member into se_lun (hch)
- Drop lun_sep_lock for se_lun->lun_se_dev RCU usage (hch + nab)
- Drop unnecessary core_tpg_register TFO parameter (nab)
- Use 64-bit LUNs tree-wide (hannes)
- Drop left-over TARGET_MAX_LUNS_PER_TRANSPORT limit (hannes)"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (76 commits)
target: Bump core version to v5.0
target: remove target_core_configfs.h
target: remove unused TARGET_CORE_CONFIG_ROOT define
target: consolidate version defines
target: implement WRITE_SAME with UNMAP bit using ->execute_unmap
target: simplify UNMAP handling
target: replace se_cmd->execute_rw with a protocol_data field
target/user: Fix inconsistent kmap_atomic/kunmap_atomic
target: Send UA when changing LUN inventory
target: Send UA upon LUN RESET tmr completion
target: Send UA on ALUA target port group change
target: Convert se_lun->lun_deve_lock to normal spinlock
target: use 'se_dev_entry' when allocating UAs
target: Remove 'ua_nacl' pointer from se_ua structure
target_core_alua: Correct UA handling when switching states
xen-scsiback: Fix compile warning for 64-bit LUN
target: Remove TARGET_MAX_LUNS_PER_TRANSPORT
target: use 64-bit LUNs
target: Drop duplicate + unused se_dev_check_wce
target: Drop unnecessary core_tpg_register TFO parameter
...
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
#include <scsi/scsi_tcq.h>
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
|
||||
#include <target/iscsi/iscsi_target_core.h>
|
||||
#include "iscsi_target_parameters.h"
|
||||
@@ -716,7 +715,7 @@ static int iscsit_add_reject_from_cmd(
|
||||
*/
|
||||
if (cmd->se_cmd.se_tfo != NULL) {
|
||||
pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
|
||||
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
|
||||
target_put_sess_cmd(&cmd->se_cmd);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -1002,13 +1001,15 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||
hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
|
||||
conn->cid);
|
||||
|
||||
target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
|
||||
target_get_sess_cmd(&cmd->se_cmd, true);
|
||||
|
||||
cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
|
||||
scsilun_to_int(&hdr->lun));
|
||||
if (cmd->sense_reason)
|
||||
goto attach_cmd;
|
||||
|
||||
/* only used for printks or comparing with ->ref_task_tag */
|
||||
cmd->se_cmd.tag = (__force u32)cmd->init_task_tag;
|
||||
cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
|
||||
if (cmd->sense_reason) {
|
||||
if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
|
||||
@@ -1068,7 +1069,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||
if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
|
||||
return -1;
|
||||
else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
|
||||
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
|
||||
target_put_sess_cmd(&cmd->se_cmd);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1084,7 +1085,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||
if (!cmd->sense_reason)
|
||||
return 0;
|
||||
|
||||
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
|
||||
target_put_sess_cmd(&cmd->se_cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1115,7 +1116,6 @@ static int
|
||||
iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
|
||||
bool dump_payload)
|
||||
{
|
||||
struct iscsi_conn *conn = cmd->conn;
|
||||
int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
|
||||
/*
|
||||
* Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
|
||||
@@ -1142,7 +1142,7 @@ after_immediate_data:
|
||||
|
||||
rc = iscsit_dump_data_payload(cmd->conn,
|
||||
cmd->first_burst_len, 1);
|
||||
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
|
||||
target_put_sess_cmd(&cmd->se_cmd);
|
||||
return rc;
|
||||
} else if (cmd->unsolicited_data)
|
||||
iscsit_set_unsoliticed_dataout(cmd);
|
||||
@@ -1811,7 +1811,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||
conn->sess->se_sess, 0, DMA_NONE,
|
||||
TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
|
||||
|
||||
target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
|
||||
target_get_sess_cmd(&cmd->se_cmd, true);
|
||||
sess_ref = true;
|
||||
|
||||
switch (function) {
|
||||
@@ -1953,7 +1953,7 @@ attach:
|
||||
*/
|
||||
if (sess_ref) {
|
||||
pr_debug("Handle TMR, using sess_ref=true check\n");
|
||||
target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
|
||||
target_put_sess_cmd(&cmd->se_cmd);
|
||||
}
|
||||
|
||||
iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
|
||||
@@ -2737,11 +2737,7 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
|
||||
cmd->iov_data_count = iov_count;
|
||||
cmd->tx_size = tx_size;
|
||||
|
||||
/* sendpage is preferred but can't insert markers */
|
||||
if (!conn->conn_ops->IFMarker)
|
||||
ret = iscsit_fe_sendpage_sg(cmd, conn);
|
||||
else
|
||||
ret = iscsit_send_tx_data(cmd, conn, 0);
|
||||
ret = iscsit_fe_sendpage_sg(cmd, conn);
|
||||
|
||||
iscsit_unmap_iovec(cmd);
|
||||
|
||||
@@ -4073,17 +4069,9 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
|
||||
" opcode while ERL=0, closing iSCSI connection.\n");
|
||||
return -1;
|
||||
}
|
||||
if (!conn->conn_ops->OFMarker) {
|
||||
pr_err("Unable to recover from unknown"
|
||||
" opcode while OFMarker=No, closing iSCSI"
|
||||
" connection.\n");
|
||||
return -1;
|
||||
}
|
||||
if (iscsit_recover_from_unknown_opcode(conn) < 0) {
|
||||
pr_err("Unable to recover from unknown"
|
||||
" opcode, closing iSCSI connection.\n");
|
||||
return -1;
|
||||
}
|
||||
pr_err("Unable to recover from unknown opcode while OFMarker=No,"
|
||||
" closing iSCSI connection.\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
#include <target/configfs_macros.h>
|
||||
#include <target/iscsi/iscsi_transport.h>
|
||||
|
||||
@@ -860,57 +859,19 @@ static struct configfs_attribute *lio_target_initiator_attrs[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct se_node_acl *lio_tpg_alloc_fabric_acl(
|
||||
struct se_portal_group *se_tpg)
|
||||
static int lio_target_init_nodeacl(struct se_node_acl *se_nacl,
|
||||
const char *name)
|
||||
{
|
||||
struct iscsi_node_acl *acl;
|
||||
|
||||
acl = kzalloc(sizeof(struct iscsi_node_acl), GFP_KERNEL);
|
||||
if (!acl) {
|
||||
pr_err("Unable to allocate memory for struct iscsi_node_acl\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &acl->se_node_acl;
|
||||
}
|
||||
|
||||
static struct se_node_acl *lio_target_make_nodeacl(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
{
|
||||
struct config_group *stats_cg;
|
||||
struct iscsi_node_acl *acl;
|
||||
struct se_node_acl *se_nacl_new, *se_nacl;
|
||||
struct iscsi_portal_group *tpg = container_of(se_tpg,
|
||||
struct iscsi_portal_group, tpg_se_tpg);
|
||||
u32 cmdsn_depth;
|
||||
|
||||
se_nacl_new = lio_tpg_alloc_fabric_acl(se_tpg);
|
||||
if (!se_nacl_new)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
cmdsn_depth = tpg->tpg_attrib.default_cmdsn_depth;
|
||||
/*
|
||||
* se_nacl_new may be released by core_tpg_add_initiator_node_acl()
|
||||
* when converting a NdoeACL from demo mode -> explict
|
||||
*/
|
||||
se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
|
||||
name, cmdsn_depth);
|
||||
if (IS_ERR(se_nacl))
|
||||
return se_nacl;
|
||||
|
||||
acl = container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
|
||||
stats_cg = &se_nacl->acl_fabric_stat_group;
|
||||
struct iscsi_node_acl *acl =
|
||||
container_of(se_nacl, struct iscsi_node_acl, se_node_acl);
|
||||
struct config_group *stats_cg = &se_nacl->acl_fabric_stat_group;
|
||||
|
||||
stats_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2,
|
||||
GFP_KERNEL);
|
||||
if (!stats_cg->default_groups) {
|
||||
pr_err("Unable to allocate memory for"
|
||||
" stats_cg->default_groups\n");
|
||||
core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1);
|
||||
kfree(acl);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
stats_cg->default_groups[0] = &acl->node_stat_grps.iscsi_sess_stats_group;
|
||||
@@ -918,13 +879,11 @@ static struct se_node_acl *lio_target_make_nodeacl(
|
||||
config_group_init_type_name(&acl->node_stat_grps.iscsi_sess_stats_group,
|
||||
"iscsi_sess_stats", &iscsi_stat_sess_cit);
|
||||
|
||||
return se_nacl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lio_target_drop_nodeacl(
|
||||
struct se_node_acl *se_nacl)
|
||||
static void lio_target_cleanup_nodeacl( struct se_node_acl *se_nacl)
|
||||
{
|
||||
struct se_portal_group *se_tpg = se_nacl->se_tpg;
|
||||
struct iscsi_node_acl *acl = container_of(se_nacl,
|
||||
struct iscsi_node_acl, se_node_acl);
|
||||
struct config_item *df_item;
|
||||
@@ -938,9 +897,6 @@ static void lio_target_drop_nodeacl(
|
||||
config_item_put(df_item);
|
||||
}
|
||||
kfree(stats_cg->default_groups);
|
||||
|
||||
core_tpg_del_initiator_node_acl(se_tpg, se_nacl, 1);
|
||||
kfree(acl);
|
||||
}
|
||||
|
||||
/* End items for lio_target_acl_cit */
|
||||
@@ -1463,8 +1419,7 @@ static struct se_portal_group *lio_target_tiqn_addtpg(
|
||||
if (!tpg)
|
||||
return NULL;
|
||||
|
||||
ret = core_tpg_register(&iscsi_ops, wwn, &tpg->tpg_se_tpg,
|
||||
tpg, TRANSPORT_TPG_TYPE_NORMAL);
|
||||
ret = core_tpg_register(wwn, &tpg->tpg_se_tpg, SCSI_PROTOCOL_ISCSI);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
@@ -1735,14 +1690,6 @@ static char *iscsi_get_fabric_name(void)
|
||||
return "iSCSI";
|
||||
}
|
||||
|
||||
static u32 iscsi_get_task_tag(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
|
||||
|
||||
/* only used for printks or comparism with ->ref_task_tag */
|
||||
return (__force u32)cmd->init_task_tag;
|
||||
}
|
||||
|
||||
static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
|
||||
@@ -1832,78 +1779,58 @@ static void lio_aborted_task(struct se_cmd *se_cmd)
|
||||
cmd->conn->conn_transport->iscsit_aborted_task(cmd->conn, cmd);
|
||||
}
|
||||
|
||||
static inline struct iscsi_portal_group *iscsi_tpg(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return container_of(se_tpg, struct iscsi_portal_group, tpg_se_tpg);
|
||||
}
|
||||
|
||||
static char *lio_tpg_get_endpoint_wwn(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return &tpg->tpg_tiqn->tiqn[0];
|
||||
return iscsi_tpg(se_tpg)->tpg_tiqn->tiqn;
|
||||
}
|
||||
|
||||
static u16 lio_tpg_get_tag(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpgt;
|
||||
return iscsi_tpg(se_tpg)->tpgt;
|
||||
}
|
||||
|
||||
static u32 lio_tpg_get_default_depth(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_attrib.default_cmdsn_depth;
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.default_cmdsn_depth;
|
||||
}
|
||||
|
||||
static int lio_tpg_check_demo_mode(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_attrib.generate_node_acls;
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.generate_node_acls;
|
||||
}
|
||||
|
||||
static int lio_tpg_check_demo_mode_cache(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_attrib.cache_dynamic_acls;
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.cache_dynamic_acls;
|
||||
}
|
||||
|
||||
static int lio_tpg_check_demo_mode_write_protect(
|
||||
struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_attrib.demo_mode_write_protect;
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.demo_mode_write_protect;
|
||||
}
|
||||
|
||||
static int lio_tpg_check_prod_mode_write_protect(
|
||||
struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_attrib.prod_mode_write_protect;
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.prod_mode_write_protect;
|
||||
}
|
||||
|
||||
static int lio_tpg_check_prot_fabric_only(
|
||||
struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
/*
|
||||
* Only report fabric_prot_type if t10_pi has also been enabled
|
||||
* for incoming ib_isert sessions.
|
||||
*/
|
||||
if (!tpg->tpg_attrib.t10_pi)
|
||||
if (!iscsi_tpg(se_tpg)->tpg_attrib.t10_pi)
|
||||
return 0;
|
||||
|
||||
return tpg->tpg_attrib.fabric_prot_type;
|
||||
}
|
||||
|
||||
static void lio_tpg_release_fabric_acl(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_acl)
|
||||
{
|
||||
struct iscsi_node_acl *acl = container_of(se_acl,
|
||||
struct iscsi_node_acl, se_node_acl);
|
||||
kfree(acl);
|
||||
return iscsi_tpg(se_tpg)->tpg_attrib.fabric_prot_type;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1948,9 +1875,7 @@ static void lio_tpg_close_session(struct se_session *se_sess)
|
||||
|
||||
static u32 lio_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct iscsi_portal_group *tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
|
||||
return tpg->tpg_tiqn->tiqn_index;
|
||||
return iscsi_tpg(se_tpg)->tpg_tiqn->tiqn_index;
|
||||
}
|
||||
|
||||
static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
|
||||
@@ -1967,7 +1892,7 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
|
||||
|
||||
static int lio_check_stop_free(struct se_cmd *se_cmd)
|
||||
{
|
||||
return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
|
||||
return target_put_sess_cmd(se_cmd);
|
||||
}
|
||||
|
||||
static void lio_release_cmd(struct se_cmd *se_cmd)
|
||||
@@ -1981,14 +1906,11 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
|
||||
const struct target_core_fabric_ops iscsi_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "iscsi",
|
||||
.node_acl_size = sizeof(struct iscsi_node_acl),
|
||||
.get_fabric_name = iscsi_get_fabric_name,
|
||||
.get_fabric_proto_ident = iscsi_get_fabric_proto_ident,
|
||||
.tpg_get_wwn = lio_tpg_get_endpoint_wwn,
|
||||
.tpg_get_tag = lio_tpg_get_tag,
|
||||
.tpg_get_default_depth = lio_tpg_get_default_depth,
|
||||
.tpg_get_pr_transport_id = iscsi_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = iscsi_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = iscsi_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = lio_tpg_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = lio_tpg_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect =
|
||||
@@ -1996,8 +1918,6 @@ const struct target_core_fabric_ops iscsi_ops = {
|
||||
.tpg_check_prod_mode_write_protect =
|
||||
lio_tpg_check_prod_mode_write_protect,
|
||||
.tpg_check_prot_fabric_only = &lio_tpg_check_prot_fabric_only,
|
||||
.tpg_alloc_fabric_acl = lio_tpg_alloc_fabric_acl,
|
||||
.tpg_release_fabric_acl = lio_tpg_release_fabric_acl,
|
||||
.tpg_get_inst_index = lio_tpg_get_inst_index,
|
||||
.check_stop_free = lio_check_stop_free,
|
||||
.release_cmd = lio_release_cmd,
|
||||
@@ -2008,7 +1928,6 @@ const struct target_core_fabric_ops iscsi_ops = {
|
||||
.write_pending = lio_write_pending,
|
||||
.write_pending_status = lio_write_pending_status,
|
||||
.set_default_node_attributes = lio_set_default_node_attributes,
|
||||
.get_task_tag = iscsi_get_task_tag,
|
||||
.get_cmd_state = iscsi_get_cmd_state,
|
||||
.queue_data_in = lio_queue_data_in,
|
||||
.queue_status = lio_queue_status,
|
||||
@@ -2020,8 +1939,8 @@ const struct target_core_fabric_ops iscsi_ops = {
|
||||
.fabric_drop_tpg = lio_target_tiqn_deltpg,
|
||||
.fabric_make_np = lio_target_call_addnptotpg,
|
||||
.fabric_drop_np = lio_target_call_delnpfromtpg,
|
||||
.fabric_make_nodeacl = lio_target_make_nodeacl,
|
||||
.fabric_drop_nodeacl = lio_target_drop_nodeacl,
|
||||
.fabric_init_nodeacl = lio_target_init_nodeacl,
|
||||
.fabric_cleanup_nodeacl = lio_target_cleanup_nodeacl,
|
||||
|
||||
.tfc_discovery_attrs = lio_target_discovery_auth_attrs,
|
||||
.tfc_wwn_attrs = lio_target_wwn_attrs,
|
||||
|
||||
@@ -956,56 +956,3 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
|
||||
|
||||
iscsit_handle_connection_cleanup(conn);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the simple function that makes the magic of
|
||||
* sync and steering happen in the follow paradoxical order:
|
||||
*
|
||||
* 0) Receive conn->of_marker (bytes left until next OFMarker)
|
||||
* bytes into an offload buffer. When we pass the exact number
|
||||
* of bytes in conn->of_marker, iscsit_dump_data_payload() and hence
|
||||
* rx_data() will automatically receive the identical u32 marker
|
||||
* values and store it in conn->of_marker_offset;
|
||||
* 1) Now conn->of_marker_offset will contain the offset to the start
|
||||
* of the next iSCSI PDU. Dump these remaining bytes into another
|
||||
* offload buffer.
|
||||
* 2) We are done!
|
||||
* Next byte in the TCP stream will contain the next iSCSI PDU!
|
||||
* Cool Huh?!
|
||||
*/
|
||||
int iscsit_recover_from_unknown_opcode(struct iscsi_conn *conn)
|
||||
{
|
||||
/*
|
||||
* Make sure the remaining bytes to next maker is a sane value.
|
||||
*/
|
||||
if (conn->of_marker > (conn->conn_ops->OFMarkInt * 4)) {
|
||||
pr_err("Remaining bytes to OFMarker: %u exceeds"
|
||||
" OFMarkInt bytes: %u.\n", conn->of_marker,
|
||||
conn->conn_ops->OFMarkInt * 4);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_debug("Advancing %u bytes in TCP stream to get to the"
|
||||
" next OFMarker.\n", conn->of_marker);
|
||||
|
||||
if (iscsit_dump_data_payload(conn, conn->of_marker, 0) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Make sure the offset marker we retrived is a valid value.
|
||||
*/
|
||||
if (conn->of_marker_offset > (ISCSI_HDR_LEN + (ISCSI_CRC_LEN * 2) +
|
||||
conn->conn_ops->MaxRecvDataSegmentLength)) {
|
||||
pr_err("OfMarker offset value: %u exceeds limit.\n",
|
||||
conn->of_marker_offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_debug("Discarding %u bytes of TCP stream to get to the"
|
||||
" next iSCSI Opcode.\n", conn->of_marker_offset);
|
||||
|
||||
if (iscsit_dump_data_payload(conn, conn->of_marker_offset, 0) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,5 @@ extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *);
|
||||
extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int);
|
||||
extern void iscsit_fall_back_to_erl0(struct iscsi_session *);
|
||||
extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *);
|
||||
extern int iscsit_recover_from_unknown_opcode(struct iscsi_conn *);
|
||||
|
||||
#endif /*** ISCSI_TARGET_ERL0_H ***/
|
||||
|
||||
@@ -410,8 +410,6 @@ static int iscsi_login_zero_tsih_s2(
|
||||
if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", na->default_erl))
|
||||
return -1;
|
||||
|
||||
if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
|
||||
return -1;
|
||||
/*
|
||||
* Set RDMAExtensions=Yes by default for iSER enabled network portals
|
||||
*/
|
||||
@@ -477,59 +475,6 @@ check_prot:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove PSTATE_NEGOTIATE for the four FIM related keys.
|
||||
* The Initiator node will be able to enable FIM by proposing them itself.
|
||||
*/
|
||||
int iscsi_login_disable_FIM_keys(
|
||||
struct iscsi_param_list *param_list,
|
||||
struct iscsi_conn *conn)
|
||||
{
|
||||
struct iscsi_param *param;
|
||||
|
||||
param = iscsi_find_param_from_key("OFMarker", param_list);
|
||||
if (!param) {
|
||||
pr_err("iscsi_find_param_from_key() for"
|
||||
" OFMarker failed\n");
|
||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
|
||||
ISCSI_LOGIN_STATUS_NO_RESOURCES);
|
||||
return -1;
|
||||
}
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
|
||||
param = iscsi_find_param_from_key("OFMarkInt", param_list);
|
||||
if (!param) {
|
||||
pr_err("iscsi_find_param_from_key() for"
|
||||
" IFMarker failed\n");
|
||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
|
||||
ISCSI_LOGIN_STATUS_NO_RESOURCES);
|
||||
return -1;
|
||||
}
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
|
||||
param = iscsi_find_param_from_key("IFMarker", param_list);
|
||||
if (!param) {
|
||||
pr_err("iscsi_find_param_from_key() for"
|
||||
" IFMarker failed\n");
|
||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
|
||||
ISCSI_LOGIN_STATUS_NO_RESOURCES);
|
||||
return -1;
|
||||
}
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
|
||||
param = iscsi_find_param_from_key("IFMarkInt", param_list);
|
||||
if (!param) {
|
||||
pr_err("iscsi_find_param_from_key() for"
|
||||
" IFMarker failed\n");
|
||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
|
||||
ISCSI_LOGIN_STATUS_NO_RESOURCES);
|
||||
return -1;
|
||||
}
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iscsi_login_non_zero_tsih_s1(
|
||||
struct iscsi_conn *conn,
|
||||
unsigned char *buf)
|
||||
@@ -616,7 +561,7 @@ static int iscsi_login_non_zero_tsih_s2(
|
||||
if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt))
|
||||
return -1;
|
||||
|
||||
return iscsi_login_disable_FIM_keys(conn->param_list, conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iscsi_login_post_auth_non_zero_tsih(
|
||||
@@ -765,7 +710,6 @@ int iscsi_post_login_handler(
|
||||
conn->conn_state = TARG_CONN_STATE_LOGGED_IN;
|
||||
|
||||
iscsi_set_connection_parameters(conn->conn_ops, conn->param_list);
|
||||
iscsit_set_sync_and_steering_values(conn);
|
||||
/*
|
||||
* SCSI Initiator -> SCSI Target Port Mapping
|
||||
*/
|
||||
|
||||
@@ -16,6 +16,5 @@ extern int iscsi_post_login_handler(struct iscsi_np *, struct iscsi_conn *, u8);
|
||||
extern void iscsi_target_login_sess_out(struct iscsi_conn *, struct iscsi_np *,
|
||||
bool, bool);
|
||||
extern int iscsi_target_login_thread(void *);
|
||||
extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *);
|
||||
|
||||
#endif /*** ISCSI_TARGET_LOGIN_H ***/
|
||||
|
||||
@@ -34,13 +34,6 @@ int iscsi_login_rx_data(
|
||||
iov.iov_len = length;
|
||||
iov.iov_base = buf;
|
||||
|
||||
/*
|
||||
* Initial Marker-less Interval.
|
||||
* Add the values regardless of IFMarker/OFMarker, considering
|
||||
* it may not be negoitated yet.
|
||||
*/
|
||||
conn->of_marker += length;
|
||||
|
||||
rx_got = rx_data(conn, &iov, 1, length);
|
||||
if (rx_got != length) {
|
||||
pr_err("rx_data returned %d, expecting %d.\n",
|
||||
@@ -72,13 +65,6 @@ int iscsi_login_tx_data(
|
||||
iov_cnt++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial Marker-less Interval.
|
||||
* Add the values regardless of IFMarker/OFMarker, considering
|
||||
* it may not be negoitated yet.
|
||||
*/
|
||||
conn->if_marker += length;
|
||||
|
||||
tx_sent = tx_data(conn, &iov[0], iov_cnt, length);
|
||||
if (tx_sent != length) {
|
||||
pr_err("tx_data returned %d, expecting %d.\n",
|
||||
@@ -97,12 +83,6 @@ void iscsi_dump_conn_ops(struct iscsi_conn_ops *conn_ops)
|
||||
"CRC32C" : "None");
|
||||
pr_debug("MaxRecvDataSegmentLength: %u\n",
|
||||
conn_ops->MaxRecvDataSegmentLength);
|
||||
pr_debug("OFMarker: %s\n", (conn_ops->OFMarker) ? "Yes" : "No");
|
||||
pr_debug("IFMarker: %s\n", (conn_ops->IFMarker) ? "Yes" : "No");
|
||||
if (conn_ops->OFMarker)
|
||||
pr_debug("OFMarkInt: %u\n", conn_ops->OFMarkInt);
|
||||
if (conn_ops->IFMarker)
|
||||
pr_debug("IFMarkInt: %u\n", conn_ops->IFMarkInt);
|
||||
}
|
||||
|
||||
void iscsi_dump_sess_ops(struct iscsi_sess_ops *sess_ops)
|
||||
@@ -194,10 +174,6 @@ static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *para
|
||||
case TYPERANGE_DIGEST:
|
||||
param->type = TYPE_VALUE_LIST | TYPE_STRING;
|
||||
break;
|
||||
case TYPERANGE_MARKINT:
|
||||
param->type = TYPE_NUMBER_RANGE;
|
||||
param->type_range |= TYPERANGE_1_TO_65535;
|
||||
break;
|
||||
case TYPERANGE_ISCSINAME:
|
||||
case TYPERANGE_SESSIONTYPE:
|
||||
case TYPERANGE_TARGETADDRESS:
|
||||
@@ -422,13 +398,13 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
|
||||
|
||||
param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT,
|
||||
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
|
||||
TYPERANGE_MARKINT, USE_INITIAL_ONLY);
|
||||
TYPERANGE_UTF8, USE_INITIAL_ONLY);
|
||||
if (!param)
|
||||
goto out;
|
||||
|
||||
param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT,
|
||||
PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
|
||||
TYPERANGE_MARKINT, USE_INITIAL_ONLY);
|
||||
TYPERANGE_UTF8, USE_INITIAL_ONLY);
|
||||
if (!param)
|
||||
goto out;
|
||||
/*
|
||||
@@ -524,9 +500,9 @@ int iscsi_set_keys_to_negotiate(
|
||||
} else if (!strcmp(param->name, OFMARKER)) {
|
||||
SET_PSTATE_NEGOTIATE(param);
|
||||
} else if (!strcmp(param->name, IFMARKINT)) {
|
||||
SET_PSTATE_NEGOTIATE(param);
|
||||
SET_PSTATE_REJECT(param);
|
||||
} else if (!strcmp(param->name, OFMARKINT)) {
|
||||
SET_PSTATE_NEGOTIATE(param);
|
||||
SET_PSTATE_REJECT(param);
|
||||
} else if (!strcmp(param->name, RDMAEXTENSIONS)) {
|
||||
if (iser)
|
||||
SET_PSTATE_NEGOTIATE(param);
|
||||
@@ -906,91 +882,6 @@ static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_pt
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iscsi_check_numerical_range_value(struct iscsi_param *param, char *value)
|
||||
{
|
||||
char *left_val_ptr = NULL, *right_val_ptr = NULL;
|
||||
char *tilde_ptr = NULL;
|
||||
u32 left_val, right_val, local_left_val;
|
||||
|
||||
if (strcmp(param->name, IFMARKINT) &&
|
||||
strcmp(param->name, OFMARKINT)) {
|
||||
pr_err("Only parameters \"%s\" or \"%s\" may contain a"
|
||||
" numerical range value.\n", IFMARKINT, OFMARKINT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IS_PSTATE_PROPOSER(param))
|
||||
return 0;
|
||||
|
||||
tilde_ptr = strchr(value, '~');
|
||||
if (!tilde_ptr) {
|
||||
pr_err("Unable to locate numerical range indicator"
|
||||
" \"~\" for \"%s\".\n", param->name);
|
||||
return -1;
|
||||
}
|
||||
*tilde_ptr = '\0';
|
||||
|
||||
left_val_ptr = value;
|
||||
right_val_ptr = value + strlen(left_val_ptr) + 1;
|
||||
|
||||
if (iscsi_check_numerical_value(param, left_val_ptr) < 0)
|
||||
return -1;
|
||||
if (iscsi_check_numerical_value(param, right_val_ptr) < 0)
|
||||
return -1;
|
||||
|
||||
left_val = simple_strtoul(left_val_ptr, NULL, 0);
|
||||
right_val = simple_strtoul(right_val_ptr, NULL, 0);
|
||||
*tilde_ptr = '~';
|
||||
|
||||
if (right_val < left_val) {
|
||||
pr_err("Numerical range for parameter \"%s\" contains"
|
||||
" a right value which is less than the left.\n",
|
||||
param->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, enforce reasonable defaults for [I,O]FMarkInt.
|
||||
*/
|
||||
tilde_ptr = strchr(param->value, '~');
|
||||
if (!tilde_ptr) {
|
||||
pr_err("Unable to locate numerical range indicator"
|
||||
" \"~\" for \"%s\".\n", param->name);
|
||||
return -1;
|
||||
}
|
||||
*tilde_ptr = '\0';
|
||||
|
||||
left_val_ptr = param->value;
|
||||
right_val_ptr = param->value + strlen(left_val_ptr) + 1;
|
||||
|
||||
local_left_val = simple_strtoul(left_val_ptr, NULL, 0);
|
||||
*tilde_ptr = '~';
|
||||
|
||||
if (param->set_param) {
|
||||
if ((left_val < local_left_val) ||
|
||||
(right_val < local_left_val)) {
|
||||
pr_err("Passed value range \"%u~%u\" is below"
|
||||
" minimum left value \"%u\" for key \"%s\","
|
||||
" rejecting.\n", left_val, right_val,
|
||||
local_left_val, param->name);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if ((left_val < local_left_val) &&
|
||||
(right_val < local_left_val)) {
|
||||
pr_err("Received value range \"%u~%u\" is"
|
||||
" below minimum left value \"%u\" for key"
|
||||
" \"%s\", rejecting.\n", left_val, right_val,
|
||||
local_left_val, param->name);
|
||||
SET_PSTATE_REJECT(param);
|
||||
if (iscsi_update_param_value(param, REJECT) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
|
||||
{
|
||||
if (IS_PSTATE_PROPOSER(param))
|
||||
@@ -1027,33 +918,6 @@ static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *val
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to pick a value range number, currently just
|
||||
* returns the lesser of both right values.
|
||||
*/
|
||||
static char *iscsi_get_value_from_number_range(
|
||||
struct iscsi_param *param,
|
||||
char *value)
|
||||
{
|
||||
char *end_ptr, *tilde_ptr1 = NULL, *tilde_ptr2 = NULL;
|
||||
u32 acceptor_right_value, proposer_right_value;
|
||||
|
||||
tilde_ptr1 = strchr(value, '~');
|
||||
if (!tilde_ptr1)
|
||||
return NULL;
|
||||
*tilde_ptr1++ = '\0';
|
||||
proposer_right_value = simple_strtoul(tilde_ptr1, &end_ptr, 0);
|
||||
|
||||
tilde_ptr2 = strchr(param->value, '~');
|
||||
if (!tilde_ptr2)
|
||||
return NULL;
|
||||
*tilde_ptr2++ = '\0';
|
||||
acceptor_right_value = simple_strtoul(tilde_ptr2, &end_ptr, 0);
|
||||
|
||||
return (acceptor_right_value >= proposer_right_value) ?
|
||||
tilde_ptr1 : tilde_ptr2;
|
||||
}
|
||||
|
||||
static char *iscsi_check_valuelist_for_support(
|
||||
struct iscsi_param *param,
|
||||
char *value)
|
||||
@@ -1103,7 +967,7 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
|
||||
struct iscsi_conn *conn)
|
||||
{
|
||||
u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
|
||||
char *negoitated_value = NULL;
|
||||
char *negotiated_value = NULL;
|
||||
|
||||
if (IS_PSTATE_ACCEPTOR(param)) {
|
||||
pr_err("Received key \"%s\" twice, protocol error.\n",
|
||||
@@ -1203,24 +1067,16 @@ static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
|
||||
pr_debug("Updated %s to target MXDSL value: %s\n",
|
||||
param->name, param->value);
|
||||
}
|
||||
|
||||
} else if (IS_TYPE_NUMBER_RANGE(param)) {
|
||||
negoitated_value = iscsi_get_value_from_number_range(
|
||||
param, value);
|
||||
if (!negoitated_value)
|
||||
return -1;
|
||||
if (iscsi_update_param_value(param, negoitated_value) < 0)
|
||||
return -1;
|
||||
} else if (IS_TYPE_VALUE_LIST(param)) {
|
||||
negoitated_value = iscsi_check_valuelist_for_support(
|
||||
negotiated_value = iscsi_check_valuelist_for_support(
|
||||
param, value);
|
||||
if (!negoitated_value) {
|
||||
if (!negotiated_value) {
|
||||
pr_err("Proposer's value list \"%s\" contains"
|
||||
" no valid values from Acceptor's value list"
|
||||
" \"%s\".\n", value, param->value);
|
||||
return -1;
|
||||
}
|
||||
if (iscsi_update_param_value(param, negoitated_value) < 0)
|
||||
if (iscsi_update_param_value(param, negotiated_value) < 0)
|
||||
return -1;
|
||||
} else if (IS_PHASE_DECLARATIVE(param)) {
|
||||
if (iscsi_update_param_value(param, value) < 0)
|
||||
@@ -1239,47 +1095,7 @@ static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (IS_TYPE_NUMBER_RANGE(param)) {
|
||||
u32 left_val = 0, right_val = 0, recieved_value = 0;
|
||||
char *left_val_ptr = NULL, *right_val_ptr = NULL;
|
||||
char *tilde_ptr = NULL;
|
||||
|
||||
if (!strcmp(value, IRRELEVANT) || !strcmp(value, REJECT)) {
|
||||
if (iscsi_update_param_value(param, value) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tilde_ptr = strchr(value, '~');
|
||||
if (tilde_ptr) {
|
||||
pr_err("Illegal \"~\" in response for \"%s\".\n",
|
||||
param->name);
|
||||
return -1;
|
||||
}
|
||||
tilde_ptr = strchr(param->value, '~');
|
||||
if (!tilde_ptr) {
|
||||
pr_err("Unable to locate numerical range"
|
||||
" indicator \"~\" for \"%s\".\n", param->name);
|
||||
return -1;
|
||||
}
|
||||
*tilde_ptr = '\0';
|
||||
|
||||
left_val_ptr = param->value;
|
||||
right_val_ptr = param->value + strlen(left_val_ptr) + 1;
|
||||
left_val = simple_strtoul(left_val_ptr, NULL, 0);
|
||||
right_val = simple_strtoul(right_val_ptr, NULL, 0);
|
||||
recieved_value = simple_strtoul(value, NULL, 0);
|
||||
|
||||
*tilde_ptr = '~';
|
||||
|
||||
if ((recieved_value < left_val) ||
|
||||
(recieved_value > right_val)) {
|
||||
pr_err("Illegal response \"%s=%u\", value must"
|
||||
" be between %u and %u.\n", param->name,
|
||||
recieved_value, left_val, right_val);
|
||||
return -1;
|
||||
}
|
||||
} else if (IS_TYPE_VALUE_LIST(param)) {
|
||||
if (IS_TYPE_VALUE_LIST(param)) {
|
||||
char *comma_ptr = NULL, *tmp_ptr = NULL;
|
||||
|
||||
comma_ptr = strchr(value, ',');
|
||||
@@ -1361,9 +1177,6 @@ static int iscsi_check_value(struct iscsi_param *param, char *value)
|
||||
} else if (IS_TYPE_NUMBER(param)) {
|
||||
if (iscsi_check_numerical_value(param, value) < 0)
|
||||
return -1;
|
||||
} else if (IS_TYPE_NUMBER_RANGE(param)) {
|
||||
if (iscsi_check_numerical_range_value(param, value) < 0)
|
||||
return -1;
|
||||
} else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
|
||||
if (iscsi_check_string_or_list_value(param, value) < 0)
|
||||
return -1;
|
||||
@@ -1483,8 +1296,6 @@ static int iscsi_enforce_integrity_rules(
|
||||
char *tmpptr;
|
||||
u8 DataSequenceInOrder = 0;
|
||||
u8 ErrorRecoveryLevel = 0, SessionType = 0;
|
||||
u8 IFMarker = 0, OFMarker = 0;
|
||||
u8 IFMarkInt_Reject = 1, OFMarkInt_Reject = 1;
|
||||
u32 FirstBurstLength = 0, MaxBurstLength = 0;
|
||||
struct iscsi_param *param = NULL;
|
||||
|
||||
@@ -1503,28 +1314,12 @@ static int iscsi_enforce_integrity_rules(
|
||||
if (!strcmp(param->name, MAXBURSTLENGTH))
|
||||
MaxBurstLength = simple_strtoul(param->value,
|
||||
&tmpptr, 0);
|
||||
if (!strcmp(param->name, IFMARKER))
|
||||
if (!strcmp(param->value, YES))
|
||||
IFMarker = 1;
|
||||
if (!strcmp(param->name, OFMARKER))
|
||||
if (!strcmp(param->value, YES))
|
||||
OFMarker = 1;
|
||||
if (!strcmp(param->name, IFMARKINT))
|
||||
if (!strcmp(param->value, REJECT))
|
||||
IFMarkInt_Reject = 1;
|
||||
if (!strcmp(param->name, OFMARKINT))
|
||||
if (!strcmp(param->value, REJECT))
|
||||
OFMarkInt_Reject = 1;
|
||||
}
|
||||
|
||||
list_for_each_entry(param, ¶m_list->param_list, p_list) {
|
||||
if (!(param->phase & phase))
|
||||
continue;
|
||||
if (!SessionType && (!IS_PSTATE_ACCEPTOR(param) &&
|
||||
(strcmp(param->name, IFMARKER) &&
|
||||
strcmp(param->name, OFMARKER) &&
|
||||
strcmp(param->name, IFMARKINT) &&
|
||||
strcmp(param->name, OFMARKINT))))
|
||||
if (!SessionType && !IS_PSTATE_ACCEPTOR(param))
|
||||
continue;
|
||||
if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
|
||||
DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
|
||||
@@ -1556,38 +1351,6 @@ static int iscsi_enforce_integrity_rules(
|
||||
param->name, param->value);
|
||||
}
|
||||
}
|
||||
if (!strcmp(param->name, IFMARKER) && IFMarkInt_Reject) {
|
||||
if (iscsi_update_param_value(param, NO) < 0)
|
||||
return -1;
|
||||
IFMarker = 0;
|
||||
pr_debug("Reset \"%s\" to \"%s\".\n",
|
||||
param->name, param->value);
|
||||
}
|
||||
if (!strcmp(param->name, OFMARKER) && OFMarkInt_Reject) {
|
||||
if (iscsi_update_param_value(param, NO) < 0)
|
||||
return -1;
|
||||
OFMarker = 0;
|
||||
pr_debug("Reset \"%s\" to \"%s\".\n",
|
||||
param->name, param->value);
|
||||
}
|
||||
if (!strcmp(param->name, IFMARKINT) && !IFMarker) {
|
||||
if (!strcmp(param->value, REJECT))
|
||||
continue;
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
if (iscsi_update_param_value(param, IRRELEVANT) < 0)
|
||||
return -1;
|
||||
pr_debug("Reset \"%s\" to \"%s\".\n",
|
||||
param->name, param->value);
|
||||
}
|
||||
if (!strcmp(param->name, OFMARKINT) && !OFMarker) {
|
||||
if (!strcmp(param->value, REJECT))
|
||||
continue;
|
||||
param->state &= ~PSTATE_NEGOTIATE;
|
||||
if (iscsi_update_param_value(param, IRRELEVANT) < 0)
|
||||
return -1;
|
||||
pr_debug("Reset \"%s\" to \"%s\".\n",
|
||||
param->name, param->value);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1824,24 +1587,6 @@ void iscsi_set_connection_parameters(
|
||||
*/
|
||||
pr_debug("MaxRecvDataSegmentLength: %u\n",
|
||||
ops->MaxRecvDataSegmentLength);
|
||||
} else if (!strcmp(param->name, OFMARKER)) {
|
||||
ops->OFMarker = !strcmp(param->value, YES);
|
||||
pr_debug("OFMarker: %s\n",
|
||||
param->value);
|
||||
} else if (!strcmp(param->name, IFMARKER)) {
|
||||
ops->IFMarker = !strcmp(param->value, YES);
|
||||
pr_debug("IFMarker: %s\n",
|
||||
param->value);
|
||||
} else if (!strcmp(param->name, OFMARKINT)) {
|
||||
ops->OFMarkInt =
|
||||
simple_strtoul(param->value, &tmpptr, 0);
|
||||
pr_debug("OFMarkInt: %s\n",
|
||||
param->value);
|
||||
} else if (!strcmp(param->name, IFMARKINT)) {
|
||||
ops->IFMarkInt =
|
||||
simple_strtoul(param->value, &tmpptr, 0);
|
||||
pr_debug("IFMarkInt: %s\n",
|
||||
param->value);
|
||||
} else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
|
||||
ops->InitiatorRecvDataSegmentLength =
|
||||
simple_strtoul(param->value, &tmpptr, 0);
|
||||
|
||||
@@ -138,8 +138,8 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
|
||||
#define INITIAL_SESSIONTYPE NORMAL
|
||||
#define INITIAL_IFMARKER NO
|
||||
#define INITIAL_OFMARKER NO
|
||||
#define INITIAL_IFMARKINT "2048~65535"
|
||||
#define INITIAL_OFMARKINT "2048~65535"
|
||||
#define INITIAL_IFMARKINT REJECT
|
||||
#define INITIAL_OFMARKINT REJECT
|
||||
|
||||
/*
|
||||
* Initial values for iSER parameters following RFC-5046 Section 6
|
||||
@@ -239,10 +239,9 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
|
||||
#define TYPERANGE_AUTH 0x0200
|
||||
#define TYPERANGE_DIGEST 0x0400
|
||||
#define TYPERANGE_ISCSINAME 0x0800
|
||||
#define TYPERANGE_MARKINT 0x1000
|
||||
#define TYPERANGE_SESSIONTYPE 0x2000
|
||||
#define TYPERANGE_TARGETADDRESS 0x4000
|
||||
#define TYPERANGE_UTF8 0x8000
|
||||
#define TYPERANGE_SESSIONTYPE 0x1000
|
||||
#define TYPERANGE_TARGETADDRESS 0x2000
|
||||
#define TYPERANGE_UTF8 0x4000
|
||||
|
||||
#define IS_TYPERANGE_0_TO_2(p) ((p)->type_range & TYPERANGE_0_TO_2)
|
||||
#define IS_TYPERANGE_0_TO_3600(p) ((p)->type_range & TYPERANGE_0_TO_3600)
|
||||
|
||||
@@ -120,7 +120,7 @@ u8 iscsit_tmr_task_reassign(
|
||||
struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
|
||||
struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
|
||||
struct iscsi_tm *hdr = (struct iscsi_tm *) buf;
|
||||
int ret, ref_lun;
|
||||
u64 ret, ref_lun;
|
||||
|
||||
pr_debug("Got TASK_REASSIGN TMR ITT: 0x%08x,"
|
||||
" RefTaskTag: 0x%08x, ExpDataSN: 0x%08x, CID: %hu\n",
|
||||
@@ -164,7 +164,7 @@ u8 iscsit_tmr_task_reassign(
|
||||
ref_lun = scsilun_to_int(&hdr->lun);
|
||||
if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) {
|
||||
pr_err("Unable to perform connection recovery for"
|
||||
" differing ref_lun: %d ref_cmd orig_fe_lun: %u\n",
|
||||
" differing ref_lun: %llu ref_cmd orig_fe_lun: %llu\n",
|
||||
ref_lun, ref_cmd->se_cmd.orig_fe_lun);
|
||||
return ISCSI_TMF_RSP_REJECTED;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
|
||||
#include <target/iscsi/iscsi_target_core.h>
|
||||
#include "iscsi_target_erl0.h"
|
||||
@@ -67,9 +66,12 @@ int iscsit_load_discovery_tpg(void)
|
||||
pr_err("Unable to allocate struct iscsi_portal_group\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = core_tpg_register(&iscsi_ops, NULL, &tpg->tpg_se_tpg,
|
||||
tpg, TRANSPORT_TPG_TYPE_DISCOVERY);
|
||||
/*
|
||||
* Save iscsi_ops pointer for special case discovery TPG that
|
||||
* doesn't exist as se_wwn->wwn_group within configfs.
|
||||
*/
|
||||
tpg->tpg_se_tpg.se_tpg_tfo = &iscsi_ops;
|
||||
ret = core_tpg_register(NULL, &tpg->tpg_se_tpg, -1);
|
||||
if (ret < 0) {
|
||||
kfree(tpg);
|
||||
return -1;
|
||||
@@ -280,8 +282,6 @@ int iscsit_tpg_del_portal_group(
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
core_tpg_clear_object_luns(&tpg->tpg_se_tpg);
|
||||
|
||||
if (tpg->param_list) {
|
||||
iscsi_release_param_list(tpg->param_list);
|
||||
tpg->param_list = NULL;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <scsi/iscsi_proto.h>
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
#include <target/iscsi/iscsi_transport.h>
|
||||
|
||||
#include <target/iscsi/iscsi_target_core.h>
|
||||
@@ -746,7 +745,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
|
||||
rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
|
||||
if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
|
||||
__iscsit_free_cmd(cmd, true, shutdown);
|
||||
target_put_sess_cmd(se_cmd->se_sess, se_cmd);
|
||||
target_put_sess_cmd(se_cmd);
|
||||
}
|
||||
break;
|
||||
case ISCSI_OP_REJECT:
|
||||
@@ -762,7 +761,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
|
||||
rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
|
||||
if (!rc && shutdown && se_cmd->se_sess) {
|
||||
__iscsit_free_cmd(cmd, true, shutdown);
|
||||
target_put_sess_cmd(se_cmd->se_sess, se_cmd);
|
||||
target_put_sess_cmd(se_cmd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -809,54 +808,6 @@ void iscsit_inc_session_usage_count(struct iscsi_session *sess)
|
||||
spin_unlock_bh(&sess->session_usage_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup conn->if_marker and conn->of_marker values based upon
|
||||
* the initial marker-less interval. (see iSCSI v19 A.2)
|
||||
*/
|
||||
int iscsit_set_sync_and_steering_values(struct iscsi_conn *conn)
|
||||
{
|
||||
int login_ifmarker_count = 0, login_ofmarker_count = 0, next_marker = 0;
|
||||
/*
|
||||
* IFMarkInt and OFMarkInt are negotiated as 32-bit words.
|
||||
*/
|
||||
u32 IFMarkInt = (conn->conn_ops->IFMarkInt * 4);
|
||||
u32 OFMarkInt = (conn->conn_ops->OFMarkInt * 4);
|
||||
|
||||
if (conn->conn_ops->OFMarker) {
|
||||
/*
|
||||
* Account for the first Login Command received not
|
||||
* via iscsi_recv_msg().
|
||||
*/
|
||||
conn->of_marker += ISCSI_HDR_LEN;
|
||||
if (conn->of_marker <= OFMarkInt) {
|
||||
conn->of_marker = (OFMarkInt - conn->of_marker);
|
||||
} else {
|
||||
login_ofmarker_count = (conn->of_marker / OFMarkInt);
|
||||
next_marker = (OFMarkInt * (login_ofmarker_count + 1)) +
|
||||
(login_ofmarker_count * MARKER_SIZE);
|
||||
conn->of_marker = (next_marker - conn->of_marker);
|
||||
}
|
||||
conn->of_marker_offset = 0;
|
||||
pr_debug("Setting OFMarker value to %u based on Initial"
|
||||
" Markerless Interval.\n", conn->of_marker);
|
||||
}
|
||||
|
||||
if (conn->conn_ops->IFMarker) {
|
||||
if (conn->if_marker <= IFMarkInt) {
|
||||
conn->if_marker = (IFMarkInt - conn->if_marker);
|
||||
} else {
|
||||
login_ifmarker_count = (conn->if_marker / IFMarkInt);
|
||||
next_marker = (IFMarkInt * (login_ifmarker_count + 1)) +
|
||||
(login_ifmarker_count * MARKER_SIZE);
|
||||
conn->if_marker = (next_marker - conn->if_marker);
|
||||
}
|
||||
pr_debug("Setting IFMarker value to %u based on Initial"
|
||||
" Markerless Interval.\n", conn->if_marker);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *sess, u16 cid)
|
||||
{
|
||||
struct iscsi_conn *conn;
|
||||
|
||||
@@ -34,7 +34,6 @@ extern void iscsit_free_cmd(struct iscsi_cmd *, bool);
|
||||
extern int iscsit_check_session_usage_count(struct iscsi_session *);
|
||||
extern void iscsit_dec_session_usage_count(struct iscsi_session *);
|
||||
extern void iscsit_inc_session_usage_count(struct iscsi_session *);
|
||||
extern int iscsit_set_sync_and_steering_values(struct iscsi_conn *);
|
||||
extern struct iscsi_conn *iscsit_get_conn_from_cid(struct iscsi_session *, u16);
|
||||
extern struct iscsi_conn *iscsit_get_conn_from_cid_rcfr(struct iscsi_session *, u16);
|
||||
extern void iscsit_check_conn_usage_count(struct iscsi_conn *);
|
||||
|
||||
@@ -35,14 +35,11 @@
|
||||
#include <target/target_core_base.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
|
||||
#include "tcm_loop.h"
|
||||
|
||||
#define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev)
|
||||
|
||||
static const struct target_core_fabric_ops loop_ops;
|
||||
|
||||
static struct workqueue_struct *tcm_loop_workqueue;
|
||||
static struct kmem_cache *tcm_loop_cmd_cache;
|
||||
|
||||
@@ -165,6 +162,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
|
||||
transfer_length = scsi_bufflen(sc);
|
||||
}
|
||||
|
||||
se_cmd->tag = tl_cmd->sc_cmd_tag;
|
||||
rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
|
||||
&tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
|
||||
transfer_length, TCM_SIMPLE_TAG,
|
||||
@@ -217,7 +215,7 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc)
|
||||
* to struct scsi_device
|
||||
*/
|
||||
static int tcm_loop_issue_tmr(struct tcm_loop_tpg *tl_tpg,
|
||||
int lun, int task, enum tcm_tmreq_table tmr)
|
||||
u64 lun, int task, enum tcm_tmreq_table tmr)
|
||||
{
|
||||
struct se_cmd *se_cmd = NULL;
|
||||
struct se_session *se_sess;
|
||||
@@ -409,7 +407,7 @@ static int tcm_loop_driver_probe(struct device *dev)
|
||||
sh->max_id = 2;
|
||||
sh->max_lun = 0;
|
||||
sh->max_channel = 0;
|
||||
sh->max_cmd_len = TL_SCSI_MAX_CMD_LEN;
|
||||
sh->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
|
||||
|
||||
host_prot = SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION |
|
||||
SHOST_DIF_TYPE3_PROTECTION | SHOST_DIX_TYPE1_PROTECTION |
|
||||
@@ -520,147 +518,26 @@ static char *tcm_loop_get_fabric_name(void)
|
||||
return "loopback";
|
||||
}
|
||||
|
||||
static u8 tcm_loop_get_fabric_proto_ident(struct se_portal_group *se_tpg)
|
||||
static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
/*
|
||||
* tl_proto_id is set at tcm_loop_configfs.c:tcm_loop_make_scsi_hba()
|
||||
* time based on the protocol dependent prefix of the passed configfs group.
|
||||
*
|
||||
* Based upon tl_proto_id, TCM_Loop emulates the requested fabric
|
||||
* ProtocolID using target_core_fabric_lib.c symbols.
|
||||
*/
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_fabric_proto_ident(se_tpg);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_fabric_proto_ident(se_tpg);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_fabric_proto_ident(se_tpg);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_fabric_proto_ident(se_tpg);
|
||||
return container_of(se_tpg, struct tcm_loop_tpg, tl_se_tpg);
|
||||
}
|
||||
|
||||
static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
/*
|
||||
* Return the passed NAA identifier for the SAS Target Port
|
||||
*/
|
||||
return &tl_tpg->tl_hba->tl_wwn_address[0];
|
||||
return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0];
|
||||
}
|
||||
|
||||
static u16 tcm_loop_get_tag(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
/*
|
||||
* This Tag is used when forming SCSI Name identifier in EVPD=1 0x83
|
||||
* to represent the SCSI Target Port.
|
||||
*/
|
||||
return tl_tpg->tl_tpgt;
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_default_depth(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,
|
||||
format_code, buf);
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,
|
||||
format_code);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
|
||||
* Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
|
||||
*/
|
||||
static char *tcm_loop_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
struct tcm_loop_tpg *tl_tpg = se_tpg->se_tpg_fabric_ptr;
|
||||
struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
|
||||
|
||||
switch (tl_hba->tl_proto_id) {
|
||||
case SCSI_PROTOCOL_SAS:
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_FCP:
|
||||
return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
case SCSI_PROTOCOL_ISCSI:
|
||||
return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
default:
|
||||
pr_err("Unknown tl_proto_id: 0x%02x, using"
|
||||
" SAS emulation\n", tl_hba->tl_proto_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,
|
||||
port_nexus_ptr);
|
||||
return tl_tpg(se_tpg)->tl_tpgt;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -703,30 +580,6 @@ static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg)
|
||||
return tl_tpg->tl_fabric_prot_type;
|
||||
}
|
||||
|
||||
static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl(
|
||||
struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct tcm_loop_nacl *tl_nacl;
|
||||
|
||||
tl_nacl = kzalloc(sizeof(struct tcm_loop_nacl), GFP_KERNEL);
|
||||
if (!tl_nacl) {
|
||||
pr_err("Unable to allocate struct tcm_loop_nacl\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &tl_nacl->se_node_acl;
|
||||
}
|
||||
|
||||
static void tcm_loop_tpg_release_fabric_acl(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl)
|
||||
{
|
||||
struct tcm_loop_nacl *tl_nacl = container_of(se_nacl,
|
||||
struct tcm_loop_nacl, se_node_acl);
|
||||
|
||||
kfree(tl_nacl);
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
@@ -742,14 +595,6 @@ static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
|
||||
return;
|
||||
}
|
||||
|
||||
static u32 tcm_loop_get_task_tag(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
|
||||
struct tcm_loop_cmd, tl_se_cmd);
|
||||
|
||||
return tl_cmd->sc_cmd_tag;
|
||||
}
|
||||
|
||||
static int tcm_loop_get_cmd_state(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
|
||||
@@ -902,7 +747,7 @@ static void tcm_loop_port_unlink(
|
||||
se_lun->unpacked_lun);
|
||||
if (!sd) {
|
||||
pr_err("Unable to locate struct scsi_device for %d:%d:"
|
||||
"%d\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
|
||||
"%llu\n", 0, tl_tpg->tl_tpgt, se_lun->unpacked_lun);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@@ -1234,8 +1079,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
|
||||
/*
|
||||
* Register the tl_tpg as a emulated SAS TCM Target Endpoint
|
||||
*/
|
||||
ret = core_tpg_register(&loop_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg,
|
||||
TRANSPORT_TPG_TYPE_NORMAL);
|
||||
ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -1386,13 +1230,8 @@ static const struct target_core_fabric_ops loop_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "loopback",
|
||||
.get_fabric_name = tcm_loop_get_fabric_name,
|
||||
.get_fabric_proto_ident = tcm_loop_get_fabric_proto_ident,
|
||||
.tpg_get_wwn = tcm_loop_get_endpoint_wwn,
|
||||
.tpg_get_tag = tcm_loop_get_tag,
|
||||
.tpg_get_default_depth = tcm_loop_get_default_depth,
|
||||
.tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = tcm_loop_check_demo_mode,
|
||||
.tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache,
|
||||
.tpg_check_demo_mode_write_protect =
|
||||
@@ -1400,8 +1239,6 @@ static const struct target_core_fabric_ops loop_ops = {
|
||||
.tpg_check_prod_mode_write_protect =
|
||||
tcm_loop_check_prod_mode_write_protect,
|
||||
.tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only,
|
||||
.tpg_alloc_fabric_acl = tcm_loop_tpg_alloc_fabric_acl,
|
||||
.tpg_release_fabric_acl = tcm_loop_tpg_release_fabric_acl,
|
||||
.tpg_get_inst_index = tcm_loop_get_inst_index,
|
||||
.check_stop_free = tcm_loop_check_stop_free,
|
||||
.release_cmd = tcm_loop_release_cmd,
|
||||
@@ -1411,7 +1248,6 @@ static const struct target_core_fabric_ops loop_ops = {
|
||||
.write_pending = tcm_loop_write_pending,
|
||||
.write_pending_status = tcm_loop_write_pending_status,
|
||||
.set_default_node_attributes = tcm_loop_set_default_node_attributes,
|
||||
.get_task_tag = tcm_loop_get_task_tag,
|
||||
.get_cmd_state = tcm_loop_get_cmd_state,
|
||||
.queue_data_in = tcm_loop_queue_data_in,
|
||||
.queue_status = tcm_loop_queue_status,
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
#define TL_WWN_ADDR_LEN 256
|
||||
#define TL_TPGS_PER_HBA 32
|
||||
|
||||
/*
|
||||
* Used in tcm_loop_driver_probe() for struct Scsi_Host->max_cmd_len
|
||||
*/
|
||||
#define TL_SCSI_MAX_CMD_LEN 32
|
||||
|
||||
struct tcm_loop_cmd {
|
||||
/* State of Linux/SCSI CDB+Data descriptor */
|
||||
u32 sc_cmd_state;
|
||||
@@ -33,10 +28,6 @@ struct tcm_loop_nexus {
|
||||
struct se_session *se_sess;
|
||||
};
|
||||
|
||||
struct tcm_loop_nacl {
|
||||
struct se_node_acl se_node_acl;
|
||||
};
|
||||
|
||||
#define TCM_TRANSPORT_ONLINE 0
|
||||
#define TCM_TRANSPORT_OFFLINE 1
|
||||
|
||||
|
||||
+53
-222
@@ -36,7 +36,6 @@
|
||||
#include <target/target_core_backend.h>
|
||||
#include <target/target_core_fabric.h>
|
||||
#include <target/target_core_fabric_configfs.h>
|
||||
#include <target/target_core_configfs.h>
|
||||
#include <target/configfs_macros.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
@@ -109,13 +108,13 @@ static struct sbp_session *sbp_session_find_by_guid(
|
||||
}
|
||||
|
||||
static struct sbp_login_descriptor *sbp_login_find_by_lun(
|
||||
struct sbp_session *session, struct se_lun *lun)
|
||||
struct sbp_session *session, u32 unpacked_lun)
|
||||
{
|
||||
struct sbp_login_descriptor *login, *found = NULL;
|
||||
|
||||
spin_lock_bh(&session->lock);
|
||||
list_for_each_entry(login, &session->login_list, link) {
|
||||
if (login->lun == lun)
|
||||
if (login->login_lun == unpacked_lun)
|
||||
found = login;
|
||||
}
|
||||
spin_unlock_bh(&session->lock);
|
||||
@@ -125,7 +124,7 @@ static struct sbp_login_descriptor *sbp_login_find_by_lun(
|
||||
|
||||
static int sbp_login_count_all_by_lun(
|
||||
struct sbp_tpg *tpg,
|
||||
struct se_lun *lun,
|
||||
u32 unpacked_lun,
|
||||
int exclusive)
|
||||
{
|
||||
struct se_session *se_sess;
|
||||
@@ -139,7 +138,7 @@ static int sbp_login_count_all_by_lun(
|
||||
|
||||
spin_lock_bh(&sess->lock);
|
||||
list_for_each_entry(login, &sess->login_list, link) {
|
||||
if (login->lun != lun)
|
||||
if (login->login_lun != unpacked_lun)
|
||||
continue;
|
||||
|
||||
if (!exclusive || login->exclusive)
|
||||
@@ -175,23 +174,23 @@ static struct sbp_login_descriptor *sbp_login_find_by_id(
|
||||
return found;
|
||||
}
|
||||
|
||||
static struct se_lun *sbp_get_lun_from_tpg(struct sbp_tpg *tpg, int lun)
|
||||
static u32 sbp_get_lun_from_tpg(struct sbp_tpg *tpg, u32 login_lun, int *err)
|
||||
{
|
||||
struct se_portal_group *se_tpg = &tpg->se_tpg;
|
||||
struct se_lun *se_lun;
|
||||
|
||||
if (lun >= TRANSPORT_MAX_LUNS_PER_TPG)
|
||||
return ERR_PTR(-EINVAL);
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(se_lun, &se_tpg->tpg_lun_hlist, link) {
|
||||
if (se_lun->unpacked_lun == login_lun) {
|
||||
rcu_read_unlock();
|
||||
*err = 0;
|
||||
return login_lun;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
spin_lock(&se_tpg->tpg_lun_lock);
|
||||
se_lun = se_tpg->tpg_lun_list[lun];
|
||||
|
||||
if (se_lun->lun_status != TRANSPORT_LUN_STATUS_ACTIVE)
|
||||
se_lun = ERR_PTR(-ENODEV);
|
||||
|
||||
spin_unlock(&se_tpg->tpg_lun_lock);
|
||||
|
||||
return se_lun;
|
||||
*err = -ENODEV;
|
||||
return login_lun;
|
||||
}
|
||||
|
||||
static struct sbp_session *sbp_session_create(
|
||||
@@ -295,17 +294,16 @@ static void sbp_management_request_login(
|
||||
{
|
||||
struct sbp_tport *tport = agent->tport;
|
||||
struct sbp_tpg *tpg = tport->tpg;
|
||||
struct se_lun *se_lun;
|
||||
int ret;
|
||||
u64 guid;
|
||||
struct sbp_session *sess;
|
||||
struct sbp_login_descriptor *login;
|
||||
struct sbp_login_response_block *response;
|
||||
int login_response_len;
|
||||
u64 guid;
|
||||
u32 unpacked_lun;
|
||||
int login_response_len, ret;
|
||||
|
||||
se_lun = sbp_get_lun_from_tpg(tpg,
|
||||
LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)));
|
||||
if (IS_ERR(se_lun)) {
|
||||
unpacked_lun = sbp_get_lun_from_tpg(tpg,
|
||||
LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)), &ret);
|
||||
if (ret) {
|
||||
pr_notice("login to unknown LUN: %d\n",
|
||||
LOGIN_ORB_LUN(be32_to_cpu(req->orb.misc)));
|
||||
|
||||
@@ -326,11 +324,11 @@ static void sbp_management_request_login(
|
||||
}
|
||||
|
||||
pr_notice("mgt_agent LOGIN to LUN %d from %016llx\n",
|
||||
se_lun->unpacked_lun, guid);
|
||||
unpacked_lun, guid);
|
||||
|
||||
sess = sbp_session_find_by_guid(tpg, guid);
|
||||
if (sess) {
|
||||
login = sbp_login_find_by_lun(sess, se_lun);
|
||||
login = sbp_login_find_by_lun(sess, unpacked_lun);
|
||||
if (login) {
|
||||
pr_notice("initiator already logged-in\n");
|
||||
|
||||
@@ -358,7 +356,7 @@ static void sbp_management_request_login(
|
||||
* reject with access_denied if any logins present
|
||||
*/
|
||||
if (LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc)) &&
|
||||
sbp_login_count_all_by_lun(tpg, se_lun, 0)) {
|
||||
sbp_login_count_all_by_lun(tpg, unpacked_lun, 0)) {
|
||||
pr_warn("refusing exclusive login with other active logins\n");
|
||||
|
||||
req->status.status = cpu_to_be32(
|
||||
@@ -371,7 +369,7 @@ static void sbp_management_request_login(
|
||||
* check exclusive bit in any existing login descriptor
|
||||
* reject with access_denied if any exclusive logins present
|
||||
*/
|
||||
if (sbp_login_count_all_by_lun(tpg, se_lun, 1)) {
|
||||
if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 1)) {
|
||||
pr_warn("refusing login while another exclusive login present\n");
|
||||
|
||||
req->status.status = cpu_to_be32(
|
||||
@@ -384,7 +382,7 @@ static void sbp_management_request_login(
|
||||
* check we haven't exceeded the number of allowed logins
|
||||
* reject with resources_unavailable if we have
|
||||
*/
|
||||
if (sbp_login_count_all_by_lun(tpg, se_lun, 0) >=
|
||||
if (sbp_login_count_all_by_lun(tpg, unpacked_lun, 0) >=
|
||||
tport->max_logins_per_lun) {
|
||||
pr_warn("max number of logins reached\n");
|
||||
|
||||
@@ -440,7 +438,7 @@ static void sbp_management_request_login(
|
||||
}
|
||||
|
||||
login->sess = sess;
|
||||
login->lun = se_lun;
|
||||
login->login_lun = unpacked_lun;
|
||||
login->status_fifo_addr = sbp2_pointer_to_addr(&req->orb.status_fifo);
|
||||
login->exclusive = LOGIN_ORB_EXCLUSIVE(be32_to_cpu(req->orb.misc));
|
||||
login->login_id = atomic_inc_return(&login_id);
|
||||
@@ -602,7 +600,7 @@ static void sbp_management_request_logout(
|
||||
}
|
||||
|
||||
pr_info("mgt_agent LOGOUT from LUN %d session %d\n",
|
||||
login->lun->unpacked_lun, login->login_id);
|
||||
login->login_lun, login->login_id);
|
||||
|
||||
if (req->node_addr != login->sess->node_id) {
|
||||
pr_warn("logout from different node ID\n");
|
||||
@@ -1228,12 +1226,14 @@ static void sbp_handle_command(struct sbp_target_request *req)
|
||||
goto err;
|
||||
}
|
||||
|
||||
unpacked_lun = req->login->lun->unpacked_lun;
|
||||
unpacked_lun = req->login->login_lun;
|
||||
sbp_calc_data_length_direction(req, &data_length, &data_dir);
|
||||
|
||||
pr_debug("sbp_handle_command ORB:0x%llx unpacked_lun:%d data_len:%d data_dir:%d\n",
|
||||
req->orb_pointer, unpacked_lun, data_length, data_dir);
|
||||
|
||||
/* only used for printk until we do TMRs */
|
||||
req->se_cmd.tag = req->orb_pointer;
|
||||
if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf,
|
||||
req->sense_buf, unpacked_lun, data_length,
|
||||
TCM_SIMPLE_TAG, data_dir, 0))
|
||||
@@ -1707,33 +1707,6 @@ static u16 sbp_get_tag(struct se_portal_group *se_tpg)
|
||||
return tpg->tport_tpgt;
|
||||
}
|
||||
|
||||
static u32 sbp_get_default_depth(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct se_node_acl *sbp_alloc_fabric_acl(struct se_portal_group *se_tpg)
|
||||
{
|
||||
struct sbp_nacl *nacl;
|
||||
|
||||
nacl = kzalloc(sizeof(struct sbp_nacl), GFP_KERNEL);
|
||||
if (!nacl) {
|
||||
pr_err("Unable to allocate struct sbp_nacl\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &nacl->se_node_acl;
|
||||
}
|
||||
|
||||
static void sbp_release_fabric_acl(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl)
|
||||
{
|
||||
struct sbp_nacl *nacl =
|
||||
container_of(se_nacl, struct sbp_nacl, se_node_acl);
|
||||
kfree(nacl);
|
||||
}
|
||||
|
||||
static u32 sbp_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
||||
{
|
||||
return 1;
|
||||
@@ -1795,15 +1768,6 @@ static void sbp_set_default_node_attrs(struct se_node_acl *nacl)
|
||||
return;
|
||||
}
|
||||
|
||||
static u32 sbp_get_task_tag(struct se_cmd *se_cmd)
|
||||
{
|
||||
struct sbp_target_request *req = container_of(se_cmd,
|
||||
struct sbp_target_request, se_cmd);
|
||||
|
||||
/* only used for printk until we do TMRs */
|
||||
return (u32)req->orb_pointer;
|
||||
}
|
||||
|
||||
static int sbp_get_cmd_state(struct se_cmd *se_cmd)
|
||||
{
|
||||
return 0;
|
||||
@@ -1859,106 +1823,23 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handlers for Serial Bus Protocol 2/3 (SBP-2 / SBP-3)
|
||||
*/
|
||||
static u8 sbp_get_fabric_proto_ident(struct se_portal_group *se_tpg)
|
||||
{
|
||||
/*
|
||||
* Return a IEEE 1394 SCSI Protocol identifier for loopback operations
|
||||
* This is defined in section 7.5.1 Table 362 in spc4r17
|
||||
*/
|
||||
return SCSI_PROTOCOL_SBP;
|
||||
}
|
||||
|
||||
static u32 sbp_get_pr_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code,
|
||||
unsigned char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Set PROTOCOL IDENTIFIER to 3h for SBP
|
||||
*/
|
||||
buf[0] = SCSI_PROTOCOL_SBP;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
|
||||
* over IEEE 1394
|
||||
*/
|
||||
ret = hex2bin(&buf[8], se_nacl->initiatorname, 8);
|
||||
if (ret < 0)
|
||||
pr_debug("sbp transport_id: invalid hex string\n");
|
||||
|
||||
/*
|
||||
* The IEEE 1394 Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
|
||||
static u32 sbp_get_pr_transport_id_len(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct se_node_acl *se_nacl,
|
||||
struct t10_pr_registration *pr_reg,
|
||||
int *format_code)
|
||||
{
|
||||
*format_code = 0;
|
||||
/*
|
||||
* From spc4r17, 7.5.4.4 TransportID for initiator ports using SCSI
|
||||
* over IEEE 1394
|
||||
*
|
||||
* The SBP Transport ID is a hardcoded 24-byte length
|
||||
*/
|
||||
return 24;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for handling SCSI fabric dependent TransportIDs in SPC-3 and above
|
||||
* Persistent Reservation SPEC_I_PT=1 and PROUT REGISTER_AND_MOVE operations.
|
||||
*/
|
||||
static char *sbp_parse_pr_out_transport_id(
|
||||
struct se_portal_group *se_tpg,
|
||||
const char *buf,
|
||||
u32 *out_tid_len,
|
||||
char **port_nexus_ptr)
|
||||
{
|
||||
/*
|
||||
* Assume the FORMAT CODE 00b from spc4r17, 7.5.4.4 TransportID
|
||||
* for initiator ports using SCSI over SBP Serial SCSI Protocol
|
||||
*
|
||||
* The TransportID for a IEEE 1394 Initiator Port is of fixed size of
|
||||
* 24 bytes, and IEEE 1394 does not contain a I_T nexus identifier,
|
||||
* so we return the **port_nexus_ptr set to NULL.
|
||||
*/
|
||||
*port_nexus_ptr = NULL;
|
||||
*out_tid_len = 24;
|
||||
|
||||
return (char *)&buf[8];
|
||||
}
|
||||
|
||||
static int sbp_count_se_tpg_luns(struct se_portal_group *tpg)
|
||||
{
|
||||
int i, count = 0;
|
||||
|
||||
spin_lock(&tpg->tpg_lun_lock);
|
||||
for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
|
||||
struct se_lun *se_lun = tpg->tpg_lun_list[i];
|
||||
|
||||
if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE)
|
||||
continue;
|
||||
struct se_lun *lun;
|
||||
int count = 0;
|
||||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(lun, &tpg->tpg_lun_hlist, link)
|
||||
count++;
|
||||
}
|
||||
spin_unlock(&tpg->tpg_lun_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int sbp_update_unit_directory(struct sbp_tport *tport)
|
||||
{
|
||||
int num_luns, num_entries, idx = 0, mgt_agt_addr, ret, i;
|
||||
struct se_lun *lun;
|
||||
int num_luns, num_entries, idx = 0, mgt_agt_addr, ret;
|
||||
u32 *data;
|
||||
|
||||
if (tport->unit_directory.data) {
|
||||
@@ -2020,28 +1901,23 @@ static int sbp_update_unit_directory(struct sbp_tport *tport)
|
||||
/* unit unique ID (leaf is just after LUNs) */
|
||||
data[idx++] = 0x8d000000 | (num_luns + 1);
|
||||
|
||||
spin_lock(&tport->tpg->se_tpg.tpg_lun_lock);
|
||||
for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) {
|
||||
struct se_lun *se_lun = tport->tpg->se_tpg.tpg_lun_list[i];
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(lun, &tport->tpg->se_tpg.tpg_lun_hlist, link) {
|
||||
struct se_device *dev;
|
||||
int type;
|
||||
|
||||
if (se_lun->lun_status == TRANSPORT_LUN_STATUS_FREE)
|
||||
continue;
|
||||
|
||||
spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock);
|
||||
|
||||
dev = se_lun->lun_se_dev;
|
||||
/*
|
||||
* rcu_dereference_raw protected by se_lun->lun_group symlink
|
||||
* reference to se_device->dev_group.
|
||||
*/
|
||||
dev = rcu_dereference_raw(lun->lun_se_dev);
|
||||
type = dev->transport->get_device_type(dev);
|
||||
|
||||
/* logical_unit_number */
|
||||
data[idx++] = 0x14000000 |
|
||||
((type << 16) & 0x1f0000) |
|
||||
(se_lun->unpacked_lun & 0xffff);
|
||||
|
||||
spin_lock(&tport->tpg->se_tpg.tpg_lun_lock);
|
||||
(lun->unpacked_lun & 0xffff);
|
||||
}
|
||||
spin_unlock(&tport->tpg->se_tpg.tpg_lun_lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
/* unit unique ID leaf */
|
||||
data[idx++] = 2 << 16;
|
||||
@@ -2100,48 +1976,13 @@ static ssize_t sbp_format_wwn(char *buf, size_t len, u64 wwn)
|
||||
return snprintf(buf, len, "%016llx", wwn);
|
||||
}
|
||||
|
||||
static struct se_node_acl *sbp_make_nodeacl(
|
||||
struct se_portal_group *se_tpg,
|
||||
struct config_group *group,
|
||||
const char *name)
|
||||
static int sbp_init_nodeacl(struct se_node_acl *se_nacl, const char *name)
|
||||
{
|
||||
struct se_node_acl *se_nacl, *se_nacl_new;
|
||||
struct sbp_nacl *nacl;
|
||||
u64 guid = 0;
|
||||
u32 nexus_depth = 1;
|
||||
|
||||
if (sbp_parse_wwn(name, &guid) < 0)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
se_nacl_new = sbp_alloc_fabric_acl(se_tpg);
|
||||
if (!se_nacl_new)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/*
|
||||
* se_nacl_new may be released by core_tpg_add_initiator_node_acl()
|
||||
* when converting a NodeACL from demo mode -> explict
|
||||
*/
|
||||
se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,
|
||||
name, nexus_depth);
|
||||
if (IS_ERR(se_nacl)) {
|
||||
sbp_release_fabric_acl(se_tpg, se_nacl_new);
|
||||
return se_nacl;
|
||||
}
|
||||
|
||||
nacl = container_of(se_nacl, struct sbp_nacl, se_node_acl);
|
||||
nacl->guid = guid;
|
||||
sbp_format_wwn(nacl->iport_name, SBP_NAMELEN, guid);
|
||||
|
||||
return se_nacl;
|
||||
}
|
||||
|
||||
static void sbp_drop_nodeacl(struct se_node_acl *se_acl)
|
||||
{
|
||||
struct sbp_nacl *nacl =
|
||||
container_of(se_acl, struct sbp_nacl, se_node_acl);
|
||||
|
||||
core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);
|
||||
kfree(nacl);
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sbp_post_link_lun(
|
||||
@@ -2214,8 +2055,7 @@ static struct se_portal_group *sbp_make_tpg(
|
||||
goto out_free_tpg;
|
||||
}
|
||||
|
||||
ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, tpg,
|
||||
TRANSPORT_TPG_TYPE_NORMAL);
|
||||
ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SBP);
|
||||
if (ret < 0)
|
||||
goto out_unreg_mgt_agt;
|
||||
|
||||
@@ -2505,19 +2345,12 @@ static const struct target_core_fabric_ops sbp_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "sbp",
|
||||
.get_fabric_name = sbp_get_fabric_name,
|
||||
.get_fabric_proto_ident = sbp_get_fabric_proto_ident,
|
||||
.tpg_get_wwn = sbp_get_fabric_wwn,
|
||||
.tpg_get_tag = sbp_get_tag,
|
||||
.tpg_get_default_depth = sbp_get_default_depth,
|
||||
.tpg_get_pr_transport_id = sbp_get_pr_transport_id,
|
||||
.tpg_get_pr_transport_id_len = sbp_get_pr_transport_id_len,
|
||||
.tpg_parse_pr_out_transport_id = sbp_parse_pr_out_transport_id,
|
||||
.tpg_check_demo_mode = sbp_check_true,
|
||||
.tpg_check_demo_mode_cache = sbp_check_true,
|
||||
.tpg_check_demo_mode_write_protect = sbp_check_false,
|
||||
.tpg_check_prod_mode_write_protect = sbp_check_false,
|
||||
.tpg_alloc_fabric_acl = sbp_alloc_fabric_acl,
|
||||
.tpg_release_fabric_acl = sbp_release_fabric_acl,
|
||||
.tpg_get_inst_index = sbp_tpg_get_inst_index,
|
||||
.release_cmd = sbp_release_cmd,
|
||||
.shutdown_session = sbp_shutdown_session,
|
||||
@@ -2526,7 +2359,6 @@ static const struct target_core_fabric_ops sbp_ops = {
|
||||
.write_pending = sbp_write_pending,
|
||||
.write_pending_status = sbp_write_pending_status,
|
||||
.set_default_node_attributes = sbp_set_default_node_attrs,
|
||||
.get_task_tag = sbp_get_task_tag,
|
||||
.get_cmd_state = sbp_get_cmd_state,
|
||||
.queue_data_in = sbp_queue_data_in,
|
||||
.queue_status = sbp_queue_status,
|
||||
@@ -2542,8 +2374,7 @@ static const struct target_core_fabric_ops sbp_ops = {
|
||||
.fabric_pre_unlink = sbp_pre_unlink_lun,
|
||||
.fabric_make_np = NULL,
|
||||
.fabric_drop_np = NULL,
|
||||
.fabric_make_nodeacl = sbp_make_nodeacl,
|
||||
.fabric_drop_nodeacl = sbp_drop_nodeacl,
|
||||
.fabric_init_nodeacl = sbp_init_nodeacl,
|
||||
|
||||
.tfc_wwn_attrs = sbp_wwn_attrs,
|
||||
.tfc_tpg_base_attrs = sbp_tpg_base_attrs,
|
||||
|
||||
@@ -125,7 +125,7 @@ struct sbp_login_descriptor {
|
||||
struct sbp_session *sess;
|
||||
struct list_head link;
|
||||
|
||||
struct se_lun *lun;
|
||||
u32 login_lun;
|
||||
|
||||
u64 status_fifo_addr;
|
||||
int exclusive;
|
||||
@@ -151,15 +151,6 @@ struct sbp_session {
|
||||
u64 reconnect_expires;
|
||||
};
|
||||
|
||||
struct sbp_nacl {
|
||||
/* Initiator EUI-64 */
|
||||
u64 guid;
|
||||
/* ASCII formatted GUID for SBP Initiator port */
|
||||
char iport_name[SBP_NAMELEN];
|
||||
/* Returned by sbp_make_nodeacl() */
|
||||
struct se_node_acl se_node_acl;
|
||||
};
|
||||
|
||||
struct sbp_tpg {
|
||||
/* Target portal group tag for TCM */
|
||||
u16 tport_tpgt;
|
||||
|
||||
+200
-263
File diff suppressed because it is too large
Load Diff
@@ -85,7 +85,6 @@
|
||||
extern struct kmem_cache *t10_alua_lu_gp_cache;
|
||||
extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
|
||||
extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
|
||||
extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
|
||||
extern struct kmem_cache *t10_alua_lba_map_cache;
|
||||
extern struct kmem_cache *t10_alua_lba_map_mem_cache;
|
||||
|
||||
@@ -94,7 +93,7 @@ extern sense_reason_t target_emulate_set_target_port_groups(struct se_cmd *);
|
||||
extern sense_reason_t target_emulate_report_referrals(struct se_cmd *);
|
||||
extern int core_alua_check_nonop_delay(struct se_cmd *);
|
||||
extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
|
||||
struct se_device *, struct se_port *,
|
||||
struct se_device *, struct se_lun *,
|
||||
struct se_node_acl *, int, int);
|
||||
extern char *core_alua_dump_status(int);
|
||||
extern struct t10_alua_lba_map *core_alua_allocate_lba_map(
|
||||
@@ -117,14 +116,11 @@ extern void core_alua_drop_lu_gp_dev(struct se_device *);
|
||||
extern struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
|
||||
struct se_device *, const char *, int);
|
||||
extern int core_alua_set_tg_pt_gp_id(struct t10_alua_tg_pt_gp *, u16);
|
||||
extern struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem(
|
||||
struct se_port *);
|
||||
extern void core_alua_free_tg_pt_gp(struct t10_alua_tg_pt_gp *);
|
||||
extern void core_alua_free_tg_pt_gp_mem(struct se_port *);
|
||||
extern void __core_alua_attach_tg_pt_gp_mem(struct t10_alua_tg_pt_gp_member *,
|
||||
struct t10_alua_tg_pt_gp *);
|
||||
extern ssize_t core_alua_show_tg_pt_gp_info(struct se_port *, char *);
|
||||
extern ssize_t core_alua_store_tg_pt_gp_info(struct se_port *, const char *,
|
||||
extern void target_detach_tg_pt_gp(struct se_lun *);
|
||||
extern void target_attach_tg_pt_gp(struct se_lun *, struct t10_alua_tg_pt_gp *);
|
||||
extern ssize_t core_alua_show_tg_pt_gp_info(struct se_lun *, char *);
|
||||
extern ssize_t core_alua_store_tg_pt_gp_info(struct se_lun *, const char *,
|
||||
size_t);
|
||||
extern ssize_t core_alua_show_access_type(struct t10_alua_tg_pt_gp *, char *);
|
||||
extern ssize_t core_alua_store_access_type(struct t10_alua_tg_pt_gp *,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+292
-1017
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user