diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-02 21:52:38 +0200 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 10:48:54 +0200 |
commit | e70beee783d6977d80eede88a3394f02eabddad1 (patch) | |
tree | 225d10e36bf031e9c4eab3de537699b60bb48f1b /drivers/target | |
parent | target/iblock: Fix double bioset_integrity_free bug (diff) | |
download | linux-e70beee783d6977d80eede88a3394f02eabddad1.tar.xz linux-e70beee783d6977d80eede88a3394f02eabddad1.zip |
target: Pass in transport supported PI at session initialization
In order to support local WRITE_INSERT + READ_STRIP operations for
non PI enabled fabrics, the fabric driver needs to be able signal
what protection offload operations are supported.
This is done at session initialization time so the modes can be
signaled by individual se_wwn + se_portal_group endpoints, as well
as optionally across different transports on the same endpoint.
For iser-target, set TARGET_PROT_ALL if the underlying ib_device
has already signaled PI offload support, and allow this to be
exposed via a new iscsit_transport->iscsit_get_sup_prot_ops()
callback.
For loopback, set TARGET_PROT_ALL to signal SCSI initiator mode
operation.
For all other drivers, set TARGET_PROT_NORMAL to disable fabric
level PI.
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Or Gerlitz <ogerlitz@mellanox.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 6 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 4 | ||||
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 2 | ||||
-rw-r--r-- | drivers/target/sbp/sbp_target.c | 2 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 8 | ||||
-rw-r--r-- | drivers/target/tcm_fc/tfc_sess.c | 3 |
6 files changed, 18 insertions, 7 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 96aee439c9fd..78cab13bbb1b 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -511,6 +511,11 @@ static void iscsit_aborted_task(struct iscsi_conn *conn, struct iscsi_cmd *cmd) __iscsit_free_cmd(cmd, scsi_cmd, true); } +static enum target_prot_op iscsit_get_sup_prot_ops(struct iscsi_conn *conn) +{ + return TARGET_PROT_NORMAL; +} + static struct iscsit_transport iscsi_target_transport = { .name = "iSCSI/TCP", .transport_type = ISCSI_TCP, @@ -526,6 +531,7 @@ static struct iscsit_transport iscsi_target_transport = { .iscsit_queue_data_in = iscsit_queue_rsp, .iscsit_queue_status = iscsit_queue_rsp, .iscsit_aborted_task = iscsit_aborted_task, + .iscsit_get_sup_prot_ops = iscsit_get_sup_prot_ops, }; static int __init iscsi_target_init_module(void) diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index e29279e6b577..8739b98f6f93 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -259,6 +259,7 @@ static int iscsi_login_zero_tsih_s1( { struct iscsi_session *sess = NULL; struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; + enum target_prot_op sup_pro_ops; int ret; sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); @@ -320,8 +321,9 @@ static int iscsi_login_zero_tsih_s1( kfree(sess); return -ENOMEM; } + sup_pro_ops = conn->conn_transport->iscsit_get_sup_prot_ops(conn); - sess->se_sess = transport_init_session(); + sess->se_sess = transport_init_session(sup_pro_ops); if (IS_ERR(sess->se_sess)) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index bdc1ad82d293..c886ad1c39fb 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -1018,7 +1018,7 @@ static int tcm_loop_make_nexus( /* * Initialize the struct se_session pointer */ - tl_nexus->se_sess = transport_init_session(); + tl_nexus->se_sess = transport_init_session(TARGET_PROT_ALL); if (IS_ERR(tl_nexus->se_sess)) { ret = PTR_ERR(tl_nexus->se_sess); goto out; diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index ad04ea928e4f..e7e93727553c 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -210,7 +210,7 @@ static struct sbp_session *sbp_session_create( return ERR_PTR(-ENOMEM); } - sess->se_sess = transport_init_session(); + sess->se_sess = transport_init_session(TARGET_PROT_NORMAL); if (IS_ERR(sess->se_sess)) { pr_err("failed to init se_session\n"); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 9393544fb471..9c820ba5ae82 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -235,7 +235,7 @@ void transport_subsystem_check_init(void) sub_api_initialized = 1; } -struct se_session *transport_init_session(void) +struct se_session *transport_init_session(enum target_prot_op sup_prot_ops) { struct se_session *se_sess; @@ -251,6 +251,7 @@ struct se_session *transport_init_session(void) INIT_LIST_HEAD(&se_sess->sess_wait_list); spin_lock_init(&se_sess->sess_cmd_lock); kref_init(&se_sess->sess_kref); + se_sess->sup_prot_ops = sup_prot_ops; return se_sess; } @@ -288,12 +289,13 @@ int transport_alloc_session_tags(struct se_session *se_sess, EXPORT_SYMBOL(transport_alloc_session_tags); struct se_session *transport_init_session_tags(unsigned int tag_num, - unsigned int tag_size) + unsigned int tag_size, + enum target_prot_op sup_prot_ops) { struct se_session *se_sess; int rc; - se_sess = transport_init_session(); + se_sess = transport_init_session(sup_prot_ops); if (IS_ERR(se_sess)) return se_sess; diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index ae52c08dad09..04751422178c 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -211,7 +211,8 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id, return NULL; sess->se_sess = transport_init_session_tags(TCM_FC_DEFAULT_TAGS, - sizeof(struct ft_cmd)); + sizeof(struct ft_cmd), + TARGET_PROT_NORMAL); if (IS_ERR(sess->se_sess)) { kfree(sess); return NULL; |