Skip to content

Commit

Permalink
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/nab/target-pending

Pull target updates from Nicholas Bellinger:
 "It has been a very busy development cycle this time around in target
  land, with the highlights including:

   - Kill struct se_subsystem_dev, in favor of direct se_device usage
     (hch)
   - Simplify reservations code by combining SPC-3 + SCSI-2 support for
     virtual backends only (hch)
   - Simplify ALUA code for virtual only backends, and remove left over
     abstractions (hch)
   - Pass sense_reason_t as return value for I/O submission path (hch)
   - Refactor MODE_SENSE emulation to allow for easier addition of new
     mode pages.  (roland)
   - Add emulation of MODE_SELECT (roland)
   - Fix bug in handling of ExpStatSN wrap-around (steve)
   - Fix bug in TMR ABORT_TASK lookup in qla2xxx target (steve)
   - Add WRITE_SAME w/ UNMAP=0 support for IBLOCK backends (nab)
   - Convert ib_srpt to use modern target_submit_cmd caller + drop
     legacy ioctx->kref usage (nab)
   - Convert ib_srpt to use modern target_submit_tmr caller (nab)
   - Add link_magic for fabric allow_link destination target_items for
     symlinks within target_core_fabric_configfs.c code (nab)
   - Allocate pointers in instead of full structs for
     config_group->default_groups (sebastian)
   - Fix 32-bit highmem breakage for FILEIO (sebastian)

  All told, hch was able to shave off another ~1K LOC by killing the
  se_subsystem_dev abstraction, along with a number of PR + ALUA
  simplifications.  Also, a nice patch by Roland is the refactoring of
  MODE_SENSE handling, along with the addition of initial MODE_SELECT
  emulation support for virtual backends.

  Sebastian found a long-standing issue wrt to allocation of full
  config_group instead of pointers for config_group->default_group[]
  setup in a number of areas, which ends up saving memory with big
  configurations.  He also managed to fix another long-standing BUG wrt
  to broken 32-bit highmem support within the FILEIO backend driver.

  Thank you again to everyone who contributed this round!"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (50 commits)
  target/iscsi_target: Add NodeACL tags for initiator group support
  target/tcm_fc: fix the lockdep warning due to inconsistent lock state
  sbp-target: fix error path in sbp_make_tpg()
  sbp-target: use simple assignment in tgt_agent_rw_agent_state()
  iscsi-target: use kstrdup() for iscsi_param
  target/file: merge fd_do_readv() and fd_do_writev()
  target/file: Fix 32-bit highmem breakage for SGL -> iovec mapping
  target: Add link_magic for fabric allow_link destination target_items
  ib_srpt: Convert TMR path to target_submit_tmr
  ib_srpt: Convert I/O path to target_submit_cmd + drop legacy ioctx->kref
  target: Make spc_get_write_same_sectors return sector_t
  target/configfs: use kmalloc() instead of kzalloc() for default groups
  target/configfs: allocate only 6 slots for dev_cg->default_groups
  target/configfs: allocate pointers instead of full struct for default_groups
  target: update error handling for sbc_setup_write_same()
  iscsit: use GFP_ATOMIC under spin lock
  iscsi_target: Remove redundant null check before kfree
  target/iblock: Forward declare bio helpers
  target: Clean up flow in transport_check_aborted_status()
  target: Clean up logic in transport_put_cmd()
  ...
  • Loading branch information
Linus Torvalds committed Dec 15, 2012
2 parents 115b1cc + 79e62fc commit 5bd665f
Show file tree
Hide file tree
Showing 49 changed files with 2,845 additions and 3,989 deletions.
178 changes: 76 additions & 102 deletions drivers/infiniband/ulp/srpt/ib_srpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}
}

/**
Expand Down Expand Up @@ -1712,10 +1686,10 @@ static uint64_t srpt_unpack_lun(const uint8_t *lun, int len)

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);
}

/**
Expand All @@ -1730,12 +1704,12 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
uint64_t unpacked_lun;
u64 data_len;
enum dma_data_direction dir;
int ret;
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;

Expand All @@ -1755,40 +1729,26 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
break;
}

ret = srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len);
if (ret) {
if (srpt_get_desc_tbl(send_ioctx, srp_cmd, &dir, &data_len)) {
printk(KERN_ERR "0x%llx: parsing SRP descriptor table failed.\n",
srp_cmd->tag);
cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
ret = TCM_INVALID_CDB_FIELD;
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));
if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) {
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 < 0) {
kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) {
srpt_queue_status(cmd);
return 0;
} else
goto send_sense;
}

transport_handle_cdb_direct(cmd);
return 0;

send_sense:
transport_send_check_condition_and_sense(cmd, cmd->scsi_sense_reason,
0);
transport_send_check_condition_and_sense(cmd, ret, 0);
return -1;
}

Expand Down Expand Up @@ -1865,9 +1825,11 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
{
struct srp_tsk_mgmt *srp_tsk;
struct se_cmd *cmd;
struct se_session *sess = ch->sess;
uint64_t unpacked_lun;
uint32_t tag = 0;
int tcm_tmr;
int res;
int rc;

BUG_ON(!send_ioctx);

Expand All @@ -1882,39 +1844,32 @@ static void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch,
send_ioctx->tag = srp_tsk->tag;
tcm_tmr = srp_tmr_to_tcm(srp_tsk->tsk_mgmt_func);
if (tcm_tmr < 0) {
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response =
TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED;
goto process_tmr;
}
res = core_tmr_alloc_req(cmd, NULL, tcm_tmr, GFP_KERNEL);
if (res < 0) {
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
goto process_tmr;
goto fail;
}

unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_tsk->lun,
sizeof(srp_tsk->lun));
res = transport_lookup_tmr_lun(&send_ioctx->cmd, unpacked_lun);
if (res) {
pr_debug("rejecting TMR for LUN %lld\n", unpacked_lun);
send_ioctx->cmd.se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
send_ioctx->cmd.se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
goto process_tmr;
}

if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK)
srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);

process_tmr:
kref_get(&send_ioctx->kref);
if (!(send_ioctx->cmd.se_cmd_flags & SCF_SCSI_CDB_EXCEPTION))
transport_generic_handle_tmr(&send_ioctx->cmd);
else
transport_send_check_condition_and_sense(cmd,
cmd->scsi_sense_reason, 0);

if (srp_tsk->tsk_mgmt_func == SRP_TSK_ABORT_TASK) {
rc = srpt_rx_mgmt_fn_tag(send_ioctx, srp_tsk->task_tag);
if (rc < 0) {
send_ioctx->cmd.se_tmr_req->response =
TMR_TASK_DOES_NOT_EXIST;
goto fail;
}
tag = srp_tsk->task_tag;
}
rc = target_submit_tmr(&send_ioctx->cmd, sess, NULL, unpacked_lun,
srp_tsk, tcm_tmr, GFP_KERNEL, tag,
TARGET_SCF_ACK_KREF);
if (rc != 0) {
send_ioctx->cmd.se_tmr_req->response = TMR_FUNCTION_REJECTED;
goto fail;
}
return;
fail:
transport_send_check_condition_and_sense(cmd, 0, 0); // XXX:
}

/**
Expand Down Expand Up @@ -1956,10 +1911,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);
Expand Down Expand Up @@ -2365,6 +2316,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,
Expand All @@ -2373,8 +2325,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);
Expand Down Expand Up @@ -3099,7 +3056,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:
Expand Down Expand Up @@ -3490,6 +3447,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);
}

/**
Expand Down
1 change: 0 additions & 1 deletion drivers/infiniband/ulp/srpt/ib_srpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ struct srpt_recv_ioctx {
struct srpt_send_ioctx {
struct srpt_ioctx ioctx;
struct srpt_rdma_ch *ch;
struct kref kref;
struct rdma_iu *rdma_ius;
struct srp_direct_buf *rbufs;
struct srp_direct_buf single_rbuf;
Expand Down
21 changes: 20 additions & 1 deletion drivers/scsi/qla2xxx/qla_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -1264,8 +1264,27 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess)
{
struct qla_hw_data *ha = vha->hw;
struct se_session *se_sess = sess->se_sess;
struct qla_tgt_mgmt_cmd *mcmd;
struct se_cmd *se_cmd;
u32 lun = 0;
int rc;
bool found_lun = false;

spin_lock(&se_sess->sess_cmd_lock);
list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
struct qla_tgt_cmd *cmd =
container_of(se_cmd, struct qla_tgt_cmd, se_cmd);
if (cmd->tag == abts->exchange_addr_to_abort) {
lun = cmd->unpacked_lun;
found_lun = true;
break;
}
}
spin_unlock(&se_sess->sess_cmd_lock);

if (!found_lun)
return -ENOENT;

ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
"qla_target(%d): task abort (tag=%d)\n",
Expand All @@ -1283,7 +1302,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
mcmd->sess = sess;
memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts));

rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, TMR_ABORT_TASK,
rc = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, TMR_ABORT_TASK,
abts->exchange_addr_to_abort);
if (rc != 0) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052,
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/tcm_qla2xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,8 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work)
return;
}

cmd->se_cmd.scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD;
transport_generic_request_failure(&cmd->se_cmd);
transport_generic_request_failure(&cmd->se_cmd,
TCM_CHECK_CONDITION_ABORT_CMD);
return;
}

Expand Down
Loading

0 comments on commit 5bd665f

Please sign in to comment.