mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
Merged revisions 6934-6958 from trunk
------------------------------------------------------------------------ r6934 | mlx-storage | 2016-08-17 10:17:37 +0300 (Wed, 17 Aug 2016) | 4 lines isert: make sure rdma_disconnect is called only once ------------------------------------------------------------------------ r6935 | mlx-storage | 2016-08-17 10:27:06 +0300 (Wed, 17 Aug 2016) | 8 lines isert: fix cleaning isert_con_dev ------------------------------------------------------------------------ r6936 | mlx-storage | 2016-08-17 10:27:11 +0300 (Wed, 17 Aug 2016) | 4 lines isert: add assertions for connection teardwon flow ------------------------------------------------------------------------ r6937 | mlx-storage | 2016-08-17 10:27:15 +0300 (Wed, 17 Aug 2016) | 8 lines isert: fix a possible extra refcount put of isert connection ------------------------------------------------------------------------ r6938 | mlx-storage | 2016-08-17 10:27:19 +0300 (Wed, 17 Aug 2016) | 4 lines isert: change wrong dev_conn bug on ------------------------------------------------------------------------ r6939 | mlx-storage | 2016-08-17 10:27:24 +0300 (Wed, 17 Aug 2016) | 6 lines isert: fix fops ioctl using invalid conn ------------------------------------------------------------------------ r6940 | mlx-storage | 2016-08-17 10:27:28 +0300 (Wed, 17 Aug 2016) | 9 lines isert: fix race between ioctl events and disconnect flow ------------------------------------------------------------------------ r6941 | mlx-storage | 2016-08-17 10:27:33 +0300 (Wed, 17 Aug 2016) | 7 lines isert: fix isert conn refcount release at unreachable event ------------------------------------------------------------------------ r6942 | mlx-storage | 2016-08-17 10:27:38 +0300 (Wed, 17 Aug 2016) | 7 lines isert: fix missing refcount cleanup at error flow ------------------------------------------------------------------------ r6943 | mlx-storage | 2016-08-17 10:27:43 +0300 (Wed, 17 Aug 2016) | 8 lines isert: add assertion if send/recv was posted after post drain ------------------------------------------------------------------------ r6944 | mlx-storage | 2016-08-17 10:27:48 +0300 (Wed, 17 Aug 2016) | 4 lines isert: replace kernel prints with scst macros ------------------------------------------------------------------------ r6945 | mlx-storage | 2016-08-17 10:27:53 +0300 (Wed, 17 Aug 2016) | 12 lines isert: fix a race between timewait exit handler and poll cq ------------------------------------------------------------------------ r6946 | mlx-storage | 2016-08-17 10:27:57 +0300 (Wed, 17 Aug 2016) | 9 lines isert: fix a race when drain wr is not the last flush ------------------------------------------------------------------------ r6947 | mlx-storage | 2016-08-17 10:28:02 +0300 (Wed, 17 Aug 2016) | 8 lines isert: fix isert connection kref leak at estabished event handler ------------------------------------------------------------------------ r6948 | mlx-storage | 2016-08-17 10:28:06 +0300 (Wed, 17 Aug 2016) | 7 lines isert: close isert connection earlier ------------------------------------------------------------------------ r6949 | mlx-storage | 2016-08-17 10:28:11 +0300 (Wed, 17 Aug 2016) | 4 lines isert: change dev conn_lock spinlock to mutex ------------------------------------------------------------------------ r6950 | mlx-storage | 2016-08-17 10:28:16 +0300 (Wed, 17 Aug 2016) | 13 lines isert: fix a race between calling to rdma_disconnect and connect flow ------------------------------------------------------------------------ r6951 | mlx-storage | 2016-08-17 10:28:20 +0300 (Wed, 17 Aug 2016) | 8 lines isert: fix isert connection kref leak ------------------------------------------------------------------------ r6952 | mlx-storage | 2016-08-17 10:28:25 +0300 (Wed, 17 Aug 2016) | 9 lines isert: faster release of isert_scst module ----------------------------------------------------------------------- r6953 | mlx-storage | 2016-08-17 10:28:29 +0300 (Wed, 17 Aug 2016) | 9 lines isert: fix races between conn fops read/write and disconnect flow ------------------------------------------------------------------------ r6954 | mlx-storage | 2016-08-17 10:28:34 +0300 (Wed, 17 Aug 2016) | 4 lines isert: add missing fd put on error flow ------------------------------------------------------------------------ r6955 | mlx-storage | 2016-08-17 10:28:38 +0300 (Wed, 17 Aug 2016) | 9 lines isert: fix working with freed conn object ------------------------------------------------------------------------ r6956 | mlx-storage | 2016-08-17 10:28:43 +0300 (Wed, 17 Aug 2016) | 8 lines isert: fix isert conn cleanup when rdma_accept fails ------------------------------------------------------------------------ r6957 | mlx-storage | 2016-08-17 10:28:47 +0300 (Wed, 17 Aug 2016) | 7 lines isert: add conn to portal conn list only if rdma_accept succeeded ------------------------------------------------------------------------ r6958 | mlx-storage | 2016-08-17 10:28:52 +0300 (Wed, 17 Aug 2016) | 4 lines isert: fix redundant module put on error flow when handling connect request ------------------------------------------------------------------------ git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/3.2.x@6966 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -2035,6 +2035,8 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
|
||||
atomic_inc(&session->active_cmds);
|
||||
req->dec_active_cmds = 1;
|
||||
|
||||
sBUG_ON(session->scst_sess == NULL);
|
||||
|
||||
scst_cmd = scst_rx_cmd(session->scst_sess,
|
||||
(uint8_t *)&req_hdr->lun, sizeof(req_hdr->lun),
|
||||
req_hdr->scb, sizeof(req_hdr->scb), SCST_NON_ATOMIC);
|
||||
|
||||
@@ -63,6 +63,7 @@ struct isert_portal {
|
||||
/* protected by dev_list_mutex */
|
||||
struct list_head conn_list; /* head of conns list */
|
||||
enum isert_portal_state state;
|
||||
int refcnt;
|
||||
};
|
||||
|
||||
struct isert_buf {
|
||||
@@ -158,8 +159,11 @@ struct isert_cq {
|
||||
|
||||
#define ISERT_CONNECTION_ABORTED 0
|
||||
#define ISERT_DRAIN_POSTED 1
|
||||
#define ISERT_DRAIN_FAILED 2
|
||||
#define ISERT_DISCON_CALLED 3
|
||||
#define ISERT_DISCON_CALLED 2
|
||||
#define ISERT_DRAINED_RQ 3
|
||||
#define ISERT_DRAINED_SQ 4
|
||||
#define ISERT_CONNECTION_CLOSE 5
|
||||
#define ISERT_IN_PORTAL_LIST 6
|
||||
|
||||
struct isert_connection {
|
||||
struct iscsi_conn iscsi ____cacheline_aligned;
|
||||
@@ -185,6 +189,7 @@ struct isert_connection {
|
||||
struct isert_cq *cq_desc;
|
||||
|
||||
enum isert_conn_state state;
|
||||
struct mutex state_mutex;
|
||||
|
||||
u32 responder_resources;
|
||||
u32 initiator_depth;
|
||||
@@ -216,7 +221,9 @@ struct isert_connection {
|
||||
struct work_struct close_work;
|
||||
struct work_struct drain_work;
|
||||
struct work_struct discon_work;
|
||||
struct isert_wr drain_wr;
|
||||
struct work_struct free_work;
|
||||
struct isert_wr drain_wr_sq;
|
||||
struct isert_wr drain_wr_rq;
|
||||
struct kref kref;
|
||||
|
||||
struct isert_portal *portal;
|
||||
@@ -287,6 +294,7 @@ void isert_free_conn_resources(struct isert_connection *isert_conn);
|
||||
void isert_conn_free(struct isert_connection *isert_conn);
|
||||
void isert_conn_disconnect(struct isert_connection *isert_conn);
|
||||
void isert_post_drain(struct isert_connection *isert_conn);
|
||||
void isert_sched_conn_free(struct isert_connection *isert_conn);
|
||||
|
||||
static inline struct isert_connection *isert_conn_zalloc(void)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev,
|
||||
isert_buf->sg = kmalloc_array(isert_buf->sg_cnt, sizeof(*isert_buf->sg),
|
||||
GFP_KERNEL);
|
||||
if (unlikely(!isert_buf->sg)) {
|
||||
pr_err("Failed to allocate buffer SG\n");
|
||||
PRINT_ERROR("Failed to allocate buffer SG");
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev,
|
||||
|
||||
page = alloc_page(GFP_KERNEL);
|
||||
if (unlikely(!page)) {
|
||||
pr_err("Failed to allocate page\n");
|
||||
PRINT_ERROR("Failed to allocate page");
|
||||
res = -ENOMEM;
|
||||
goto out_map_failed;
|
||||
}
|
||||
@@ -74,8 +74,8 @@ static int isert_buf_alloc_pg(struct ib_device *ib_dev,
|
||||
res = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, dma_dir);
|
||||
if (unlikely(!res)) {
|
||||
--i; /* do not overrun isert_buf->sg */
|
||||
pr_err("Failed to DMA map iser sg:%p len:%d\n",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
PRINT_ERROR("Failed to DMA map iser sg:%p len:%d",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
res = -ENOMEM;
|
||||
goto out_map_failed;
|
||||
}
|
||||
@@ -111,14 +111,14 @@ static int isert_buf_malloc(struct ib_device *ib_dev,
|
||||
isert_buf->sg_cnt = 1;
|
||||
isert_buf->sg = kmalloc(sizeof(isert_buf->sg[0]), GFP_KERNEL);
|
||||
if (unlikely(!isert_buf->sg)) {
|
||||
pr_err("Failed to allocate buffer SG\n");
|
||||
PRINT_ERROR("Failed to allocate buffer SG");
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
isert_buf->addr = kmalloc(size, GFP_KERNEL);
|
||||
if (unlikely(!isert_buf->addr)) {
|
||||
pr_err("Failed to allocate data buffer\n");
|
||||
PRINT_ERROR("Failed to allocate data buffer");
|
||||
res = -ENOMEM;
|
||||
goto data_malloc_failed;
|
||||
}
|
||||
@@ -127,8 +127,8 @@ static int isert_buf_malloc(struct ib_device *ib_dev,
|
||||
|
||||
res = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt, dma_dir);
|
||||
if (unlikely(!res)) {
|
||||
pr_err("Failed to DMA map iser sg:%p len:%d\n",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
PRINT_ERROR("Failed to DMA map iser sg:%p len:%d",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
res = -ENOMEM;
|
||||
goto out_map_failed;
|
||||
}
|
||||
@@ -233,7 +233,7 @@ int isert_wr_init(struct isert_wr *wr,
|
||||
case ISER_WR_RDMA_READ:
|
||||
send_wr_op = IB_WR_RDMA_READ;
|
||||
if (unlikely(!pdu->is_wstag_valid)) {
|
||||
pr_err("No write tag/va specified for RDMA op\n");
|
||||
PRINT_ERROR("No write tag/va specified for RDMA op");
|
||||
isert_buf_release(isert_buf);
|
||||
buff_offset = -EFAULT;
|
||||
goto out;
|
||||
@@ -250,7 +250,7 @@ int isert_wr_init(struct isert_wr *wr,
|
||||
case ISER_WR_RDMA_WRITE:
|
||||
send_wr_op = IB_WR_RDMA_WRITE;
|
||||
if (unlikely(!pdu->is_rstag_valid)) {
|
||||
pr_err("No read tag/va specified for RDMA op\n");
|
||||
PRINT_ERROR("No read tag/va specified for RDMA op");
|
||||
isert_buf_release(isert_buf);
|
||||
buff_offset = -EFAULT;
|
||||
goto out;
|
||||
|
||||
@@ -47,7 +47,7 @@ int isert_datamover_init(void)
|
||||
|
||||
err = isert_global_init();
|
||||
if (unlikely(err)) {
|
||||
pr_err("iser datamover init failed, err:%d\n", err);
|
||||
PRINT_ERROR("iser datamover init failed, err:%d", err);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
@@ -189,7 +189,7 @@ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery)
|
||||
if (last && !discovery) {
|
||||
err = isert_alloc_conn_resources(isert_conn);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to init conn resources\n");
|
||||
PRINT_ERROR("Failed to init conn resources");
|
||||
return err;
|
||||
}
|
||||
isert_pdu_free(isert_conn->login_req_pdu);
|
||||
@@ -199,7 +199,7 @@ int isert_login_rsp_tx(struct iscsi_cmnd *login_rsp, int last, int discovery)
|
||||
&isert_conn->login_req_pdu->wr[0],
|
||||
1);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to post recv login req rx buf, err:%d\n", err);
|
||||
PRINT_ERROR("Failed to post recv login req rx buf, err:%d", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,8 @@ int isert_data_in_sent(struct iscsi_cmnd *cmd);
|
||||
int isert_pdu_sent(struct iscsi_cmnd *pdu);
|
||||
void isert_pdu_err(struct iscsi_cmnd *pdu);
|
||||
|
||||
int isert_connection_closed(struct iscsi_conn *iscsi_conn);
|
||||
void isert_connection_closed(struct iscsi_conn *iscsi_conn);
|
||||
void isert_connection_abort(struct iscsi_conn *iscsi_conn);
|
||||
|
||||
void *isert_get_priv(struct iscsi_conn *iscsi_conn);
|
||||
void isert_set_priv(struct iscsi_conn *iscsi_conn, void *priv);
|
||||
|
||||
@@ -106,7 +106,7 @@ int isert_global_init(void)
|
||||
|
||||
isert_glob.conn_wq = create_workqueue("isert_conn_wq");
|
||||
if (!isert_glob.conn_wq) {
|
||||
pr_err("Failed to alloc iser conn work queue\n");
|
||||
PRINT_ERROR("Failed to alloc iser conn work queue");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ int isert_global_init(void)
|
||||
SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN);
|
||||
if (!isert_cmnd_cache) {
|
||||
destroy_workqueue(isert_glob.conn_wq);
|
||||
pr_err("Failed to alloc iser command cache\n");
|
||||
PRINT_ERROR("Failed to alloc iser command cache");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ int isert_global_init(void)
|
||||
if (!isert_conn_cache) {
|
||||
destroy_workqueue(isert_glob.conn_wq);
|
||||
kmem_cache_destroy(isert_cmnd_cache);
|
||||
pr_err("Failed to alloc iser connection cache\n");
|
||||
PRINT_ERROR("Failed to alloc iser connection cache");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ int isert_get_addr_size(struct sockaddr *sa, size_t *addr_len)
|
||||
*addr_len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
pr_err("Unknown address family\n");
|
||||
PRINT_ERROR("Unknown address family");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -263,8 +263,8 @@ int isert_prepare_rdma(struct isert_cmnd *isert_pdu,
|
||||
err = ib_dma_map_sg(ib_dev, isert_buf->sg, isert_buf->sg_cnt,
|
||||
isert_buf->dma_dir);
|
||||
if (unlikely(!err)) {
|
||||
pr_err("Failed to DMA map iser sg:%p len:%d\n",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
PRINT_ERROR("Failed to DMA map iser sg:%p len:%d",
|
||||
isert_buf->sg, isert_buf->sg_cnt);
|
||||
wr_cnt = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
@@ -331,27 +331,27 @@ struct isert_cmnd *isert_rx_pdu_alloc(struct isert_connection *isert_conn,
|
||||
|
||||
pdu = isert_pdu_alloc();
|
||||
if (unlikely(!pdu)) {
|
||||
pr_err("Failed to alloc pdu\n");
|
||||
PRINT_ERROR("Failed to alloc pdu");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = isert_alloc_for_rdma(pdu, 4, isert_conn);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to alloc sge and wr for rx pdu\n");
|
||||
PRINT_ERROR("Failed to alloc sge and wr for rx pdu");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev,
|
||||
&pdu->buf, size, DMA_FROM_DEVICE);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to alloc rx pdu buf sz:%zd\n", size);
|
||||
PRINT_ERROR("Failed to alloc rx pdu buf sz:%zd", size);
|
||||
goto buf_alloc_failed;
|
||||
}
|
||||
|
||||
err = isert_rx_pdu_init(pdu, isert_conn);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to init rx pdu wr:%p size:%zd err:%d\n",
|
||||
&pdu->wr, size, err);
|
||||
PRINT_ERROR("Failed to init rx pdu wr:%p size:%zd err:%d",
|
||||
&pdu->wr, size, err);
|
||||
goto pdu_init_failed;
|
||||
}
|
||||
|
||||
@@ -379,27 +379,27 @@ struct isert_cmnd *isert_tx_pdu_alloc(struct isert_connection *isert_conn,
|
||||
|
||||
pdu = isert_pdu_alloc();
|
||||
if (unlikely(!pdu)) {
|
||||
pr_err("Failed to alloc pdu\n");
|
||||
PRINT_ERROR("Failed to alloc pdu");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = isert_alloc_for_rdma(pdu, 4, isert_conn);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to alloc sge and wr for tx pdu\n");
|
||||
PRINT_ERROR("Failed to alloc sge and wr for tx pdu");
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = isert_buf_alloc_data_buf(isert_conn->isert_dev->ib_dev,
|
||||
&pdu->buf, size, DMA_TO_DEVICE);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to alloc tx pdu buf sz:%zd\n", size);
|
||||
PRINT_ERROR("Failed to alloc tx pdu buf sz:%zd", size);
|
||||
goto buf_alloc_failed;
|
||||
}
|
||||
|
||||
err = isert_pdu_tx_buf_init(pdu, isert_conn);
|
||||
if (unlikely(err < 0)) {
|
||||
pr_err("Failed to init tx pdu wr:%p size:%zd err:%d\n",
|
||||
&pdu->wr, size, err);
|
||||
PRINT_ERROR("Failed to init tx pdu wr:%p size:%zd err:%d",
|
||||
&pdu->wr, size, err);
|
||||
goto buf_init_failed;
|
||||
}
|
||||
|
||||
@@ -449,8 +449,8 @@ int isert_alloc_conn_resources(struct isert_connection *isert_conn)
|
||||
to_alloc = isert_conn->queue_depth * 2 + isert_conn->repost_threshold;
|
||||
|
||||
if (unlikely(to_alloc > ISER_MAX_WCE)) {
|
||||
pr_err("QueuedCommands larger than %d not supported\n",
|
||||
(ISER_MAX_WCE - isert_conn->repost_threshold) / 2);
|
||||
PRINT_ERROR("QueuedCommands larger than %d not supported",
|
||||
(ISER_MAX_WCE - isert_conn->repost_threshold) / 2);
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -478,7 +478,7 @@ int isert_alloc_conn_resources(struct isert_connection *isert_conn)
|
||||
|
||||
err = isert_post_recv(isert_conn, &first_pdu->wr[0], to_alloc);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to post recv err:%d\n", err);
|
||||
PRINT_ERROR("Failed to post recv err:%d", err);
|
||||
goto clean_pdus;
|
||||
}
|
||||
|
||||
@@ -596,8 +596,8 @@ int isert_pdu_send(struct isert_connection *isert_conn,
|
||||
|
||||
err = isert_post_send(isert_conn, wr, 1);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n",
|
||||
isert_conn, tx_pdu, err);
|
||||
PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d",
|
||||
isert_conn, tx_pdu, err);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(err);
|
||||
@@ -623,8 +623,8 @@ int isert_pdu_post_rdma_write(struct isert_connection *isert_conn,
|
||||
isert_link_send_pdu_wrs(isert_cmd, isert_rsp, wr_cnt);
|
||||
err = isert_post_send(isert_conn, &isert_cmd->wr[0], wr_cnt + 1);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n",
|
||||
isert_conn, isert_cmd, err);
|
||||
PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d",
|
||||
isert_conn, isert_cmd, err);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(err);
|
||||
@@ -640,8 +640,8 @@ int isert_pdu_post_rdma_read(struct isert_connection *isert_conn,
|
||||
|
||||
err = isert_post_send(isert_conn, &isert_cmd->wr[0], wr_cnt);
|
||||
if (unlikely(err)) {
|
||||
pr_err("Failed to send pdu conn:%p pdu:%p err:%d\n",
|
||||
isert_conn, isert_cmd, err);
|
||||
PRINT_ERROR("Failed to send pdu conn:%p pdu:%p err:%d",
|
||||
isert_conn, isert_cmd, err);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(err);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -78,6 +78,11 @@ static void isert_mark_conn_closed(struct iscsi_conn *conn, int flags)
|
||||
|
||||
static void isert_close_conn(struct iscsi_conn *conn, int flags)
|
||||
{
|
||||
struct isert_conn_dev *dev;
|
||||
|
||||
dev = isert_get_priv(conn);
|
||||
if (dev)
|
||||
dev->state = CS_DISCONNECTED;
|
||||
}
|
||||
|
||||
static int isert_receive_cmnd_data(struct iscsi_cmnd *cmnd)
|
||||
@@ -283,7 +288,7 @@ static void isert_free_conn(struct iscsi_conn *conn)
|
||||
isert_free_connection(conn);
|
||||
}
|
||||
|
||||
int isert_handle_close_connection(struct iscsi_conn *conn)
|
||||
void isert_handle_close_connection(struct iscsi_conn *conn)
|
||||
{
|
||||
isert_mark_conn_closed(conn, 0);
|
||||
/*
|
||||
@@ -295,7 +300,6 @@ int isert_handle_close_connection(struct iscsi_conn *conn)
|
||||
isert_free_connection(conn);
|
||||
else
|
||||
start_close_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int isert_pdu_rx(struct iscsi_cmnd *cmnd)
|
||||
@@ -393,8 +397,8 @@ int isert_pdu_sent(struct iscsi_cmnd *pdu)
|
||||
struct iscsi_target *target = pdu->conn->session->target;
|
||||
|
||||
PRINT_INFO("Closing all connections for target %x at "
|
||||
"initiator's %s request", target->tid,
|
||||
conn->session->initiator_name);
|
||||
"initiator's %s request", target->tid,
|
||||
conn->session->initiator_name);
|
||||
mutex_lock(&target->target_mutex);
|
||||
target_del_all_sess(target, 0);
|
||||
mutex_unlock(&target->target_mutex);
|
||||
@@ -492,7 +496,7 @@ static int __init isert_init_module(void)
|
||||
int ret;
|
||||
|
||||
if (isert_nr_devs > 999) {
|
||||
PRINT_ERROR("Invalid argument for isert_nr_devs provded: %d\n",
|
||||
PRINT_ERROR("Invalid argument for isert_nr_devs provded: %d",
|
||||
isert_nr_devs);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
||||
@@ -71,7 +71,7 @@ struct isert_listener_dev {
|
||||
struct cdev cdev;
|
||||
dev_t devno;
|
||||
wait_queue_head_t waitqueue;
|
||||
spinlock_t conn_lock;
|
||||
struct mutex conn_lock;
|
||||
struct list_head new_conn_list;
|
||||
struct list_head curr_conn_list;
|
||||
struct isert_addr_info info;
|
||||
@@ -129,7 +129,7 @@ int isert_conn_alloc(struct iscsi_session *session,
|
||||
struct iscsi_kern_conn_info *info,
|
||||
struct iscsi_conn **new_conn,
|
||||
struct iscsit_transport *t);
|
||||
int isert_handle_close_connection(struct iscsi_conn *conn);
|
||||
void isert_handle_close_connection(struct iscsi_conn *conn);
|
||||
void isert_close_all_portals(void);
|
||||
void isert_del_timer(struct isert_conn_dev *dev);
|
||||
|
||||
|
||||
@@ -49,8 +49,11 @@
|
||||
#include "isert_dbg.h"
|
||||
#include "../iscsi.h"
|
||||
#include "isert.h"
|
||||
#include "iser.h"
|
||||
#include "iser_datamover.h"
|
||||
|
||||
static DEFINE_MUTEX(conn_mgmt_mutex);
|
||||
|
||||
static unsigned int n_devs;
|
||||
|
||||
static int isert_major;
|
||||
@@ -67,7 +70,7 @@ static struct isert_conn_dev *get_available_dev(struct isert_listener_dev *dev,
|
||||
unsigned int i;
|
||||
struct isert_conn_dev *res = NULL;
|
||||
|
||||
spin_lock(&dev->conn_lock);
|
||||
mutex_lock(&dev->conn_lock);
|
||||
for (i = 0; i < n_devs; ++i) {
|
||||
if (!isert_conn_devices[i].occupied) {
|
||||
res = &isert_conn_devices[i];
|
||||
@@ -78,7 +81,7 @@ static struct isert_conn_dev *get_available_dev(struct isert_listener_dev *dev,
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev->conn_lock);
|
||||
mutex_unlock(&dev->conn_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -107,9 +110,10 @@ static void isert_kref_release_dev(struct kref *kref)
|
||||
|
||||
static void isert_dev_release(struct isert_conn_dev *dev)
|
||||
{
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
sBUG_ON(atomic_read(&dev->kref.refcount) == 0);
|
||||
mutex_lock(&isert_listen_dev.conn_lock);
|
||||
kref_put(&dev->kref, isert_kref_release_dev);
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
mutex_unlock(&isert_listen_dev.conn_lock);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
|
||||
@@ -137,7 +141,7 @@ static void isert_conn_timer_fn(unsigned long arg)
|
||||
|
||||
conn_dev->timer_active = 0;
|
||||
|
||||
PRINT_ERROR("Timeout on connection %p\n", conn_dev->conn);
|
||||
PRINT_ERROR("Timeout on connection %p", conn_dev->conn);
|
||||
|
||||
schedule_work(&conn->close_work);
|
||||
|
||||
@@ -153,7 +157,7 @@ static int add_new_connection(struct isert_listener_dev *dev,
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (!conn_dev) {
|
||||
PRINT_WARNING("%s", "Unable to allocate new connection");
|
||||
PRINT_WARNING("Unable to allocate new connection");
|
||||
res = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
@@ -181,9 +185,9 @@ static bool have_new_connection(struct isert_listener_dev *dev)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
spin_lock(&dev->conn_lock);
|
||||
mutex_lock(&dev->conn_lock);
|
||||
ret = !list_empty(&dev->new_conn_list);
|
||||
spin_unlock(&dev->conn_lock);
|
||||
mutex_unlock(&dev->conn_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -203,6 +207,8 @@ int isert_conn_alloc(struct iscsi_session *session,
|
||||
|
||||
lockdep_assert_held(&session->target->target_mutex);
|
||||
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (unlikely(!filp)) {
|
||||
res = -EBADF;
|
||||
goto out;
|
||||
@@ -210,6 +216,14 @@ int isert_conn_alloc(struct iscsi_session *session,
|
||||
|
||||
dev = filp->private_data;
|
||||
|
||||
if (unlikely(dev->state == CS_DISCONNECTED)) {
|
||||
fput(filp);
|
||||
res = -EBADF;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sBUG_ON(dev->state != CS_RSP_FINISHED);
|
||||
|
||||
cmnd = dev->login_rsp;
|
||||
|
||||
sBUG_ON(cmnd == NULL);
|
||||
@@ -265,6 +279,7 @@ cleanup_conn:
|
||||
conn->session = NULL;
|
||||
isert_close_connection(conn);
|
||||
out:
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
@@ -304,8 +319,8 @@ static void isert_delete_conn_dev(struct isert_conn_dev *conn_dev)
|
||||
isert_del_timer(conn_dev);
|
||||
|
||||
if (!test_and_set_bit(ISERT_CONN_PASSED, &conn_dev->flags)) {
|
||||
BUG_ON(conn_dev->conn == NULL);
|
||||
isert_close_connection(conn_dev->conn);
|
||||
if (conn_dev->conn)
|
||||
isert_close_connection(conn_dev->conn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,13 +329,13 @@ static int isert_listen_release(struct inode *inode, struct file *filp)
|
||||
struct isert_listener_dev *dev = filp->private_data;
|
||||
struct isert_conn_dev *conn_dev;
|
||||
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
mutex_lock(&isert_listen_dev.conn_lock);
|
||||
list_for_each_entry(conn_dev, &dev->new_conn_list, conn_list_entry)
|
||||
isert_delete_conn_dev(conn_dev);
|
||||
|
||||
list_for_each_entry(conn_dev, &dev->curr_conn_list, conn_list_entry)
|
||||
isert_delete_conn_dev(conn_dev);
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
mutex_unlock(&isert_listen_dev.conn_lock);
|
||||
|
||||
atomic_inc(&dev->available);
|
||||
return 0;
|
||||
@@ -347,16 +362,16 @@ wait_for_connection:
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&dev->conn_lock);
|
||||
mutex_lock(&dev->conn_lock);
|
||||
if (list_empty(&dev->new_conn_list)) {
|
||||
/* could happen if we got disconnect */
|
||||
spin_unlock(&dev->conn_lock);
|
||||
mutex_unlock(&dev->conn_lock);
|
||||
goto wait_for_connection;
|
||||
}
|
||||
conn_dev = list_first_entry(&dev->new_conn_list, struct isert_conn_dev,
|
||||
conn_list_entry);
|
||||
list_move(&conn_dev->conn_list_entry, &dev->curr_conn_list);
|
||||
spin_unlock(&dev->conn_lock);
|
||||
mutex_unlock(&dev->conn_lock);
|
||||
|
||||
to_write = min_t(size_t, sizeof(k_buff), count);
|
||||
res = scnprintf(k_buff, to_write, "/dev/"ISER_CONN_DEV_PREFIX"%d",
|
||||
@@ -385,13 +400,13 @@ static long isert_listen_ioctl(struct file *filp, unsigned int cmd,
|
||||
case SET_LISTEN_ADDR:
|
||||
rc = copy_from_user(&dev->info, ptr, sizeof(dev->info));
|
||||
if (unlikely(rc != 0)) {
|
||||
PRINT_ERROR("Failed to copy %d user's bytes\n", rc);
|
||||
PRINT_ERROR("Failed to copy %d user's bytes", rc);
|
||||
res = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (unlikely(dev->free_portal_idx >= ISERT_MAX_PORTALS)) {
|
||||
PRINT_ERROR("Maximum number of portals exceeded: %d\n",
|
||||
PRINT_ERROR("Maximum number of portals exceeded: %d",
|
||||
ISERT_MAX_PORTALS);
|
||||
res = -EINVAL;
|
||||
goto out;
|
||||
@@ -407,7 +422,7 @@ static long isert_listen_ioctl(struct file *filp, unsigned int cmd,
|
||||
portal = isert_portal_add((struct sockaddr *)&dev->info.addr,
|
||||
dev->info.addr_len);
|
||||
if (IS_ERR(portal)) {
|
||||
PRINT_ERROR("Unable to add portal of size %zu\n",
|
||||
PRINT_ERROR("Unable to add portal of size %zu",
|
||||
dev->info.addr_len);
|
||||
res = PTR_ERR(portal);
|
||||
goto out;
|
||||
@@ -431,36 +446,61 @@ int isert_conn_established(struct iscsi_conn *iscsi_conn,
|
||||
return add_new_connection(&isert_listen_dev, iscsi_conn);
|
||||
}
|
||||
|
||||
int isert_connection_closed(struct iscsi_conn *iscsi_conn)
|
||||
static void isert_dev_disconnect(struct iscsi_conn* iscsi_conn)
|
||||
{
|
||||
int res = 0;
|
||||
struct isert_conn_dev* dev = isert_get_priv(iscsi_conn);
|
||||
|
||||
if (dev) {
|
||||
isert_del_timer(dev);
|
||||
dev->state = CS_DISCONNECTED;
|
||||
dev->conn = NULL;
|
||||
if (dev->login_req) {
|
||||
isert_task_abort(dev->login_req);
|
||||
spin_lock(&dev->pdu_lock);
|
||||
dev->login_req = NULL;
|
||||
spin_unlock(&dev->pdu_lock);
|
||||
}
|
||||
wake_up(&dev->waitqueue);
|
||||
isert_dev_release(dev);
|
||||
isert_set_priv(iscsi_conn, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void isert_connection_closed(struct iscsi_conn *iscsi_conn)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (iscsi_conn->rd_state) {
|
||||
res = isert_handle_close_connection(iscsi_conn);
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
isert_handle_close_connection(iscsi_conn);
|
||||
} else {
|
||||
struct isert_conn_dev *dev = isert_get_priv(iscsi_conn);
|
||||
|
||||
if (dev) {
|
||||
isert_del_timer(dev);
|
||||
dev->state = CS_DISCONNECTED;
|
||||
if (dev->login_req) {
|
||||
res = isert_task_abort(dev->login_req);
|
||||
spin_lock(&dev->pdu_lock);
|
||||
dev->login_req = NULL;
|
||||
spin_unlock(&dev->pdu_lock);
|
||||
}
|
||||
|
||||
wake_up(&dev->waitqueue);
|
||||
isert_dev_release(dev);
|
||||
}
|
||||
|
||||
isert_dev_disconnect(iscsi_conn);
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
isert_free_connection(iscsi_conn);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
TRACE_EXIT();
|
||||
}
|
||||
|
||||
void isert_connection_abort(struct iscsi_conn *iscsi_conn)
|
||||
{
|
||||
struct isert_connection *isert_conn = (struct isert_connection *)iscsi_conn;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (!iscsi_conn->rd_state) {
|
||||
if (!test_and_set_bit(ISERT_DISCON_CALLED, &isert_conn->flags)) {
|
||||
isert_dev_disconnect(iscsi_conn);
|
||||
isert_free_connection(iscsi_conn);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
|
||||
TRACE_EXIT();
|
||||
}
|
||||
|
||||
static bool will_read_block(struct isert_conn_dev *dev)
|
||||
@@ -492,13 +532,13 @@ static int isert_open(struct inode *inode, struct file *filp)
|
||||
|
||||
dev = container_of(inode->i_cdev, struct isert_conn_dev, cdev);
|
||||
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
mutex_lock(&isert_listen_dev.conn_lock);
|
||||
if (unlikely(dev->occupied == 0)) {
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
mutex_unlock(&isert_listen_dev.conn_lock);
|
||||
res = -ENODEV; /* already closed */
|
||||
goto out;
|
||||
}
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
mutex_unlock(&isert_listen_dev.conn_lock);
|
||||
|
||||
if (unlikely(!atomic_dec_and_test(&dev->available))) {
|
||||
atomic_inc(&dev->available);
|
||||
@@ -506,9 +546,9 @@ static int isert_open(struct inode *inode, struct file *filp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock(&isert_listen_dev.conn_lock);
|
||||
mutex_lock(&isert_listen_dev.conn_lock);
|
||||
kref_get(&dev->kref);
|
||||
spin_unlock(&isert_listen_dev.conn_lock);
|
||||
mutex_unlock(&isert_listen_dev.conn_lock);
|
||||
|
||||
filp->private_data = dev; /* for other methods */
|
||||
|
||||
@@ -528,13 +568,7 @@ static int isert_release(struct inode *inode, struct file *filp)
|
||||
dev->sg_virt = NULL;
|
||||
dev->is_discovery = 0;
|
||||
|
||||
if (!test_and_set_bit(ISERT_CONN_PASSED, &dev->flags)) {
|
||||
BUG_ON(dev->conn == NULL);
|
||||
isert_close_connection(dev->conn);
|
||||
}
|
||||
|
||||
isert_del_timer(dev);
|
||||
|
||||
isert_delete_conn_dev(dev);
|
||||
isert_dev_release(dev);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -562,23 +596,33 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count,
|
||||
struct isert_conn_dev *dev = filp->private_data;
|
||||
size_t to_read;
|
||||
|
||||
if (dev->state == CS_DISCONNECTED)
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (dev->state == CS_DISCONNECTED) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
if (will_read_block(dev)) {
|
||||
int ret;
|
||||
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
if (filp->f_flags & O_NONBLOCK) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
ret = wait_event_freezable(dev->waitqueue,
|
||||
!will_read_block(dev));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
to_read = min(count, dev->read_len);
|
||||
if (copy_to_user(buf, dev->read_buf, to_read))
|
||||
if (copy_to_user(buf, dev->read_buf, to_read)) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
dev->read_len -= to_read;
|
||||
dev->read_buf += to_read;
|
||||
@@ -590,8 +634,10 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count,
|
||||
dev->sg_virt = isert_vmap_sg(dev->pages,
|
||||
dev->login_req->sg,
|
||||
dev->login_req->sg_cnt);
|
||||
if (!dev->sg_virt)
|
||||
if (!dev->sg_virt) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev->read_buf = dev->sg_virt + ISER_HDRS_SZ;
|
||||
dev->state = CS_REQ_DATA;
|
||||
}
|
||||
@@ -610,11 +656,12 @@ static ssize_t isert_read(struct file *filp, char __user *buf, size_t count,
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT_ERROR("Invalid state in %s (%d)\n", __func__,
|
||||
dev->state);
|
||||
PRINT_ERROR("Invalid state %d", dev->state);
|
||||
to_read = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
@@ -624,12 +671,18 @@ static ssize_t isert_write(struct file *filp, const char __user *buf,
|
||||
struct isert_conn_dev *dev = filp->private_data;
|
||||
size_t to_write;
|
||||
|
||||
if (dev->state == CS_DISCONNECTED)
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (dev->state == CS_DISCONNECTED) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
to_write = min(count, dev->write_len);
|
||||
if (copy_from_user(dev->write_buf, buf, to_write))
|
||||
if (copy_from_user(dev->write_buf, buf, to_write)) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
dev->write_len -= to_write;
|
||||
dev->write_buf += to_write;
|
||||
@@ -641,8 +694,10 @@ static ssize_t isert_write(struct file *filp, const char __user *buf,
|
||||
dev->sg_virt = isert_vmap_sg(dev->pages,
|
||||
dev->login_rsp->sg,
|
||||
dev->login_rsp->sg_cnt);
|
||||
if (!dev->sg_virt)
|
||||
if (!dev->sg_virt) {
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev->write_buf = dev->sg_virt + ISER_HDRS_SZ;
|
||||
dev->write_len = dev->login_rsp->bufflen -
|
||||
sizeof(dev->login_rsp->pdu.bhs);
|
||||
@@ -654,11 +709,12 @@ static ssize_t isert_write(struct file *filp, const char __user *buf,
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT_ERROR("Invalid state in %s (%d)\n", __func__,
|
||||
dev->state);
|
||||
PRINT_ERROR("Invalid state %d", dev->state);
|
||||
to_write = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
|
||||
return to_write;
|
||||
}
|
||||
|
||||
@@ -678,6 +734,8 @@ static long isert_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
mutex_lock(&conn_mgmt_mutex);
|
||||
|
||||
if (dev->state == CS_DISCONNECTED) {
|
||||
res = -EPIPE;
|
||||
goto out;
|
||||
@@ -764,6 +822,7 @@ static long isert_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&conn_mgmt_mutex);
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
@@ -914,7 +973,7 @@ static void __init isert_setup_listener_cdev(struct isert_listener_dev *dev)
|
||||
init_waitqueue_head(&dev->waitqueue);
|
||||
INIT_LIST_HEAD(&dev->new_conn_list);
|
||||
INIT_LIST_HEAD(&dev->curr_conn_list);
|
||||
spin_lock_init(&dev->conn_lock);
|
||||
mutex_init(&dev->conn_lock);
|
||||
atomic_set(&dev->available, 1);
|
||||
err = cdev_add(&dev->cdev, dev->devno, 1);
|
||||
/* Fail gracefully if need be */
|
||||
@@ -944,7 +1003,7 @@ int __init isert_init_login_devs(unsigned int ndevs)
|
||||
isert_major = MAJOR(devno);
|
||||
|
||||
if (unlikely(res < 0)) {
|
||||
PRINT_ERROR("isert: can't get major %d\n", isert_major);
|
||||
PRINT_ERROR("can't get major %d", isert_major);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -969,7 +1028,7 @@ int __init isert_init_login_devs(unsigned int ndevs)
|
||||
|
||||
res = isert_datamover_init();
|
||||
if (unlikely(res)) {
|
||||
PRINT_ERROR("Unable to initialize datamover: %d\n", res);
|
||||
PRINT_ERROR("Unable to initialize datamover: %d", res);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user