[PATCH 2/9] iscsi: Move TCP code over to transport API

Replace iscsi-tcp specific calls with transport API calls
in order to be able to override them with iser implementation specifics.
Make iscsi-tcp specific debug print into a general print
Refactor conn close code to work with isert

Only allocate RX data in NOP for iscsi-tcp
In case of iser, the data is already received

Signed-off-by: Yan Burman <yanb@mellanox.com>




git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/iser@5230 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2014-01-28 04:13:12 +00:00
parent e885ce50f3
commit 52e0426703
5 changed files with 269 additions and 154 deletions

View File

@@ -21,6 +21,7 @@
#include "iscsi.h"
#include "digest.h"
#include "iscsit_transport.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
#if defined(CONFIG_LOCKDEP) && !defined(CONFIG_SCST_PROC)
@@ -158,42 +159,7 @@ struct kobj_type iscsi_conn_ktype = {
static ssize_t iscsi_get_initiator_ip(struct iscsi_conn *conn,
char *buf, int size)
{
int pos;
struct sock *sk;
TRACE_ENTRY();
sk = conn->sock->sk;
switch (sk->sk_family) {
case AF_INET:
pos = scnprintf(buf, size,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
"%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));
#else
"%pI4", &inet_sk(sk)->inet_daddr);
#endif
break;
case AF_INET6:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
pos = scnprintf(buf, size,
"[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",
NIP6(inet6_sk(sk)->daddr));
#else
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
pos = scnprintf(buf, size, "[%p6]", &inet6_sk(sk)->daddr);
#else
pos = scnprintf(buf, size, "[%p6]", &sk->sk_v6_daddr);
#endif
#endif
break;
default:
pos = scnprintf(buf, size, "Unknown family %d",
sk->sk_family);
break;
}
TRACE_EXIT_RES(pos);
return pos;
return conn->transport->iscsit_get_initiator_ip(conn, buf, size);
}
static ssize_t iscsi_conn_ip_show(struct kobject *kobj,
@@ -431,7 +397,7 @@ void iscsi_make_conn_wr_active(struct iscsi_conn *conn)
return;
}
void __mark_conn_closed(struct iscsi_conn *conn, int flags)
void iscsi_tcp_mark_conn_closed(struct iscsi_conn *conn, int flags)
{
spin_lock_bh(&conn->conn_thr_pool->rd_lock);
conn->closing = 1;
@@ -444,6 +410,11 @@ void __mark_conn_closed(struct iscsi_conn *conn, int flags)
iscsi_make_conn_rd_active(conn);
}
void __mark_conn_closed(struct iscsi_conn *conn, int flags)
{
conn->transport->iscsit_mark_conn_closed(conn, flags);
}
void mark_conn_closed(struct iscsi_conn *conn)
{
__mark_conn_closed(conn, ISCSI_CONN_ACTIVE_CLOSE);
@@ -746,7 +717,7 @@ void conn_reinst_finished(struct iscsi_conn *conn)
return;
}
static void conn_activate(struct iscsi_conn *conn)
int conn_activate(struct iscsi_conn *conn)
{
TRACE_MGMT_DBG("Enabling conn %p", conn);
@@ -772,7 +743,7 @@ static void conn_activate(struct iscsi_conn *conn)
*/
__iscsi_state_change(conn->sock->sk);
return;
return 0;
}
/*
@@ -814,8 +785,19 @@ out:
return res;
}
void iscsi_tcp_conn_free(struct iscsi_conn *conn)
{
fput(conn->file);
conn->file = NULL;
conn->sock = NULL;
free_page((unsigned long)conn->read_iov);
kmem_cache_free(iscsi_conn_cache, conn);
}
/* target_mutex supposed to be locked */
int conn_free(struct iscsi_conn *conn)
void conn_free(struct iscsi_conn *conn)
{
struct iscsi_session *session = conn->session;
@@ -856,25 +838,18 @@ int conn_free(struct iscsi_conn *conn)
list_del(&conn->conn_list_entry);
fput(conn->file);
conn->file = NULL;
conn->sock = NULL;
free_page((unsigned long)conn->read_iov);
kmem_cache_free(iscsi_conn_cache, conn);
conn->transport->iscsit_conn_free(conn);
if (list_empty(&session->conn_list)) {
sBUG_ON(session->sess_reinst_successor != NULL);
session_free(session, true);
}
return 0;
}
/* target_mutex supposed to be locked */
static int iscsi_conn_alloc(struct iscsi_session *session,
struct iscsi_kern_conn_info *info, struct iscsi_conn **new_conn)
int iscsi_conn_alloc(struct iscsi_session *session,
struct iscsi_kern_conn_info *info, struct iscsi_conn **new_conn,
struct iscsit_transport *t)
{
struct iscsi_conn *conn;
int res = 0;
@@ -892,6 +867,8 @@ static int iscsi_conn_alloc(struct iscsi_session *session,
TRACE_MGMT_DBG("Creating connection %p for sid %#Lx, cid %u", conn,
(long long unsigned int)session->sid, info->cid);
conn->transport = t;
/* Changing it, change ISCSI_CONN_IOV_MAX as well !! */
conn->read_iov = (struct iovec *)get_zeroed_page(GFP_KERNEL);
if (conn->read_iov == NULL) {
@@ -986,6 +963,7 @@ int __add_conn(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
struct iscsi_conn *conn, *new_conn = NULL;
int err;
bool reinstatement = false;
struct iscsit_transport *t;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
lockdep_assert_held(&session->target->target_mutex);
@@ -1001,7 +979,13 @@ int __add_conn(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
goto out;
}
err = iscsi_conn_alloc(session, info, &new_conn);
t = iscsit_get_transport(ISCSI_TCP);
if (!t) {
err = -ENOENT;
goto out;
}
err = t->iscsit_conn_alloc(session, info, &new_conn, t);
if (err != 0)
goto out;
@@ -1013,7 +997,7 @@ int __add_conn(struct iscsi_session *session, struct iscsi_kern_conn_info *info)
__mark_conn_closed(conn, 0);
}
conn_activate(new_conn);
err = t->iscsit_conn_activate(new_conn);
out:
return err;

View File

@@ -27,6 +27,7 @@
#include "iscsi.h"
#include "digest.h"
#include "iscsit_transport.h"
#ifndef GENERATING_UPSTREAM_PATCH
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
@@ -242,7 +243,7 @@ static struct iscsi_cmnd *iscsi_create_tm_clone(struct iscsi_cmnd *cmnd)
TRACE_ENTRY();
tm_clone = cmnd_alloc(cmnd->conn, NULL);
tm_clone = cmnd->conn->transport->iscsit_alloc_cmd(cmnd->conn, NULL);
if (tm_clone != NULL) {
set_bit(ISCSI_CMD_ABORTED, &tm_clone->prelim_compl_flags);
tm_clone->pdu = cmnd->pdu;
@@ -496,10 +497,10 @@ void cmnd_done(struct iscsi_cmnd *cmnd)
list_for_each_entry_safe(rsp, t, &cmnd->rsp_cmd_list,
rsp_cmd_list_entry) {
cmnd_free(rsp);
cmnd->conn->transport->iscsit_free_cmd(rsp);
}
cmnd_free(cmnd);
cmnd->conn->transport->iscsit_free_cmd(cmnd);
} else {
struct iscsi_cmnd *parent = cmnd->parent_req;
@@ -735,7 +736,7 @@ static struct iscsi_cmnd *iscsi_alloc_rsp(struct iscsi_cmnd *parent)
TRACE_ENTRY();
rsp = cmnd_alloc(parent->conn, parent);
rsp = parent->conn->transport->iscsit_alloc_cmd(parent->conn, parent);
TRACE_DBG("Adding rsp %p to parent %p", rsp, parent);
list_add_tail(&rsp->rsp_cmd_list_entry, &parent->rsp_cmd_list);
@@ -797,7 +798,7 @@ static void iscsi_cmnds_init_write(struct list_head *send, int flags)
spin_unlock_bh(&conn->write_list_lock);
if (flags & ISCSI_INIT_WRITE_WAKE)
iscsi_make_conn_wr_active(conn);
conn->transport->iscsit_make_conn_wr_active(conn);
return;
}
@@ -992,12 +993,25 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
return;
}
static void iscsi_tcp_set_sense_data(struct iscsi_cmnd *rsp,
const u8 *sense_buf, int sense_len)
{
struct scatterlist *sg;
sg = rsp->sg = rsp->rsp_sg;
rsp->sg_cnt = 2;
rsp->own_sg = 1;
sg_init_table(sg, 2);
sg_set_buf(&sg[0], &rsp->sense_hdr, sizeof(rsp->sense_hdr));
sg_set_buf(&sg[1], sense_buf, sense_len);
}
static void iscsi_init_status_rsp(struct iscsi_cmnd *rsp,
int status, const u8 *sense_buf, int sense_len)
{
struct iscsi_cmnd *req = rsp->parent_req;
struct iscsi_scsi_rsp_hdr *rsp_hdr;
struct scatterlist *sg;
TRACE_ENTRY();
@@ -1011,16 +1025,11 @@ static void iscsi_init_status_rsp(struct iscsi_cmnd *rsp,
if (scst_sense_valid(sense_buf)) {
TRACE_DBG("%s", "SENSE VALID");
sg = rsp->sg = rsp->rsp_sg;
rsp->sg_cnt = 2;
rsp->own_sg = 1;
sg_init_table(sg, 2);
sg_set_buf(&sg[0], &rsp->sense_hdr, sizeof(rsp->sense_hdr));
sg_set_buf(&sg[1], sense_buf, sense_len);
rsp->sense_hdr.length = cpu_to_be16(sense_len);
rsp->conn->transport->iscsit_set_sense_data(rsp, sense_buf,
sense_len);
rsp->pdu.datasize = sizeof(rsp->sense_hdr) + sense_len;
rsp->bufflen = rsp->pdu.datasize;
} else {
@@ -1049,6 +1058,25 @@ static inline struct iscsi_cmnd *create_status_rsp(struct iscsi_cmnd *req,
return rsp;
}
static void iscsi_tcp_send_data_rsp(struct iscsi_cmnd *req, u8 *sense,
int sense_len, u8 status,
int is_send_status)
{
if ((status != SAM_STAT_CHECK_CONDITION) &&
((cmnd_hdr(req)->flags & (ISCSI_CMD_WRITE|ISCSI_CMD_READ)) !=
(ISCSI_CMD_WRITE|ISCSI_CMD_READ))) {
send_data_rsp(req, status, is_send_status);
} else {
struct iscsi_cmnd *rsp;
send_data_rsp(req, 0, 0);
if (is_send_status) {
rsp = create_status_rsp(req, status, sense,
sense_len);
iscsi_cmnd_init_write(rsp, 0);
}
}
}
/*
* Initializes data receive fields. Can be called only when they have not been
* initialized yet.
@@ -1737,7 +1765,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd)
size = cmnd->pdu.datasize;
if (size) {
if (size && !conn->session->sess_params.rdma_extensions) {
conn->read_msg.msg_iov = conn->read_iov;
if (cmnd->pdu.bhs.itt != ISCSI_RESERVED_TAG) {
struct scatterlist *sg;
@@ -1978,7 +2006,8 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
scst_cmd_set_expected_out_transfer_len(scst_cmd,
be32_to_cpu(req_hdr->data_length));
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd);
if (conn->transport->need_alloc_write_buf)
scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd);
#endif
}
} else if (req_hdr->flags & ISCSI_CMD_READ) {
@@ -1986,7 +2015,8 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
scst_cmd_set_expected(scst_cmd, dir,
be32_to_cpu(req_hdr->data_length));
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd);
if (conn->transport->need_alloc_write_buf)
scst_cmd_set_tgt_need_alloc_data_buf(scst_cmd);
#endif
} else if (req_hdr->flags & ISCSI_CMD_WRITE) {
dir = SCST_DATA_WRITE;
@@ -2053,7 +2083,7 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
scst_cmd_init_stage1_done(scst_cmd, SCST_CONTEXT_DIRECT, 0);
if (req->scst_state != ISCSI_CMD_STATE_RX_CMD)
res = cmnd_rx_continue(req);
res = req->conn->transport->iscsit_receive_cmnd_data(req);
else {
TRACE_DBG("Delaying req %p post processing (scst_state %d)",
req, req->scst_state);
@@ -2664,6 +2694,14 @@ reject:
return;
}
static void iscsi_tcp_set_req_data(struct iscsi_cmnd *req,
struct iscsi_cmnd *rsp)
{
rsp->sg = req->sg;
rsp->sg_cnt = req->sg_cnt;
rsp->bufflen = req->bufflen;
}
static void nop_out_exec(struct iscsi_cmnd *req)
{
struct iscsi_cmnd *rsp;
@@ -2687,11 +2725,8 @@ static void nop_out_exec(struct iscsi_cmnd *req)
else
sBUG_ON(req->sg != NULL);
if (req->sg) {
rsp->sg = req->sg;
rsp->sg_cnt = req->sg_cnt;
rsp->bufflen = req->bufflen;
}
if (req->bufflen)
req->conn->transport->iscsit_set_req_data(req, rsp);
/* We already checked it in check_segment_length() */
sBUG_ON(get_pgcnt(req->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX);
@@ -3176,6 +3211,47 @@ out:
return;
}
static ssize_t iscsi_tcp_get_initiator_ip(struct iscsi_conn *conn,
char *buf, int size)
{
int pos;
struct sock *sk;
TRACE_ENTRY();
sk = conn->sock->sk;
switch (sk->sk_family) {
case AF_INET:
pos = scnprintf(buf, size,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
"%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));
#else
"%pI4", &inet_sk(sk)->inet_daddr);
#endif
break;
case AF_INET6:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
pos = scnprintf(buf, size,
"[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",
NIP6(inet6_sk(sk)->daddr));
#else
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
pos = scnprintf(buf, size, "[%p6]", &inet6_sk(sk)->daddr);
#else
pos = scnprintf(buf, size, "[%p6]", &sk->sk_v6_daddr);
#endif
#endif
break;
default:
pos = scnprintf(buf, size, "Unknown family %d",
sk->sk_family);
break;
}
TRACE_EXIT_RES(pos);
return pos;
}
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
static int iscsi_alloc_data_buf(struct scst_cmd *cmd)
{
@@ -3192,11 +3268,8 @@ static int iscsi_alloc_data_buf(struct scst_cmd *cmd)
}
#endif
static void iscsi_preprocessing_done(struct scst_cmd *scst_cmd)
static void iscsi_tcp_preprocessing_done(struct iscsi_cmnd *req)
{
struct iscsi_cmnd *req = (struct iscsi_cmnd *)
scst_cmd_get_tgt_priv(scst_cmd);
TRACE_DBG("req %p", req);
if (req->conn->rx_task == current)
@@ -3223,8 +3296,14 @@ static void iscsi_preprocessing_done(struct scst_cmd *scst_cmd)
}
cmnd_put(req);
}
}
return;
static void iscsi_preprocessing_done(struct scst_cmd *scst_cmd)
{
struct iscsi_cmnd *req = (struct iscsi_cmnd *)
scst_cmd_get_tgt_priv(scst_cmd);
req->conn->transport->iscsit_preprocessing_done(req);
}
/* No locks */
@@ -3285,6 +3364,52 @@ static void iscsi_try_local_processing(struct iscsi_cmnd *req)
return;
}
static int iscsi_tcp_send_locally(struct iscsi_cmnd *req,
unsigned int cmd_count)
{
struct iscsi_conn *conn = req->conn;
struct iscsi_cmnd *wr_rsp, *our_rsp;
int ret = 0;
/*
* There's no need for protection, since we are not going to
* dereference them.
*/
wr_rsp = list_first_entry(&conn->write_list, struct iscsi_cmnd,
write_list_entry);
our_rsp = list_first_entry(&req->rsp_cmd_list, struct iscsi_cmnd,
rsp_cmd_list_entry);
if (wr_rsp == our_rsp) {
/*
* This is our rsp, so let's try to process it locally to
* decrease latency. We need to call pre_release before
* processing to handle some error recovery cases.
*/
if (cmd_count <= 2) {
req_cmnd_pre_release(req);
iscsi_try_local_processing(req);
cmnd_put(req);
} else {
/*
* There's too much backend activity, so it could be
* better to push it to the write thread.
*/
ret = 1;
}
} else
ret = 1;
return ret;
}
static void iscsi_tcp_conn_close(struct iscsi_conn *conn, int flags)
{
if (!flags)
conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0);
else
conn->sock->ops->shutdown(conn->sock, flags);
}
static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
{
int is_send_status = scst_cmd_get_is_send_status(scst_cmd);
@@ -3294,7 +3419,6 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
int status = scst_cmd_get_status(scst_cmd);
u8 *sense = scst_cmd_get_sense_buffer(scst_cmd);
int sense_len = scst_cmd_get_sense_buffer_len(scst_cmd);
struct iscsi_cmnd *wr_rsp, *our_rsp;
EXTRACHECKS_BUG_ON(scst_cmd_atomic(scst_cmd));
@@ -3369,19 +3493,9 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
* so status is valid here, but in future that could change.
* ToDo
*/
if ((status != SAM_STAT_CHECK_CONDITION) &&
((cmnd_hdr(req)->flags & (ISCSI_CMD_WRITE|ISCSI_CMD_READ)) !=
(ISCSI_CMD_WRITE|ISCSI_CMD_READ))) {
send_data_rsp(req, status, is_send_status);
} else {
struct iscsi_cmnd *rsp;
send_data_rsp(req, 0, 0);
if (is_send_status) {
rsp = create_status_rsp(req, status, sense,
sense_len);
iscsi_cmnd_init_write(rsp, 0);
}
}
req->conn->transport->iscsit_send_data_rsp(req, sense,
sense_len, status,
is_send_status);
} else if (is_send_status) {
struct iscsi_cmnd *rsp;
rsp = create_status_rsp(req, status, sense, sense_len);
@@ -3392,32 +3506,7 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
sBUG();
#endif
/*
* There's no need for protection, since we are not going to
* dereference them.
*/
wr_rsp = list_first_entry(&conn->write_list, struct iscsi_cmnd,
write_list_entry);
our_rsp = list_first_entry(&req->rsp_cmd_list, struct iscsi_cmnd,
rsp_cmd_list_entry);
if (wr_rsp == our_rsp) {
/*
* This is our rsp, so let's try to process it locally to
* decrease latency. We need to call pre_release before
* processing to handle some error recovery cases.
*/
if (scst_get_active_cmd_count(scst_cmd) <= 2) {
req_cmnd_pre_release(req);
iscsi_try_local_processing(req);
cmnd_put(req);
} else {
/*
* There's too much backend activity, so it could be
* better to push it to the write thread.
*/
goto out_push_to_wr_thread;
}
} else
if (conn->transport->iscsit_send_locally(req, scst_get_active_cmd_count(scst_cmd)))
goto out_push_to_wr_thread;
out:
@@ -3426,7 +3515,7 @@ out:
out_push_to_wr_thread:
TRACE_DBG("Waking up write thread (conn %p)", conn);
req_cmnd_release(req);
iscsi_make_conn_wr_active(conn);
conn->transport->iscsit_make_conn_wr_active(conn);
goto out;
}
@@ -3610,7 +3699,6 @@ static int iscsi_scsi_aen(struct scst_aen *aen)
bool found;
struct iscsi_cmnd *fake_req, *rsp;
struct iscsi_async_msg_hdr *rsp_hdr;
struct scatterlist *sg;
TRACE_ENTRY();
@@ -3633,7 +3721,7 @@ static int iscsi_scsi_aen(struct scst_aen *aen)
}
/* Create a fake request */
fake_req = cmnd_alloc(conn, NULL);
fake_req = conn->transport->iscsit_alloc_cmd(conn, NULL);
if (fake_req == NULL) {
PRINT_ERROR("%s", "Unable to alloc fake AEN request");
goto out_err_unlock;
@@ -3658,15 +3746,10 @@ static int iscsi_scsi_aen(struct scst_aen *aen)
rsp_hdr->ffffffff = cpu_to_be32(0xffffffff);
rsp_hdr->async_event = ISCSI_ASYNC_SCSI;
sg = rsp->sg = rsp->rsp_sg;
rsp->sg_cnt = 2;
rsp->own_sg = 1;
sg_init_table(sg, 2);
sg_set_buf(&sg[0], &rsp->sense_hdr, sizeof(rsp->sense_hdr));
sg_set_buf(&sg[1], sense, sense_len);
rsp->sense_hdr.length = cpu_to_be16(sense_len);
rsp->conn->transport->iscsit_set_sense_data(rsp, sense, sense_len);
rsp->pdu.datasize = sizeof(rsp->sense_hdr) + sense_len;
rsp->bufflen = rsp->pdu.datasize;
@@ -3788,7 +3871,7 @@ void iscsi_send_nop_in(struct iscsi_conn *conn)
TRACE_ENTRY();
req = cmnd_alloc(conn, NULL);
req = conn->transport->iscsit_alloc_cmd(conn, NULL);
if (req == NULL) {
PRINT_ERROR("%s", "Unable to alloc fake Nop-In request");
goto out_err;
@@ -3930,6 +4013,30 @@ struct scst_tgt_template iscsi_template = {
.get_scsi_transport_version = iscsi_get_scsi_transport_version,
};
static struct iscsit_transport iscsi_tcp_transport = {
.owner = THIS_MODULE,
.name = "iSCSI-TCP",
.transport_type = ISCSI_TCP,
#if !defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
.need_alloc_write_buf = 1,
#endif
.iscsit_conn_alloc = iscsi_conn_alloc,
.iscsit_conn_activate = conn_activate,
.iscsit_conn_free = iscsi_tcp_conn_free,
.iscsit_alloc_cmd = cmnd_alloc,
.iscsit_free_cmd = cmnd_free,
.iscsit_preprocessing_done = iscsi_tcp_preprocessing_done,
.iscsit_send_data_rsp = iscsi_tcp_send_data_rsp,
.iscsit_make_conn_wr_active = iscsi_make_conn_wr_active,
.iscsit_mark_conn_closed = iscsi_tcp_mark_conn_closed,
.iscsit_conn_close = iscsi_tcp_conn_close,
.iscsit_get_initiator_ip = iscsi_tcp_get_initiator_ip,
.iscsit_send_locally = iscsi_tcp_send_locally,
.iscsit_set_sense_data = iscsi_tcp_set_sense_data,
.iscsit_set_req_data = iscsi_tcp_set_req_data,
.iscsit_receive_cmnd_data = cmnd_rx_continue,
};
static void __iscsi_threads_pool_put(struct iscsi_thread_pool *p)
{
struct iscsi_thread *t, *tt;
@@ -4110,6 +4217,10 @@ static int __init iscsi_init(void)
PRINT_INFO("iSCSI SCST Target - version %s", ISCSI_VERSION_STRING);
err = iscsit_register_transport(&iscsi_tcp_transport);
if (err)
goto out;
dummy_page = alloc_pages(GFP_KERNEL, 0);
if (dummy_page == NULL) {
PRINT_ERROR("%s", "Dummy page allocation failed");
@@ -4260,6 +4371,8 @@ static void __exit iscsi_exit(void)
scst_unregister_target_template(&iscsi_template);
iscsit_unregister_transport(&iscsi_tcp_transport);
#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION)
net_set_get_put_page_callbacks(NULL, NULL);
#endif

View File

@@ -555,7 +555,7 @@ extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16);
extern void conn_reinst_finished(struct iscsi_conn *);
extern int __add_conn(struct iscsi_session *, struct iscsi_kern_conn_info *);
extern int __del_conn(struct iscsi_session *, struct iscsi_kern_conn_info *);
extern int conn_free(struct iscsi_conn *);
extern void conn_free(struct iscsi_conn *);
extern void iscsi_make_conn_rd_active(struct iscsi_conn *conn);
#define ISCSI_CONN_ACTIVE_CLOSE 1
#define ISCSI_CONN_DELETING 2
@@ -829,4 +829,11 @@ static inline void iscsi_extracheck_is_rd_thread(struct iscsi_conn *conn) {}
static inline void iscsi_extracheck_is_wr_thread(struct iscsi_conn *conn) {}
#endif
extern int iscsi_conn_alloc(struct iscsi_session *session,
struct iscsi_kern_conn_info *info, struct iscsi_conn **new_conn,
struct iscsit_transport *t);
extern int conn_activate(struct iscsi_conn *conn);
extern void iscsi_tcp_mark_conn_closed(struct iscsi_conn *conn, int flags);
extern void iscsi_tcp_conn_free(struct iscsi_conn *conn);
#endif /* __ISCSI_H__ */

View File

@@ -24,6 +24,7 @@
#include "iscsi.h"
#include "digest.h"
#include "iscsit_transport.h"
/* Read data states */
enum rx_state {
@@ -408,10 +409,10 @@ static void close_conn(struct iscsi_conn *conn)
if (conn->active_close) {
/* We want all our already send operations to complete */
conn->sock->ops->shutdown(conn->sock, RCV_SHUTDOWN);
conn->transport->iscsit_conn_close(conn, RCV_SHUTDOWN);
} else {
conn->sock->ops->shutdown(conn->sock,
RCV_SHUTDOWN|SEND_SHUTDOWN);
conn->transport->iscsit_conn_close(conn,
RCV_SHUTDOWN|SEND_SHUTDOWN);
}
mutex_lock(&session->target->target_mutex);
@@ -487,15 +488,13 @@ static void close_conn(struct iscsi_conn *conn)
}
}
iscsi_make_conn_wr_active(conn);
conn->transport->iscsit_make_conn_wr_active(conn);
/* That's for active close only, actually */
if (time_after(jiffies, start_waiting + CONN_WAIT_TIMEOUT) &&
!wait_expired) {
TRACE_CONN_CLOSE("Wait time expired (conn %p, "
"sk_state %d)",
conn, conn->sock->sk->sk_state);
conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN);
TRACE_CONN_CLOSE("Wait time expired (conn %p)", conn);
conn->transport->iscsit_conn_close(conn, SEND_SHUTDOWN);
wait_expired = 1;
shut_start_waiting = jiffies;
}
@@ -505,9 +504,8 @@ static void close_conn(struct iscsi_conn *conn)
conn->deleting ? CONN_DEL_SHUT_TIMEOUT :
CONN_REG_SHUT_TIMEOUT)) {
TRACE_CONN_CLOSE("Wait time after shutdown expired "
"(conn %p, sk_state %d)", conn,
conn->sock->sk->sk_state);
conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0);
"(conn %p)", conn);
conn->transport->iscsit_conn_close(conn, 0);
shut_expired = 1;
}
@@ -523,17 +521,21 @@ static void close_conn(struct iscsi_conn *conn)
trace_conn_close(conn);
/* It might never be called for being closed conn */
__iscsi_write_space_ready(conn);
if (!conn->session->sess_params.rdma_extensions) {
/* It might never be called for being closed conn */
__iscsi_write_space_ready(conn);
iscsi_check_closewait(conn);
iscsi_check_closewait(conn);
}
}
write_lock_bh(&conn->sock->sk->sk_callback_lock);
conn->sock->sk->sk_state_change = conn->old_state_change;
conn->sock->sk->sk_data_ready = conn->old_data_ready;
conn->sock->sk->sk_write_space = conn->old_write_space;
write_unlock_bh(&conn->sock->sk->sk_callback_lock);
if (!conn->session->sess_params.rdma_extensions) {
write_lock_bh(&conn->sock->sk->sk_callback_lock);
conn->sock->sk->sk_state_change = conn->old_state_change;
conn->sock->sk->sk_data_ready = conn->old_data_ready;
conn->sock->sk->sk_write_space = conn->old_write_space;
write_unlock_bh(&conn->sock->sk->sk_callback_lock);
}
while (1) {
bool t;
@@ -832,7 +834,7 @@ static int process_read_io(struct iscsi_conn *conn, int *closed)
switch (conn->read_state) {
case RX_INIT_BHS:
EXTRACHECKS_BUG_ON(conn->read_cmnd != NULL);
cmnd = cmnd_alloc(conn, NULL);
cmnd = conn->transport->iscsit_alloc_cmd(conn, NULL);
conn->read_cmnd = cmnd;
iscsi_conn_init_read(cmnd->conn,
(void __force __user *)&cmnd->pdu.bhs,

View File

@@ -349,6 +349,7 @@ void target_del_all_sess(struct iscsi_target *target, int flags)
void target_del_all(void)
{
struct iscsit_transport *transport;
struct iscsi_target *target, *t;
bool first = true;
@@ -356,6 +357,14 @@ void target_del_all(void)
TRACE_MGMT_DBG("%s", "Deleting all targets");
transport = iscsit_get_transport(ISCSI_TCP);
if (transport && transport->iscsit_close_all_portals)
transport->iscsit_close_all_portals();
transport = iscsit_get_transport(ISCSI_RDMA);
if (transport && transport->iscsit_close_all_portals)
transport->iscsit_close_all_portals();
/* Not the best, ToDo */
while (1) {
mutex_lock(&target_mgmt_mutex);