|
@@ -1269,7 +1269,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
|
|
|
return ioctx;
|
|
|
|
|
|
BUG_ON(ioctx->ch != ch);
|
|
|
- kref_init(&ioctx->kref);
|
|
|
spin_lock_init(&ioctx->spinlock);
|
|
|
ioctx->state = SRPT_STATE_NEW;
|
|
|
ioctx->n_rbuf = 0;
|
|
@@ -1290,39 +1289,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
|
|
|
return ioctx;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * srpt_put_send_ioctx() - Free up resources.
|
|
|
- */
|
|
|
-static void srpt_put_send_ioctx(struct srpt_send_ioctx *ioctx)
|
|
|
-{
|
|
|
- struct srpt_rdma_ch *ch;
|
|
|
- unsigned long flags;
|
|
|
-
|
|
|
- BUG_ON(!ioctx);
|
|
|
- ch = ioctx->ch;
|
|
|
- BUG_ON(!ch);
|
|
|
-
|
|
|
- WARN_ON(srpt_get_cmd_state(ioctx) != SRPT_STATE_DONE);
|
|
|
-
|
|
|
- srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
|
|
|
- transport_generic_free_cmd(&ioctx->cmd, 0);
|
|
|
-
|
|
|
- if (ioctx->n_rbuf > 1) {
|
|
|
- kfree(ioctx->rbufs);
|
|
|
- ioctx->rbufs = NULL;
|
|
|
- ioctx->n_rbuf = 0;
|
|
|
- }
|
|
|
-
|
|
|
- spin_lock_irqsave(&ch->spinlock, flags);
|
|
|
- list_add(&ioctx->free_list, &ch->free_list);
|
|
|
- spin_unlock_irqrestore(&ch->spinlock, flags);
|
|
|
-}
|
|
|
-
|
|
|
-static void srpt_put_send_ioctx_kref(struct kref *kref)
|
|
|
-{
|
|
|
- srpt_put_send_ioctx(container_of(kref, struct srpt_send_ioctx, kref));
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* srpt_abort_cmd() - Abort a SCSI command.
|
|
|
* @ioctx: I/O context associated with the SCSI command.
|
|
@@ -1359,8 +1325,14 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
|
|
|
}
|
|
|
spin_unlock_irqrestore(&ioctx->spinlock, flags);
|
|
|
|
|
|
- if (state == SRPT_STATE_DONE)
|
|
|
+ if (state == SRPT_STATE_DONE) {
|
|
|
+ struct srpt_rdma_ch *ch = ioctx->ch;
|
|
|
+
|
|
|
+ BUG_ON(ch->sess == NULL);
|
|
|
+
|
|
|
+ target_put_sess_cmd(ch->sess, &ioctx->cmd);
|
|
|
goto out;
|
|
|
+ }
|
|
|
|
|
|
pr_debug("Aborting cmd with state %d and tag %lld\n", state,
|
|
|
ioctx->tag);
|
|
@@ -1395,11 +1367,11 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
|
|
|
spin_lock_irqsave(&ioctx->cmd.t_state_lock, flags);
|
|
|
ioctx->cmd.transport_state |= CMD_T_LUN_STOP;
|
|
|
spin_unlock_irqrestore(&ioctx->cmd.t_state_lock, flags);
|
|
|
- kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
+ target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
|
|
break;
|
|
|
case SRPT_STATE_MGMT_RSP_SENT:
|
|
|
srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
|
|
- kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
+ target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
|
|
break;
|
|
|
default:
|
|
|
WARN_ON("ERROR: unexpected command state");
|
|
@@ -1457,11 +1429,13 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch,
|
|
|
&& state != SRPT_STATE_DONE))
|
|
|
pr_debug("state = %d\n", state);
|
|
|
|
|
|
- if (state != SRPT_STATE_DONE)
|
|
|
- kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
- else
|
|
|
+ if (state != SRPT_STATE_DONE) {
|
|
|
+ srpt_unmap_sg_to_ib_sge(ch, ioctx);
|
|
|
+ transport_generic_free_cmd(&ioctx->cmd, 0);
|
|
|
+ } else {
|
|
|
printk(KERN_ERR "IB completion has been received too late for"
|
|
|
" wr_id = %u.\n", ioctx->ioctx.index);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1712,10 +1686,10 @@ out_err:
|
|
|
|
|
|
static int srpt_check_stop_free(struct se_cmd *cmd)
|
|
|
{
|
|
|
- struct srpt_send_ioctx *ioctx;
|
|
|
+ struct srpt_send_ioctx *ioctx = container_of(cmd,
|
|
|
+ struct srpt_send_ioctx, cmd);
|
|
|
|
|
|
- ioctx = container_of(cmd, struct srpt_send_ioctx, cmd);
|
|
|
- return kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
+ return target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1731,11 +1705,11 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
|
|
|
u64 data_len;
|
|
|
enum dma_data_direction dir;
|
|
|
sense_reason_t ret;
|
|
|
+ int rc;
|
|
|
|
|
|
BUG_ON(!send_ioctx);
|
|
|
|
|
|
srp_cmd = recv_ioctx->ioctx.buf;
|
|
|
- kref_get(&send_ioctx->kref);
|
|
|
cmd = &send_ioctx->cmd;
|
|
|
send_ioctx->tag = srp_cmd->tag;
|
|
|
|
|
@@ -1759,30 +1733,18 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
|
|
|
printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
|
|
|
srp_cmd->tag);
|
|
|
ret = TCM_INVALID_CDB_FIELD;
|
|
|
- kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
goto send_sense;
|
|
|
}
|
|
|
|
|
|
- cmd->data_length = data_len;
|
|
|
- cmd->data_direction = dir;
|
|
|
unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
|
|
|
sizeof(srp_cmd->lun));
|
|
|
- ret = transport_lookup_cmd_lun(cmd, unpacked_lun);
|
|
|
- if (ret) {
|
|
|
- kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
+ rc = target_submit_cmd(cmd, ch->sess, srp_cmd->cdb,
|
|
|
+ &send_ioctx->sense_data[0], unpacked_lun, data_len,
|
|
|
+ MSG_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF);
|
|
|
+ if (rc != 0) {
|
|
|
+ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
|
|
goto send_sense;
|
|
|
}
|
|
|
- ret = target_setup_cmd_from_cdb(cmd, srp_cmd->cdb);
|
|
|
- if (ret) {
|
|
|
- kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
- if (ret == TCM_RESERVATION_CONFLICT) {
|
|
|
- srpt_queue_status(cmd);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- goto send_sense;
|
|
|
- }
|
|
|
-
|
|
|
- transport_handle_cdb_direct(cmd);
|
|
|
return 0;
|
|
|
|
|
|
send_sense:
|
|
@@ -1884,6 +1846,9 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
|
|
|
TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
|
|
|
goto fail;
|
|
|
}
|
|
|
+ transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
|
|
|
+ 0, DMA_NONE, MSG_SIMPLE_TAG, send_ioctx->sense_data);
|
|
|
+
|
|
|
res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
|
|
|
if (res < 0) {
|
|
|
send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
|
|
@@ -1902,11 +1867,9 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
|
|
|
if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
|
|
|
srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
|
|
|
|
|
|
- kref_get(&send_ioctx->kref);
|
|
|
transport_generic_handle_tmr(&send_ioctx->cmd);
|
|
|
return;
|
|
|
fail:
|
|
|
- kref_get(&send_ioctx->kref);
|
|
|
transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
|
|
|
}
|
|
|
|
|
@@ -1949,10 +1912,6 @@ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- transport_init_se_cmd(&send_ioctx->cmd, &srpt_target->tf_ops, ch->sess,
|
|
|
- 0, DMA_NONE, MSG_SIMPLE_TAG,
|
|
|
- send_ioctx->sense_data);
|
|
|
-
|
|
|
switch (srp_cmd->opcode) {
|
|
|
case SRP_CMD:
|
|
|
srpt_handle_cmd(ch, recv_ioctx, send_ioctx);
|
|
@@ -2358,6 +2317,7 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|
|
{
|
|
|
struct srpt_rdma_ch *ch;
|
|
|
struct srpt_device *sdev;
|
|
|
+ struct se_session *se_sess;
|
|
|
|
|
|
ch = container_of(w, struct srpt_rdma_ch, release_work);
|
|
|
pr_debug("ch = %p; ch->sess = %p; release_done = %p\n", ch, ch->sess,
|
|
@@ -2366,8 +2326,13 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|
|
sdev = ch->sport->sdev;
|
|
|
BUG_ON(!sdev);
|
|
|
|
|
|
- transport_deregister_session_configfs(ch->sess);
|
|
|
- transport_deregister_session(ch->sess);
|
|
|
+ se_sess = ch->sess;
|
|
|
+ BUG_ON(!se_sess);
|
|
|
+
|
|
|
+ target_wait_for_sess_cmds(se_sess, 0);
|
|
|
+
|
|
|
+ transport_deregister_session_configfs(se_sess);
|
|
|
+ transport_deregister_session(se_sess);
|
|
|
ch->sess = NULL;
|
|
|
|
|
|
srpt_destroy_ch_ib(ch);
|
|
@@ -3092,7 +3057,7 @@ static int srpt_queue_response(struct se_cmd *cmd)
|
|
|
ioctx->tag);
|
|
|
srpt_unmap_sg_to_ib_sge(ch, ioctx);
|
|
|
srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
|
|
|
- kref_put(&ioctx->kref, srpt_put_send_ioctx_kref);
|
|
|
+ target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
|
|
|
}
|
|
|
|
|
|
out:
|
|
@@ -3483,6 +3448,23 @@ static u32 srpt_tpg_get_inst_index(struct se_portal_group *se_tpg)
|
|
|
|
|
|
static void srpt_release_cmd(struct se_cmd *se_cmd)
|
|
|
{
|
|
|
+ struct srpt_send_ioctx *ioctx = container_of(se_cmd,
|
|
|
+ struct srpt_send_ioctx, cmd);
|
|
|
+ struct srpt_rdma_ch *ch = ioctx->ch;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ WARN_ON(ioctx->state != SRPT_STATE_DONE);
|
|
|
+ WARN_ON(ioctx->mapped_sg_count != 0);
|
|
|
+
|
|
|
+ if (ioctx->n_rbuf > 1) {
|
|
|
+ kfree(ioctx->rbufs);
|
|
|
+ ioctx->rbufs = NULL;
|
|
|
+ ioctx->n_rbuf = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_lock_irqsave(&ch->spinlock, flags);
|
|
|
+ list_add(&ioctx->free_list, &ch->free_list);
|
|
|
+ spin_unlock_irqrestore(&ch->spinlock, flags);
|
|
|
}
|
|
|
|
|
|
/**
|