Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull scsi-target changes from Nicholas Bellinger:
 "There has been lots of work in existing code in a number of areas this
  past cycle.  The major highlights have been:

   * Removal of transport_do_task_sg_chain() from core + fabrics
     (Roland)
   * target-core: Removal of se_task abstraction from target-core and
     enforce hw_max_sectors for pSCSI backends (hch)
   * Re-factoring of iscsi-target tx immediate/response queues (agrover)
   * Conversion of iscsi-target back to using target core memory
     allocation logic (agrover)

  We've had one last minute iscsi-target patch go into for-next to
  address a nasty regression bug related to the target core allocation
  logic conversion from agrover that is not included in friday's
  linux-next build, but has been included in this series.

  On the new fabric module code front for-3.5, here is a brief status
  update for the three currently in flight this round:

   * usb-gadget target driver:

  Sebastian Siewior's driver for supporting usb-gadget target mode
  operation.  This will be going out as a separate PULL request from
  target-pending/usb-target-merge with subsystem maintainer ACKs.  There
  is one minor target-core patch in this series required to function.

   * sbp ieee-1394/firewire target driver:

  Chris Boot's driver for supportting the Serial Block Protocol (SBP)
  across IEEE-1394 Firewire hardware.  This will be going out as a
  separate PULL request from target-pending/sbp-target-merge with two
  additional drivers/firewire/ patches w/ subsystem maintainer ACKs.

   * qla2xxx LLD target mode infrastructure changes + tcm_qla2xxx:

  The Qlogic >= 24xx series HW target mode LLD infrastructure patch-set
  and tcm_qla2xxx fabric driver.  Support for FC target mode using
  qla2xxx LLD code has been officially submitted by Qlogic to James
  below, and is currently outstanding but not yet merged into
  scsi.git/for-next..

    [PATCH 00/22] qla2xxx: Updates for scsi "misc" branch
    http://www.spinics.net/lists/linux-scsi/msg59350.html

  Note there are *zero* direct dependencies upon this for-next series
  for the qla2xxx LLD target + tcm_qla2xxx patches submitted above, and
  over the last days the target mode team has been tracking down an
  tcm_qla2xxx specific active I/O shutdown bug that appears to now be
  almost squashed for 3.5-rc-fixes."

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (47 commits)
  iscsi-target: Fix iov_count calculation bug in iscsit_allocate_iovecs
  iscsi-target: remove dead code in iscsi_check_valuelist_for_support
  target: Handle ATA_16 passthrough for pSCSI backend devices
  target: Add MI_REPORT_TARGET_PGS ext. header + implict_trans_secs attribute
  target: Fix MAINTENANCE_IN service action CDB checks to use lower 5 bits
  target: add support for the WRITE_VERIFY command
  target: make target_put_session void
  target: cleanup transport_execute_tasks()
  target: Remove max_sectors device attribute for modern se_task less code
  target: lock => unlock typo in transport_lun_wait_for_tasks
  target: Enforce hw_max_sectors for SCF_SCSI_DATA_SG_IO_CDB
  target: remove the t_se_count field in struct se_cmd
  target: remove the t_task_cdbs_ex_left field in struct se_cmd
  target: remove the t_task_cdbs_left field in struct se_cmd
  target: remove struct se_task
  target: move the state and execute lists to the command
  target: simplify command to task linkage
  target: always allocate a single task
  target: replace ->execute_task with ->execute_cmd
  target: remove the task_sectors field in struct se_task
  ...
This commit is contained in:
Linus Torvalds
2012-05-21 17:37:09 -07:00
41 changed files with 1332 additions and 2321 deletions
File diff suppressed because it is too large Load Diff
+1 -2
View File
@@ -18,8 +18,7 @@ extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8);
extern int iscsit_send_r2t(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, int);
extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, bool recovery);
extern void iscsit_thread_get_cpumask(struct iscsi_conn *);
extern int iscsi_target_tx_thread(void *);
extern int iscsi_target_rx_thread(void *);
+1 -1
View File
@@ -1538,7 +1538,7 @@ static int lio_write_pending(struct se_cmd *se_cmd)
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
if (!cmd->immediate_data && !cmd->unsolicited_data)
return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 1);
return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false);
return 0;
}
+2 -10
View File
@@ -296,12 +296,11 @@ struct iscsi_datain_req {
u32 runlength;
u32 data_length;
u32 data_offset;
u32 data_offset_end;
u32 data_sn;
u32 next_burst_len;
u32 read_data_done;
u32 seq_send_order;
struct list_head dr_list;
struct list_head cmd_datain_node;
} ____cacheline_aligned;
struct iscsi_ooo_cmdsn {
@@ -381,8 +380,6 @@ struct iscsi_cmd {
u32 buf_ptr_size;
/* Used to store DataDigest */
u32 data_crc;
/* Total size in bytes associated with command */
u32 data_length;
/* Counter for MaxOutstandingR2T */
u32 outstanding_r2ts;
/* Next R2T Offset when DataSequenceInOrder=Yes */
@@ -464,16 +461,13 @@ struct iscsi_cmd {
/* Session the command is part of, used for connection recovery */
struct iscsi_session *sess;
/* list_head for connection list */
struct list_head i_list;
struct list_head i_conn_node;
/* The TCM I/O descriptor that is accessed via container_of() */
struct se_cmd se_cmd;
/* Sense buffer that will be mapped into outgoing status */
#define ISCSI_SENSE_BUFFER_LEN (TRANSPORT_SENSE_BUFFER + 2)
unsigned char sense_buffer[ISCSI_SENSE_BUFFER_LEN];
struct scatterlist *t_mem_sg;
u32 t_mem_sg_nents;
u32 padding;
u8 pad_bytes[4];
@@ -500,8 +494,6 @@ struct iscsi_conn {
u8 network_transport;
enum iscsi_timer_flags_table nopin_timer_flags;
enum iscsi_timer_flags_table nopin_response_timer_flags;
u8 tx_immediate_queue;
u8 tx_response_queue;
/* Used to know what thread encountered a transport failure */
u8 which_thread;
/* connection id assigned by the Initiator */
@@ -37,7 +37,7 @@ struct iscsi_datain_req *iscsit_allocate_datain_req(void)
" struct iscsi_datain_req\n");
return NULL;
}
INIT_LIST_HEAD(&dr->dr_list);
INIT_LIST_HEAD(&dr->cmd_datain_node);
return dr;
}
@@ -45,14 +45,14 @@ struct iscsi_datain_req *iscsit_allocate_datain_req(void)
void iscsit_attach_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
{
spin_lock(&cmd->datain_lock);
list_add_tail(&dr->dr_list, &cmd->datain_list);
list_add_tail(&dr->cmd_datain_node, &cmd->datain_list);
spin_unlock(&cmd->datain_lock);
}
void iscsit_free_datain_req(struct iscsi_cmd *cmd, struct iscsi_datain_req *dr)
{
spin_lock(&cmd->datain_lock);
list_del(&dr->dr_list);
list_del(&dr->cmd_datain_node);
spin_unlock(&cmd->datain_lock);
kmem_cache_free(lio_dr_cache, dr);
@@ -63,8 +63,8 @@ void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd)
struct iscsi_datain_req *dr, *dr_tmp;
spin_lock(&cmd->datain_lock);
list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, dr_list) {
list_del(&dr->dr_list);
list_for_each_entry_safe(dr, dr_tmp, &cmd->datain_list, cmd_datain_node) {
list_del(&dr->cmd_datain_node);
kmem_cache_free(lio_dr_cache, dr);
}
spin_unlock(&cmd->datain_lock);
@@ -72,17 +72,14 @@ void iscsit_free_all_datain_reqs(struct iscsi_cmd *cmd)
struct iscsi_datain_req *iscsit_get_datain_req(struct iscsi_cmd *cmd)
{
struct iscsi_datain_req *dr;
if (list_empty(&cmd->datain_list)) {
pr_err("cmd->datain_list is empty for ITT:"
" 0x%08x\n", cmd->init_task_tag);
return NULL;
}
list_for_each_entry(dr, &cmd->datain_list, dr_list)
break;
return dr;
return list_first_entry(&cmd->datain_list, struct iscsi_datain_req,
cmd_datain_node);
}
/*
@@ -113,7 +110,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_yes(
read_data_done = (!dr->recovery) ?
cmd->read_data_done : dr->read_data_done;
read_data_left = (cmd->data_length - read_data_done);
read_data_left = (cmd->se_cmd.data_length - read_data_done);
if (!read_data_left) {
pr_err("ITT: 0x%08x read_data_left is zero!\n",
cmd->init_task_tag);
@@ -212,7 +209,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
seq_send_order = (!dr->recovery) ?
cmd->seq_send_order : dr->seq_send_order;
read_data_left = (cmd->data_length - read_data_done);
read_data_left = (cmd->se_cmd.data_length - read_data_done);
if (!read_data_left) {
pr_err("ITT: 0x%08x read_data_left is zero!\n",
cmd->init_task_tag);
@@ -231,8 +228,8 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
offset = (seq->offset + seq->next_burst_len);
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->data_length) {
datain->length = (cmd->data_length - offset);
cmd->se_cmd.data_length) {
datain->length = (cmd->se_cmd.data_length - offset);
datain->offset = offset;
datain->flags |= ISCSI_FLAG_CMD_FINAL;
@@ -264,7 +261,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_yes(
}
}
if ((read_data_done + datain->length) == cmd->data_length)
if ((read_data_done + datain->length) == cmd->se_cmd.data_length)
datain->flags |= ISCSI_FLAG_DATA_STATUS;
datain->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
@@ -333,7 +330,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no(
read_data_done = (!dr->recovery) ?
cmd->read_data_done : dr->read_data_done;
read_data_left = (cmd->data_length - read_data_done);
read_data_left = (cmd->se_cmd.data_length - read_data_done);
if (!read_data_left) {
pr_err("ITT: 0x%08x read_data_left is zero!\n",
cmd->init_task_tag);
@@ -344,7 +341,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_yes_and_no(
if (!pdu)
return dr;
if ((read_data_done + pdu->length) == cmd->data_length) {
if ((read_data_done + pdu->length) == cmd->se_cmd.data_length) {
pdu->flags |= (ISCSI_FLAG_CMD_FINAL | ISCSI_FLAG_DATA_STATUS);
if (conn->sess->sess_ops->ErrorRecoveryLevel > 0)
pdu->flags |= ISCSI_FLAG_DATA_ACK;
@@ -433,7 +430,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no(
seq_send_order = (!dr->recovery) ?
cmd->seq_send_order : dr->seq_send_order;
read_data_left = (cmd->data_length - read_data_done);
read_data_left = (cmd->se_cmd.data_length - read_data_done);
if (!read_data_left) {
pr_err("ITT: 0x%08x read_data_left is zero!\n",
cmd->init_task_tag);
@@ -463,7 +460,7 @@ static struct iscsi_datain_req *iscsit_set_datain_values_no_and_no(
} else
seq->next_burst_len += pdu->length;
if ((read_data_done + pdu->length) == cmd->data_length)
if ((read_data_done + pdu->length) == cmd->se_cmd.data_length)
pdu->flags |= ISCSI_FLAG_DATA_STATUS;
pdu->data_sn = (!dr->recovery) ? cmd->data_sn++ : dr->data_sn++;
+17 -14
View File
@@ -48,9 +48,9 @@ void iscsit_set_dataout_sequence_values(
if (cmd->unsolicited_data) {
cmd->seq_start_offset = cmd->write_data_done;
cmd->seq_end_offset = (cmd->write_data_done +
(cmd->data_length >
(cmd->se_cmd.data_length >
conn->sess->sess_ops->FirstBurstLength) ?
conn->sess->sess_ops->FirstBurstLength : cmd->data_length);
conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length);
return;
}
@@ -59,15 +59,15 @@ void iscsit_set_dataout_sequence_values(
if (!cmd->seq_start_offset && !cmd->seq_end_offset) {
cmd->seq_start_offset = cmd->write_data_done;
cmd->seq_end_offset = (cmd->data_length >
cmd->seq_end_offset = (cmd->se_cmd.data_length >
conn->sess->sess_ops->MaxBurstLength) ?
(cmd->write_data_done +
conn->sess->sess_ops->MaxBurstLength) : cmd->data_length;
conn->sess->sess_ops->MaxBurstLength) : cmd->se_cmd.data_length;
} else {
cmd->seq_start_offset = cmd->seq_end_offset;
cmd->seq_end_offset = ((cmd->seq_end_offset +
conn->sess->sess_ops->MaxBurstLength) >=
cmd->data_length) ? cmd->data_length :
cmd->se_cmd.data_length) ? cmd->se_cmd.data_length :
(cmd->seq_end_offset +
conn->sess->sess_ops->MaxBurstLength);
}
@@ -182,13 +182,13 @@ static int iscsit_dataout_check_unsolicited_sequence(
if (!conn->sess->sess_ops->DataPDUInOrder)
goto out;
if ((first_burst_len != cmd->data_length) &&
if ((first_burst_len != cmd->se_cmd.data_length) &&
(first_burst_len != conn->sess->sess_ops->FirstBurstLength)) {
pr_err("Unsolicited non-immediate data"
" received %u does not equal FirstBurstLength: %u, and"
" does not equal ExpXferLen %u.\n", first_burst_len,
conn->sess->sess_ops->FirstBurstLength,
cmd->data_length);
cmd->se_cmd.data_length);
transport_send_check_condition_and_sense(&cmd->se_cmd,
TCM_INCORRECT_AMOUNT_OF_DATA, 0);
return DATAOUT_CANNOT_RECOVER;
@@ -201,10 +201,10 @@ static int iscsit_dataout_check_unsolicited_sequence(
conn->sess->sess_ops->FirstBurstLength);
return DATAOUT_CANNOT_RECOVER;
}
if (first_burst_len == cmd->data_length) {
if (first_burst_len == cmd->se_cmd.data_length) {
pr_err("Command ITT: 0x%08x reached"
" ExpXferLen: %u, but ISCSI_FLAG_CMD_FINAL is not set. protocol"
" error.\n", cmd->init_task_tag, cmd->data_length);
" error.\n", cmd->init_task_tag, cmd->se_cmd.data_length);
return DATAOUT_CANNOT_RECOVER;
}
}
@@ -294,7 +294,7 @@ static int iscsit_dataout_check_sequence(
if ((next_burst_len <
conn->sess->sess_ops->MaxBurstLength) &&
((cmd->write_data_done + payload_length) <
cmd->data_length)) {
cmd->se_cmd.data_length)) {
pr_err("Command ITT: 0x%08x set ISCSI_FLAG_CMD_FINAL"
" before end of DataOUT sequence, protocol"
" error.\n", cmd->init_task_tag);
@@ -319,7 +319,7 @@ static int iscsit_dataout_check_sequence(
return DATAOUT_CANNOT_RECOVER;
}
if ((cmd->write_data_done + payload_length) ==
cmd->data_length) {
cmd->se_cmd.data_length) {
pr_err("Command ITT: 0x%08x reached"
" last DataOUT PDU in sequence but ISCSI_FLAG_"
"CMD_FINAL is not set, protocol error.\n",
@@ -640,9 +640,12 @@ static int iscsit_dataout_post_crc_passed(
cmd->write_data_done += payload_length;
return (cmd->write_data_done == cmd->data_length) ?
DATAOUT_SEND_TO_TRANSPORT : (send_r2t) ?
DATAOUT_SEND_R2T : DATAOUT_NORMAL;
if (cmd->write_data_done == cmd->se_cmd.data_length)
return DATAOUT_SEND_TO_TRANSPORT;
else if (send_r2t)
return DATAOUT_SEND_R2T;
else
return DATAOUT_NORMAL;
}
static int iscsit_dataout_post_crc_failed(
+9 -14
View File
@@ -279,11 +279,9 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no(
* seq->first_datasn and seq->last_datasn have not been set.
*/
if (!seq->sent) {
#if 0
pr_err("Ignoring non-sent sequence 0x%08x ->"
" 0x%08x\n\n", seq->first_datasn,
seq->last_datasn);
#endif
continue;
}
@@ -294,11 +292,10 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no(
*/
if ((seq->first_datasn < begrun) &&
(seq->last_datasn < begrun)) {
#if 0
pr_err("Pre BegRun sequence 0x%08x ->"
" 0x%08x\n", seq->first_datasn,
seq->last_datasn);
#endif
read_data_done += cmd->seq_list[i].xfer_len;
seq->next_burst_len = seq->pdu_send_order = 0;
continue;
@@ -309,11 +306,10 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no(
*/
if ((seq->first_datasn <= begrun) &&
(seq->last_datasn >= begrun)) {
#if 0
pr_err("Found sequence begrun: 0x%08x in"
" 0x%08x -> 0x%08x\n", begrun,
seq->first_datasn, seq->last_datasn);
#endif
seq_send_order = seq->seq_send_order;
data_sn = seq->first_datasn;
seq->next_burst_len = seq->pdu_send_order = 0;
@@ -369,10 +365,9 @@ int iscsit_create_recovery_datain_values_datasequenceinorder_no(
*/
if ((seq->first_datasn > begrun) ||
(seq->last_datasn > begrun)) {
#if 0
pr_err("Post BegRun sequence 0x%08x -> 0x%08x\n",
seq->first_datasn, seq->last_datasn);
#endif
seq->next_burst_len = seq->pdu_send_order = 0;
continue;
}
@@ -526,7 +521,7 @@ int iscsit_handle_status_snack(
found_cmd = 0;
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
if (cmd->stat_sn == begrun) {
found_cmd = 1;
break;
@@ -987,7 +982,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
return 0;
iscsit_set_dataout_sequence_values(cmd);
iscsit_build_r2ts_for_cmd(cmd, cmd->conn, 0);
iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false);
}
return 0;
}
@@ -1121,8 +1116,8 @@ static int iscsit_set_dataout_timeout_values(
if (cmd->unsolicited_data) {
*offset = 0;
*length = (conn->sess->sess_ops->FirstBurstLength >
cmd->data_length) ?
cmd->data_length :
cmd->se_cmd.data_length) ?
cmd->se_cmd.data_length :
conn->sess->sess_ops->FirstBurstLength;
return 0;
}
@@ -1193,8 +1188,8 @@ static void iscsit_handle_dataout_timeout(unsigned long data)
if (conn->sess->sess_ops->DataPDUInOrder) {
pdu_offset = cmd->write_data_done;
if ((pdu_offset + (conn->sess->sess_ops->MaxBurstLength -
cmd->next_burst_len)) > cmd->data_length)
pdu_length = (cmd->data_length -
cmd->next_burst_len)) > cmd->se_cmd.data_length)
pdu_length = (cmd->se_cmd.data_length -
cmd->write_data_done);
else
pdu_length = (conn->sess->sess_ops->MaxBurstLength -
+14 -14
View File
@@ -138,9 +138,9 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
spin_lock(&cr->conn_recovery_cmd_lock);
list_for_each_entry_safe(cmd, cmd_tmp,
&cr->conn_recovery_cmd_list, i_list) {
&cr->conn_recovery_cmd_list, i_conn_node) {
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
cmd->conn = NULL;
spin_unlock(&cr->conn_recovery_cmd_lock);
iscsit_free_cmd(cmd);
@@ -160,9 +160,9 @@ void iscsit_free_connection_recovery_entires(struct iscsi_session *sess)
spin_lock(&cr->conn_recovery_cmd_lock);
list_for_each_entry_safe(cmd, cmd_tmp,
&cr->conn_recovery_cmd_list, i_list) {
&cr->conn_recovery_cmd_list, i_conn_node) {
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
cmd->conn = NULL;
spin_unlock(&cr->conn_recovery_cmd_lock);
iscsit_free_cmd(cmd);
@@ -220,7 +220,7 @@ int iscsit_remove_cmd_from_connection_recovery(
}
cr = cmd->cr;
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
return --cr->cmd_count;
}
@@ -234,7 +234,7 @@ void iscsit_discard_cr_cmds_by_expstatsn(
spin_lock(&cr->conn_recovery_cmd_lock);
list_for_each_entry_safe(cmd, cmd_tmp,
&cr->conn_recovery_cmd_list, i_list) {
&cr->conn_recovery_cmd_list, i_conn_node) {
if (((cmd->deferred_i_state != ISTATE_SENT_STATUS) &&
(cmd->deferred_i_state != ISTATE_REMOVE)) ||
@@ -297,11 +297,11 @@ int iscsit_discard_unacknowledged_ooo_cmdsns_for_conn(struct iscsi_conn *conn)
mutex_unlock(&sess->cmdsn_mutex);
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) {
list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) {
if (!(cmd->cmd_flags & ICF_OOO_CMDSN))
continue;
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
spin_unlock_bh(&conn->cmd_lock);
iscsit_free_cmd(cmd);
@@ -339,14 +339,14 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
/*
* Only perform connection recovery on ISCSI_OP_SCSI_CMD or
* ISCSI_OP_NOOP_OUT opcodes. For all other opcodes call
* list_del(&cmd->i_list); to release the command to the
* list_del(&cmd->i_conn_node); to release the command to the
* session pool and remove it from the connection's list.
*
* Also stop the DataOUT timer, which will be restarted after
* sending the TMR response.
*/
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_list) {
list_for_each_entry_safe(cmd, cmd_tmp, &conn->conn_cmd_list, i_conn_node) {
if ((cmd->iscsi_opcode != ISCSI_OP_SCSI_CMD) &&
(cmd->iscsi_opcode != ISCSI_OP_NOOP_OUT)) {
@@ -355,7 +355,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
" CID: %hu\n", cmd->iscsi_opcode,
cmd->init_task_tag, cmd->cmd_sn, conn->cid);
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
spin_unlock_bh(&conn->cmd_lock);
iscsit_free_cmd(cmd);
spin_lock_bh(&conn->cmd_lock);
@@ -375,7 +375,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
*/
if (!(cmd->cmd_flags & ICF_OOO_CMDSN) && !cmd->immediate_cmd &&
(cmd->cmd_sn >= conn->sess->exp_cmd_sn)) {
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
spin_unlock_bh(&conn->cmd_lock);
iscsit_free_cmd(cmd);
spin_lock_bh(&conn->cmd_lock);
@@ -397,7 +397,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
cmd->sess = conn->sess;
list_del(&cmd->i_list);
list_del(&cmd->i_conn_node);
spin_unlock_bh(&conn->cmd_lock);
iscsit_free_all_datain_reqs(cmd);
@@ -407,7 +407,7 @@ int iscsit_prepare_cmds_for_realligance(struct iscsi_conn *conn)
* Add the struct iscsi_cmd to the connection recovery cmd list
*/
spin_lock(&cr->conn_recovery_cmd_lock);
list_add_tail(&cmd->i_list, &cr->conn_recovery_cmd_list);
list_add_tail(&cmd->i_conn_node, &cr->conn_recovery_cmd_list);
spin_unlock(&cr->conn_recovery_cmd_lock);
spin_lock_bh(&conn->cmd_lock);
@@ -803,14 +803,6 @@ static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_pt
value = simple_strtoul(value_ptr, &tmpptr, 0);
/* #warning FIXME: Fix this */
#if 0
if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) {
pr_err("Illegal value \"%s\" for \"%s\".\n",
value, param->name);
return -1;
}
#endif
if (IS_TYPERANGE_0_TO_2(param)) {
if ((value < 0) || (value > 2)) {
pr_err("Illegal value for \"%s\", must be"
@@ -1045,13 +1037,6 @@ static char *iscsi_check_valuelist_for_support(
tmp2 = strchr(acceptor_values, ',');
if (tmp2)
*tmp2 = '\0';
if (!acceptor_values || !proposer_values) {
if (tmp1)
*tmp1 = ',';
if (tmp2)
*tmp2 = ',';
return NULL;
}
if (!strcmp(acceptor_values, proposer_values)) {
if (tmp2)
*tmp2 = ',';
@@ -1061,8 +1046,6 @@ static char *iscsi_check_valuelist_for_support(
*tmp2++ = ',';
acceptor_values = tmp2;
if (!acceptor_values)
break;
} while (acceptor_values);
if (tmp1)
*tmp1++ = ',';
@@ -24,11 +24,13 @@
#include "iscsi_target_core.h"
#include "iscsi_target_util.h"
#include "iscsi_target_tpg.h"
#include "iscsi_target_seq_pdu_list.h"
#define OFFLOAD_BUF_SIZE 32768
void iscsit_dump_seq_list(struct iscsi_cmd *cmd)
#ifdef DEBUG
static void iscsit_dump_seq_list(struct iscsi_cmd *cmd)
{
int i;
struct iscsi_seq *seq;
@@ -46,7 +48,7 @@ void iscsit_dump_seq_list(struct iscsi_cmd *cmd)
}
}
void iscsit_dump_pdu_list(struct iscsi_cmd *cmd)
static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd)
{
int i;
struct iscsi_pdu *pdu;
@@ -61,6 +63,10 @@ void iscsit_dump_pdu_list(struct iscsi_cmd *cmd)
pdu->length, pdu->pdu_send_order, pdu->seq_no);
}
}
#else
static void iscsit_dump_seq_list(struct iscsi_cmd *cmd) {}
static void iscsit_dump_pdu_list(struct iscsi_cmd *cmd) {}
#endif
static void iscsit_ordered_seq_lists(
struct iscsi_cmd *cmd,
@@ -135,11 +141,11 @@ redo:
seq_count++;
continue;
}
array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
if (!array) {
pr_err("Unable to allocate memory"
" for random array.\n");
return -1;
return -ENOMEM;
}
iscsit_create_random_array(array, seq_count);
@@ -155,11 +161,11 @@ redo:
}
if (seq_count) {
array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
if (!array) {
pr_err("Unable to allocate memory for"
" random array.\n");
return -1;
return -ENOMEM;
}
iscsit_create_random_array(array, seq_count);
@@ -187,10 +193,10 @@ static int iscsit_randomize_seq_lists(
if (!seq_count)
return 0;
array = kzalloc(seq_count * sizeof(u32), GFP_KERNEL);
array = kcalloc(seq_count, sizeof(u32), GFP_KERNEL);
if (!array) {
pr_err("Unable to allocate memory for random array.\n");
return -1;
return -ENOMEM;
}
iscsit_create_random_array(array, seq_count);
@@ -221,11 +227,10 @@ static void iscsit_determine_counts_for_list(
if ((bl->type == PDULIST_UNSOLICITED) ||
(bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
unsolicited_data_length = (cmd->data_length >
conn->sess->sess_ops->FirstBurstLength) ?
conn->sess->sess_ops->FirstBurstLength : cmd->data_length;
unsolicited_data_length = min(cmd->se_cmd.data_length,
conn->sess->sess_ops->FirstBurstLength);
while (offset < cmd->data_length) {
while (offset < cmd->se_cmd.data_length) {
*pdu_count += 1;
if (check_immediate) {
@@ -239,10 +244,10 @@ static void iscsit_determine_counts_for_list(
}
if (unsolicited_data_length > 0) {
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
>= cmd->data_length) {
>= cmd->se_cmd.data_length) {
unsolicited_data_length -=
(cmd->data_length - offset);
offset += (cmd->data_length - offset);
(cmd->se_cmd.data_length - offset);
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
@@ -263,8 +268,8 @@ static void iscsit_determine_counts_for_list(
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->data_length) {
offset += (cmd->data_length - offset);
cmd->se_cmd.data_length) {
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
@@ -283,10 +288,10 @@ static void iscsit_determine_counts_for_list(
/*
* Builds PDU and/or Sequence list, called while DataSequenceInOrder=No
* and DataPDUInOrder=No.
* Builds PDU and/or Sequence list, called while DataSequenceInOrder=No
* or DataPDUInOrder=No.
*/
static int iscsit_build_pdu_and_seq_list(
static int iscsit_do_build_pdu_and_seq_lists(
struct iscsi_cmd *cmd,
struct iscsi_build_list *bl)
{
@@ -306,11 +311,10 @@ static int iscsit_build_pdu_and_seq_list(
if ((bl->type == PDULIST_UNSOLICITED) ||
(bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
unsolicited_data_length = (cmd->data_length >
conn->sess->sess_ops->FirstBurstLength) ?
conn->sess->sess_ops->FirstBurstLength : cmd->data_length;
unsolicited_data_length = min(cmd->se_cmd.data_length,
conn->sess->sess_ops->FirstBurstLength);
while (offset < cmd->data_length) {
while (offset < cmd->se_cmd.data_length) {
pdu_count++;
if (!datapduinorder) {
pdu[i].offset = offset;
@@ -346,21 +350,21 @@ static int iscsit_build_pdu_and_seq_list(
if (unsolicited_data_length > 0) {
if ((offset +
conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->data_length) {
cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_UNSOLICITED;
pdu[i].length =
(cmd->data_length - offset);
(cmd->se_cmd.data_length - offset);
}
if (!datasequenceinorder) {
seq[seq_no].type = SEQTYPE_UNSOLICITED;
seq[seq_no].pdu_count = pdu_count;
seq[seq_no].xfer_len = (burstlength +
(cmd->data_length - offset));
(cmd->se_cmd.data_length - offset));
}
unsolicited_data_length -=
(cmd->data_length - offset);
offset += (cmd->data_length - offset);
(cmd->se_cmd.data_length - offset);
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((offset +
@@ -402,18 +406,18 @@ static int iscsit_build_pdu_and_seq_list(
continue;
}
if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
cmd->data_length) {
cmd->se_cmd.data_length) {
if (!datapduinorder) {
pdu[i].type = PDUTYPE_NORMAL;
pdu[i].length = (cmd->data_length - offset);
pdu[i].length = (cmd->se_cmd.data_length - offset);
}
if (!datasequenceinorder) {
seq[seq_no].type = SEQTYPE_NORMAL;
seq[seq_no].pdu_count = pdu_count;
seq[seq_no].xfer_len = (burstlength +
(cmd->data_length - offset));
(cmd->se_cmd.data_length - offset));
}
offset += (cmd->data_length - offset);
offset += (cmd->se_cmd.data_length - offset);
continue;
}
if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
@@ -464,9 +468,8 @@ static int iscsit_build_pdu_and_seq_list(
} else
iscsit_ordered_seq_lists(cmd, bl->type);
}
#if 0
iscsit_dump_seq_list(cmd);
#endif
}
if (!datapduinorder) {
if (bl->data_direction & ISCSI_PDU_WRITE) {
@@ -484,50 +487,86 @@ static int iscsit_build_pdu_and_seq_list(
} else
iscsit_ordered_pdu_lists(cmd, bl->type);
}
#if 0
iscsit_dump_pdu_list(cmd);
#endif
}
return 0;
}
/*
* Only called while DataSequenceInOrder=No or DataPDUInOrder=No.
*/
int iscsit_do_build_list(
int iscsit_build_pdu_and_seq_lists(
struct iscsi_cmd *cmd,
struct iscsi_build_list *bl)
u32 immediate_data_length)
{
struct iscsi_build_list bl;
u32 pdu_count = 0, seq_count = 1;
struct iscsi_conn *conn = cmd->conn;
struct iscsi_pdu *pdu = NULL;
struct iscsi_seq *seq = NULL;
iscsit_determine_counts_for_list(cmd, bl, &seq_count, &pdu_count);
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na;
/*
* Do nothing if no OOO shenanigans
*/
if (sess->sess_ops->DataSequenceInOrder &&
sess->sess_ops->DataPDUInOrder)
return 0;
if (cmd->data_direction == DMA_NONE)
return 0;
na = iscsit_tpg_get_node_attrib(sess);
memset(&bl, 0, sizeof(struct iscsi_build_list));
if (cmd->data_direction == DMA_FROM_DEVICE) {
bl.data_direction = ISCSI_PDU_READ;
bl.type = PDULIST_NORMAL;
if (na->random_datain_pdu_offsets)
bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS;
if (na->random_datain_seq_offsets)
bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS;
} else {
bl.data_direction = ISCSI_PDU_WRITE;
bl.immediate_data_length = immediate_data_length;
if (na->random_r2t_offsets)
bl.randomize |= RANDOM_R2T_OFFSETS;
if (!cmd->immediate_data && !cmd->unsolicited_data)
bl.type = PDULIST_NORMAL;
else if (cmd->immediate_data && !cmd->unsolicited_data)
bl.type = PDULIST_IMMEDIATE;
else if (!cmd->immediate_data && cmd->unsolicited_data)
bl.type = PDULIST_UNSOLICITED;
else if (cmd->immediate_data && cmd->unsolicited_data)
bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED;
}
iscsit_determine_counts_for_list(cmd, &bl, &seq_count, &pdu_count);
if (!conn->sess->sess_ops->DataSequenceInOrder) {
seq = kzalloc(seq_count * sizeof(struct iscsi_seq), GFP_ATOMIC);
seq = kcalloc(seq_count, sizeof(struct iscsi_seq), GFP_ATOMIC);
if (!seq) {
pr_err("Unable to allocate struct iscsi_seq list\n");
return -1;
return -ENOMEM;
}
cmd->seq_list = seq;
cmd->seq_count = seq_count;
}
if (!conn->sess->sess_ops->DataPDUInOrder) {
pdu = kzalloc(pdu_count * sizeof(struct iscsi_pdu), GFP_ATOMIC);
pdu = kcalloc(pdu_count, sizeof(struct iscsi_pdu), GFP_ATOMIC);
if (!pdu) {
pr_err("Unable to allocate struct iscsi_pdu list.\n");
kfree(seq);
return -1;
return -ENOMEM;
}
cmd->pdu_list = pdu;
cmd->pdu_count = pdu_count;
}
return iscsit_build_pdu_and_seq_list(cmd, bl);
return iscsit_do_build_pdu_and_seq_lists(cmd, &bl);
}
struct iscsi_pdu *iscsit_get_pdu_holder(
@@ -572,13 +611,12 @@ redo:
pdu = &cmd->pdu_list[cmd->pdu_start];
for (i = 0; pdu[i].seq_no != cmd->seq_no; i++) {
#if 0
pr_debug("pdu[i].seq_no: %d, pdu[i].pdu"
"_send_order: %d, pdu[i].offset: %d,"
" pdu[i].length: %d\n", pdu[i].seq_no,
pdu[i].pdu_send_order, pdu[i].offset,
pdu[i].length);
#endif
if (pdu[i].pdu_send_order == cmd->pdu_send_order) {
cmd->pdu_send_order++;
return &pdu[i];
@@ -601,11 +639,11 @@ redo:
pr_err("struct iscsi_seq is NULL!\n");
return NULL;
}
#if 0
pr_debug("seq->pdu_start: %d, seq->pdu_count: %d,"
" seq->seq_no: %d\n", seq->pdu_start, seq->pdu_count,
seq->seq_no);
#endif
pdu = &cmd->pdu_list[seq->pdu_start];
if (seq->pdu_send_order == seq->pdu_count) {
@@ -645,12 +683,11 @@ struct iscsi_seq *iscsit_get_seq_holder(
}
for (i = 0; i < cmd->seq_count; i++) {
#if 0
pr_debug("seq_list[i].orig_offset: %d, seq_list[i]."
"xfer_len: %d, seq_list[i].seq_no %u\n",
cmd->seq_list[i].orig_offset, cmd->seq_list[i].xfer_len,
cmd->seq_list[i].seq_no);
#endif
if ((cmd->seq_list[i].orig_offset +
cmd->seq_list[i].xfer_len) >=
(offset + length))
@@ -78,7 +78,7 @@ struct iscsi_seq {
u32 xfer_len;
} ____cacheline_aligned;
extern int iscsit_do_build_list(struct iscsi_cmd *, struct iscsi_build_list *);
extern int iscsit_build_pdu_and_seq_lists(struct iscsi_cmd *, u32);
extern struct iscsi_pdu *iscsit_get_pdu_holder(struct iscsi_cmd *, u32, u32);
extern struct iscsi_pdu *iscsit_get_pdu_holder_for_seq(struct iscsi_cmd *, struct iscsi_seq *);
extern struct iscsi_seq *iscsit_get_seq_holder(struct iscsi_cmd *, u32, u32);
+6 -9
View File
@@ -78,10 +78,7 @@ int iscsit_tmr_task_warm_reset(
{
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na = iscsit_tpg_get_node_attrib(sess);
#if 0
struct iscsi_init_task_mgt_cmnd *hdr =
(struct iscsi_init_task_mgt_cmnd *) buf;
#endif
if (!na->tmr_warm_reset) {
pr_err("TMR Opcode TARGET_WARM_RESET authorization"
" failed for Initiator Node: %s\n",
@@ -216,7 +213,7 @@ static int iscsit_task_reassign_complete_nop_out(
iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
cmd->i_state = ISTATE_SEND_NOPIN;
@@ -272,9 +269,9 @@ static int iscsit_task_reassign_complete_write(
offset = cmd->next_burst_len = cmd->write_data_done;
if ((conn->sess->sess_ops->FirstBurstLength - offset) >=
cmd->data_length) {
cmd->se_cmd.data_length) {
no_build_r2ts = 1;
length = (cmd->data_length - offset);
length = (cmd->se_cmd.data_length - offset);
} else
length = (conn->sess->sess_ops->FirstBurstLength - offset);
@@ -292,7 +289,7 @@ static int iscsit_task_reassign_complete_write(
/*
* iscsit_build_r2ts_for_cmd() can handle the rest from here.
*/
return iscsit_build_r2ts_for_cmd(cmd, conn, 2);
return iscsit_build_r2ts_for_cmd(cmd, conn, true);
}
static int iscsit_task_reassign_complete_read(
@@ -385,7 +382,7 @@ static int iscsit_task_reassign_complete_scsi_cmnd(
iscsit_task_reassign_remove_cmd(cmd, cr, conn->sess);
spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
if (se_cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
+9 -183
View File
@@ -163,7 +163,7 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
}
cmd->conn = conn;
INIT_LIST_HEAD(&cmd->i_list);
INIT_LIST_HEAD(&cmd->i_conn_node);
INIT_LIST_HEAD(&cmd->datain_list);
INIT_LIST_HEAD(&cmd->cmd_r2t_list);
init_completion(&cmd->reject_comp);
@@ -176,174 +176,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *conn, gfp_t gfp_mask)
return cmd;
}
/*
* Called from iscsi_handle_scsi_cmd()
*/
struct iscsi_cmd *iscsit_allocate_se_cmd(
struct iscsi_conn *conn,
u32 data_length,
int data_direction,
int iscsi_task_attr)
{
struct iscsi_cmd *cmd;
struct se_cmd *se_cmd;
int sam_task_attr;
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
return NULL;
cmd->data_direction = data_direction;
cmd->data_length = data_length;
/*
* Figure out the SAM Task Attribute for the incoming SCSI CDB
*/
if ((iscsi_task_attr == ISCSI_ATTR_UNTAGGED) ||
(iscsi_task_attr == ISCSI_ATTR_SIMPLE))
sam_task_attr = MSG_SIMPLE_TAG;
else if (iscsi_task_attr == ISCSI_ATTR_ORDERED)
sam_task_attr = MSG_ORDERED_TAG;
else if (iscsi_task_attr == ISCSI_ATTR_HEAD_OF_QUEUE)
sam_task_attr = MSG_HEAD_TAG;
else if (iscsi_task_attr == ISCSI_ATTR_ACA)
sam_task_attr = MSG_ACA_TAG;
else {
pr_debug("Unknown iSCSI Task Attribute: 0x%02x, using"
" MSG_SIMPLE_TAG\n", iscsi_task_attr);
sam_task_attr = MSG_SIMPLE_TAG;
}
se_cmd = &cmd->se_cmd;
/*
* Initialize struct se_cmd descriptor from target_core_mod infrastructure
*/
transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
conn->sess->se_sess, data_length, data_direction,
sam_task_attr, &cmd->sense_buffer[0]);
return cmd;
}
struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(
struct iscsi_conn *conn,
u8 function)
{
struct iscsi_cmd *cmd;
struct se_cmd *se_cmd;
int rc;
u8 tcm_function;
cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
if (!cmd)
return NULL;
cmd->data_direction = DMA_NONE;
cmd->tmr_req = kzalloc(sizeof(struct iscsi_tmr_req), GFP_KERNEL);
if (!cmd->tmr_req) {
pr_err("Unable to allocate memory for"
" Task Management command!\n");
goto out;
}
/*
* TASK_REASSIGN for ERL=2 / connection stays inside of
* LIO-Target $FABRIC_MOD
*/
if (function == ISCSI_TM_FUNC_TASK_REASSIGN)
return cmd;
se_cmd = &cmd->se_cmd;
/*
* Initialize struct se_cmd descriptor from target_core_mod infrastructure
*/
transport_init_se_cmd(se_cmd, &lio_target_fabric_configfs->tf_ops,
conn->sess->se_sess, 0, DMA_NONE,
MSG_SIMPLE_TAG, &cmd->sense_buffer[0]);
switch (function) {
case ISCSI_TM_FUNC_ABORT_TASK:
tcm_function = TMR_ABORT_TASK;
break;
case ISCSI_TM_FUNC_ABORT_TASK_SET:
tcm_function = TMR_ABORT_TASK_SET;
break;
case ISCSI_TM_FUNC_CLEAR_ACA:
tcm_function = TMR_CLEAR_ACA;
break;
case ISCSI_TM_FUNC_CLEAR_TASK_SET:
tcm_function = TMR_CLEAR_TASK_SET;
break;
case ISCSI_TM_FUNC_LOGICAL_UNIT_RESET:
tcm_function = TMR_LUN_RESET;
break;
case ISCSI_TM_FUNC_TARGET_WARM_RESET:
tcm_function = TMR_TARGET_WARM_RESET;
break;
case ISCSI_TM_FUNC_TARGET_COLD_RESET:
tcm_function = TMR_TARGET_COLD_RESET;
break;
default:
pr_err("Unknown iSCSI TMR Function:"
" 0x%02x\n", function);
goto out;
}
rc = core_tmr_alloc_req(se_cmd, cmd->tmr_req, tcm_function, GFP_KERNEL);
if (rc < 0)
goto out;
cmd->tmr_req->se_tmr_req = se_cmd->se_tmr_req;
return cmd;
out:
iscsit_release_cmd(cmd);
return NULL;
}
int iscsit_decide_list_to_build(
struct iscsi_cmd *cmd,
u32 immediate_data_length)
{
struct iscsi_build_list bl;
struct iscsi_conn *conn = cmd->conn;
struct iscsi_session *sess = conn->sess;
struct iscsi_node_attrib *na;
if (sess->sess_ops->DataSequenceInOrder &&
sess->sess_ops->DataPDUInOrder)
return 0;
if (cmd->data_direction == DMA_NONE)
return 0;
na = iscsit_tpg_get_node_attrib(sess);
memset(&bl, 0, sizeof(struct iscsi_build_list));
if (cmd->data_direction == DMA_FROM_DEVICE) {
bl.data_direction = ISCSI_PDU_READ;
bl.type = PDULIST_NORMAL;
if (na->random_datain_pdu_offsets)
bl.randomize |= RANDOM_DATAIN_PDU_OFFSETS;
if (na->random_datain_seq_offsets)
bl.randomize |= RANDOM_DATAIN_SEQ_OFFSETS;
} else {
bl.data_direction = ISCSI_PDU_WRITE;
bl.immediate_data_length = immediate_data_length;
if (na->random_r2t_offsets)
bl.randomize |= RANDOM_R2T_OFFSETS;
if (!cmd->immediate_data && !cmd->unsolicited_data)
bl.type = PDULIST_NORMAL;
else if (cmd->immediate_data && !cmd->unsolicited_data)
bl.type = PDULIST_IMMEDIATE;
else if (!cmd->immediate_data && cmd->unsolicited_data)
bl.type = PDULIST_UNSOLICITED;
else if (cmd->immediate_data && cmd->unsolicited_data)
bl.type = PDULIST_IMMEDIATE_AND_UNSOLICITED;
}
return iscsit_do_build_list(cmd, &bl);
}
struct iscsi_seq *iscsit_get_seq_holder_for_datain(
struct iscsi_cmd *cmd,
u32 seq_send_order)
@@ -502,14 +334,14 @@ int iscsit_check_unsolicited_dataout(struct iscsi_cmd *cmd, unsigned char *buf)
if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))
return 0;
if (((cmd->first_burst_len + payload_length) != cmd->data_length) &&
if (((cmd->first_burst_len + payload_length) != cmd->se_cmd.data_length) &&
((cmd->first_burst_len + payload_length) !=
conn->sess->sess_ops->FirstBurstLength)) {
pr_err("Unsolicited non-immediate data received %u"
" does not equal FirstBurstLength: %u, and does"
" not equal ExpXferLen %u.\n",
(cmd->first_burst_len + payload_length),
conn->sess->sess_ops->FirstBurstLength, cmd->data_length);
conn->sess->sess_ops->FirstBurstLength, cmd->se_cmd.data_length);
transport_send_check_condition_and_sense(se_cmd,
TCM_INCORRECT_AMOUNT_OF_DATA, 0);
return -1;
@@ -524,7 +356,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt(
struct iscsi_cmd *cmd;
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
if (cmd->init_task_tag == init_task_tag) {
spin_unlock_bh(&conn->cmd_lock);
return cmd;
@@ -545,7 +377,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
struct iscsi_cmd *cmd;
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
if (cmd->init_task_tag == init_task_tag) {
spin_unlock_bh(&conn->cmd_lock);
return cmd;
@@ -568,7 +400,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_ttt(
struct iscsi_cmd *cmd = NULL;
spin_lock_bh(&conn->cmd_lock);
list_for_each_entry(cmd, &conn->conn_cmd_list, i_list) {
list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) {
if (cmd->targ_xfer_tag == targ_xfer_tag) {
spin_unlock_bh(&conn->cmd_lock);
return cmd;
@@ -596,7 +428,7 @@ int iscsit_find_cmd_for_recovery(
spin_lock(&sess->cr_i_lock);
list_for_each_entry(cr, &sess->cr_inactive_list, cr_list) {
spin_lock(&cr->conn_recovery_cmd_lock);
list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) {
list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_conn_node) {
if (cmd->init_task_tag == init_task_tag) {
spin_unlock(&cr->conn_recovery_cmd_lock);
spin_unlock(&sess->cr_i_lock);
@@ -616,7 +448,7 @@ int iscsit_find_cmd_for_recovery(
spin_lock(&sess->cr_a_lock);
list_for_each_entry(cr, &sess->cr_active_list, cr_list) {
spin_lock(&cr->conn_recovery_cmd_lock);
list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_list) {
list_for_each_entry(cmd, &cr->conn_recovery_cmd_list, i_conn_node) {
if (cmd->init_task_tag == init_task_tag) {
spin_unlock(&cr->conn_recovery_cmd_lock);
spin_unlock(&sess->cr_a_lock);
@@ -813,7 +645,6 @@ void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
void iscsit_release_cmd(struct iscsi_cmd *cmd)
{
struct iscsi_conn *conn = cmd->conn;
int i;
iscsit_free_r2ts_from_list(cmd);
iscsit_free_all_datain_reqs(cmd);
@@ -824,11 +655,6 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd)
kfree(cmd->tmr_req);
kfree(cmd->iov_data);
for (i = 0; i < cmd->t_mem_sg_nents; i++)
__free_page(sg_page(&cmd->t_mem_sg[i]));
kfree(cmd->t_mem_sg);
if (conn) {
iscsit_remove_cmd_from_immediate_queue(cmd, conn);
iscsit_remove_cmd_from_response_queue(cmd, conn);
@@ -1038,7 +864,7 @@ static int iscsit_add_nopin(struct iscsi_conn *conn, int want_response)
spin_unlock_bh(&conn->sess->ttt_lock);
spin_lock_bh(&conn->cmd_lock);
list_add_tail(&cmd->i_list, &conn->conn_cmd_list);
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
spin_unlock_bh(&conn->cmd_lock);
if (want_response)
-3
View File
@@ -9,9 +9,6 @@ extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *);
extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *);
extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *);
extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
extern struct iscsi_cmd *iscsit_allocate_se_cmd(struct iscsi_conn *, u32, int, int);
extern struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(struct iscsi_conn *, u8);
extern int iscsit_decide_list_to_build(struct iscsi_cmd *, u32);
extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
+2 -2
View File
@@ -213,7 +213,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
* associated read buffers, go ahead and do that here for type
* SCF_SCSI_CONTROL_SG_IO_CDB. Also note that this is currently
* guaranteed to be a single SGL for SCF_SCSI_CONTROL_SG_IO_CDB
* by target core in transport_generic_allocate_tasks() ->
* by target core in target_setup_cmd_from_cdb() ->
* transport_generic_cmd_sequencer().
*/
if (se_cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB &&
@@ -227,7 +227,7 @@ static void tcm_loop_submission_work(struct work_struct *work)
}
}
ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd);
if (ret == -ENOMEM) {
transport_send_check_condition_and_sense(se_cmd,
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
+77 -23
View File
@@ -59,26 +59,31 @@ struct t10_alua_lu_gp *default_lu_gp;
*
* See spc4r17 section 6.27
*/
int target_emulate_report_target_port_groups(struct se_task *task)
int target_emulate_report_target_port_groups(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev;
struct se_port *port;
struct t10_alua_tg_pt_gp *tg_pt_gp;
struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
unsigned char *buf;
u32 rd_len = 0, off = 4; /* Skip over RESERVED area to first
Target port group descriptor */
u32 rd_len = 0, off;
int ext_hdr = (cmd->t_task_cdb[1] & 0x20);
/*
* Need at least 4 bytes of response data or else we can't
* even fit the return data length.
* Skip over RESERVED area to first Target port group descriptor
* depending on the PARAMETER DATA FORMAT type..
*/
if (cmd->data_length < 4) {
pr_warn("REPORT TARGET PORT GROUPS allocation length %u"
" too small\n", cmd->data_length);
if (ext_hdr != 0)
off = 8;
else
off = 4;
if (cmd->data_length < off) {
pr_warn("REPORT TARGET PORT GROUPS allocation length %u too"
" small for %s header\n", cmd->data_length,
(ext_hdr) ? "extended" : "normal");
cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
return -EINVAL;
}
buf = transport_kmap_data_sg(cmd);
spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
@@ -159,15 +164,34 @@ int target_emulate_report_target_port_groups(struct se_task *task)
/*
* Set the RETURN DATA LENGTH set in the header of the DataIN Payload
*/
buf[0] = ((rd_len >> 24) & 0xff);
buf[1] = ((rd_len >> 16) & 0xff);
buf[2] = ((rd_len >> 8) & 0xff);
buf[3] = (rd_len & 0xff);
put_unaligned_be32(rd_len, &buf[0]);
/*
* Fill in the Extended header parameter data format if requested
*/
if (ext_hdr != 0) {
buf[4] = 0x10;
/*
* Set the implict transition time (in seconds) for the application
* client to use as a base for it's transition timeout value.
*
* Use the current tg_pt_gp_mem -> tg_pt_gp membership from the LUN
* this CDB was received upon to determine this value individually
* for ALUA target port group.
*/
port = cmd->se_lun->lun_sep;
tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
if (tg_pt_gp_mem) {
spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
if (tg_pt_gp)
buf[5] = tg_pt_gp->tg_pt_gp_implict_trans_secs;
spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
}
}
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
@@ -176,9 +200,8 @@ int target_emulate_report_target_port_groups(struct se_task *task)
*
* See spc4r17 section 6.35
*/
int target_emulate_set_target_port_groups(struct se_task *task)
int target_emulate_set_target_port_groups(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
struct se_subsystem_dev *su_dev = dev->se_sub_dev;
struct se_port *port, *l_port = cmd->se_lun->lun_sep;
@@ -351,8 +374,7 @@ int target_emulate_set_target_port_groups(struct se_task *task)
out:
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
@@ -391,7 +413,7 @@ static inline int core_alua_state_standby(
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
case MAINTENANCE_IN:
switch (cdb[1]) {
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
@@ -433,7 +455,7 @@ static inline int core_alua_state_unavailable(
case INQUIRY:
case REPORT_LUNS:
case MAINTENANCE_IN:
switch (cdb[1]) {
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
@@ -473,7 +495,7 @@ static inline int core_alua_state_transition(
case INQUIRY:
case REPORT_LUNS:
case MAINTENANCE_IN:
switch (cdb[1]) {
switch (cdb[1] & 0x1f) {
case MI_REPORT_TARGET_PGS:
return 0;
default:
@@ -1359,6 +1381,7 @@ struct t10_alua_tg_pt_gp *core_alua_allocate_tg_pt_gp(
*/
tg_pt_gp->tg_pt_gp_nonop_delay_msecs = ALUA_DEFAULT_NONOP_DELAY_MSECS;
tg_pt_gp->tg_pt_gp_trans_delay_msecs = ALUA_DEFAULT_TRANS_DELAY_MSECS;
tg_pt_gp->tg_pt_gp_implict_trans_secs = ALUA_DEFAULT_IMPLICT_TRANS_SECS;
if (def_group) {
spin_lock(&su_dev->t10_alua.tg_pt_gps_lock);
@@ -1855,6 +1878,37 @@ ssize_t core_alua_store_trans_delay_msecs(
return count;
}
ssize_t core_alua_show_implict_trans_secs(
struct t10_alua_tg_pt_gp *tg_pt_gp,
char *page)
{
return sprintf(page, "%d\n", tg_pt_gp->tg_pt_gp_implict_trans_secs);
}
ssize_t core_alua_store_implict_trans_secs(
struct t10_alua_tg_pt_gp *tg_pt_gp,
const char *page,
size_t count)
{
unsigned long tmp;
int ret;
ret = strict_strtoul(page, 0, &tmp);
if (ret < 0) {
pr_err("Unable to extract implict_trans_secs\n");
return -EINVAL;
}
if (tmp > ALUA_MAX_IMPLICT_TRANS_SECS) {
pr_err("Passed implict_trans_secs: %lu, exceeds"
" ALUA_MAX_IMPLICT_TRANS_SECS: %d\n", tmp,
ALUA_MAX_IMPLICT_TRANS_SECS);
return -EINVAL;
}
tg_pt_gp->tg_pt_gp_implict_trans_secs = (int)tmp;
return count;
}
ssize_t core_alua_show_preferred_bit(
struct t10_alua_tg_pt_gp *tg_pt_gp,
char *page)
+12 -2
View File
@@ -51,6 +51,12 @@
*/
#define ALUA_DEFAULT_TRANS_DELAY_MSECS 0
#define ALUA_MAX_TRANS_DELAY_MSECS 30000 /* 30 seconds */
/*
* Used for the recommended application client implict transition timeout
* in seconds, returned by the REPORT_TARGET_PORT_GROUPS w/ extended header.
*/
#define ALUA_DEFAULT_IMPLICT_TRANS_SECS 0
#define ALUA_MAX_IMPLICT_TRANS_SECS 255
/*
* Used by core_alua_update_tpg_primary_metadata() and
* core_alua_update_tpg_secondary_metadata()
@@ -66,8 +72,8 @@ extern struct kmem_cache *t10_alua_lu_gp_mem_cache;
extern struct kmem_cache *t10_alua_tg_pt_gp_cache;
extern struct kmem_cache *t10_alua_tg_pt_gp_mem_cache;
extern int target_emulate_report_target_port_groups(struct se_task *);
extern int target_emulate_set_target_port_groups(struct se_task *);
extern int target_emulate_report_target_port_groups(struct se_cmd *);
extern int target_emulate_set_target_port_groups(struct se_cmd *);
extern int core_alua_check_nonop_delay(struct se_cmd *);
extern int core_alua_do_port_transition(struct t10_alua_tg_pt_gp *,
struct se_device *, struct se_port *,
@@ -107,6 +113,10 @@ extern ssize_t core_alua_show_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_trans_delay_msecs(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_implict_trans_secs(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_implict_trans_secs(struct t10_alua_tg_pt_gp *,
const char *, size_t);
extern ssize_t core_alua_show_preferred_bit(struct t10_alua_tg_pt_gp *,
char *);
extern ssize_t core_alua_store_preferred_bit(struct t10_alua_tg_pt_gp *,
+26 -92
View File
@@ -432,6 +432,7 @@ static int
target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
{
struct se_device *dev = cmd->se_dev;
u32 max_sectors;
int have_tp = 0;
/*
@@ -456,7 +457,9 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
/*
* Set MAXIMUM TRANSFER LENGTH
*/
put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors, &buf[8]);
max_sectors = min(dev->se_sub_dev->se_dev_attrib.fabric_max_sectors,
dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
put_unaligned_be32(max_sectors, &buf[8]);
/*
* Set OPTIMAL TRANSFER LENGTH
@@ -598,9 +601,8 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
return 0;
}
int target_emulate_inquiry(struct se_task *task)
int target_emulate_inquiry(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg;
unsigned char *buf, *map_buf;
@@ -664,16 +666,13 @@ out:
}
transport_kunmap_data_sg(cmd);
if (!ret) {
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
}
if (!ret)
target_complete_cmd(cmd, GOOD);
return ret;
}
int target_emulate_readcapacity(struct se_task *task)
int target_emulate_readcapacity(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
unsigned char *buf;
unsigned long long blocks_long = dev->transport->get_blocks(dev);
@@ -697,14 +696,12 @@ int target_emulate_readcapacity(struct se_task *task)
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
int target_emulate_readcapacity_16(struct se_task *task)
int target_emulate_readcapacity_16(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
unsigned char *buf;
unsigned long long blocks = dev->transport->get_blocks(dev);
@@ -732,8 +729,7 @@ int target_emulate_readcapacity_16(struct se_task *task)
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
@@ -872,9 +868,8 @@ target_modesense_dpofua(unsigned char *buf, int type)
}
}
int target_emulate_modesense(struct se_task *task)
int target_emulate_modesense(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
char *cdb = cmd->t_task_cdb;
unsigned char *rbuf;
@@ -947,14 +942,12 @@ int target_emulate_modesense(struct se_task *task)
memcpy(rbuf, buf, offset);
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
int target_emulate_request_sense(struct se_task *task)
int target_emulate_request_sense(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
unsigned char *cdb = cmd->t_task_cdb;
unsigned char *buf;
u8 ua_asc = 0, ua_ascq = 0;
@@ -1008,8 +1001,7 @@ int target_emulate_request_sense(struct se_task *task)
end:
transport_kunmap_data_sg(cmd);
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
@@ -1017,9 +1009,8 @@ end:
* Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
* Note this is not used for TCM/pSCSI passthrough
*/
int target_emulate_unmap(struct se_task *task)
int target_emulate_unmap(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
unsigned char *buf, *ptr = NULL;
unsigned char *cdb = &cmd->t_task_cdb[0];
@@ -1066,10 +1057,8 @@ int target_emulate_unmap(struct se_task *task)
err:
transport_kunmap_data_sg(cmd);
if (!ret) {
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
}
if (!ret)
target_complete_cmd(cmd, GOOD);
return ret;
}
@@ -1077,9 +1066,8 @@ err:
* Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
* Note this is not used for TCM/pSCSI passthrough
*/
int target_emulate_write_same(struct se_task *task)
int target_emulate_write_same(struct se_cmd *cmd)
{
struct se_cmd *cmd = task->task_se_cmd;
struct se_device *dev = cmd->se_dev;
sector_t range;
sector_t lba = cmd->t_task_lba;
@@ -1118,79 +1106,25 @@ int target_emulate_write_same(struct se_task *task)
return ret;
}
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
int target_emulate_synchronize_cache(struct se_task *task)
int target_emulate_synchronize_cache(struct se_cmd *cmd)
{
struct se_device *dev = task->task_se_cmd->se_dev;
struct se_cmd *cmd = task->task_se_cmd;
if (!dev->transport->do_sync_cache) {
if (!cmd->se_dev->transport->do_sync_cache) {
pr_err("SYNCHRONIZE_CACHE emulation not supported"
" for: %s\n", dev->transport->name);
" for: %s\n", cmd->se_dev->transport->name);
cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE;
return -ENOSYS;
}
dev->transport->do_sync_cache(task);
cmd->se_dev->transport->do_sync_cache(cmd);
return 0;
}
int target_emulate_noop(struct se_task *task)
int target_emulate_noop(struct se_cmd *cmd)
{
task->task_scsi_status = GOOD;
transport_complete_task(task, 1);
target_complete_cmd(cmd, GOOD);
return 0;
}
/*
* Write a CDB into @cdb that is based on the one the intiator sent us,
* but updated to only cover the sectors that the current task handles.
*/
void target_get_task_cdb(struct se_task *task, unsigned char *cdb)
{
struct se_cmd *cmd = task->task_se_cmd;
unsigned int cdb_len = scsi_command_size(cmd->t_task_cdb);
memcpy(cdb, cmd->t_task_cdb, cdb_len);
if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
unsigned long long lba = task->task_lba;
u32 sectors = task->task_sectors;
switch (cdb_len) {
case 6:
/* 21-bit LBA and 8-bit sectors */
cdb[1] = (lba >> 16) & 0x1f;
cdb[2] = (lba >> 8) & 0xff;
cdb[3] = lba & 0xff;
cdb[4] = sectors & 0xff;
break;
case 10:
/* 32-bit LBA and 16-bit sectors */
put_unaligned_be32(lba, &cdb[2]);
put_unaligned_be16(sectors, &cdb[7]);
break;
case 12:
/* 32-bit LBA and 32-bit sectors */
put_unaligned_be32(lba, &cdb[2]);
put_unaligned_be32(sectors, &cdb[6]);
break;
case 16:
/* 64-bit LBA and 32-bit sectors */
put_unaligned_be64(lba, &cdb[2]);
put_unaligned_be32(sectors, &cdb[10]);
break;
case 32:
/* 64-bit LBA and 32-bit sectors, extended CDB */
put_unaligned_be64(lba, &cdb[12]);
put_unaligned_be32(sectors, &cdb[28]);
break;
default:
BUG();
}
}
}
EXPORT_SYMBOL(target_get_task_cdb);
+21 -4
View File
@@ -683,9 +683,6 @@ SE_DEV_ATTR(block_size, S_IRUGO | S_IWUSR);
DEF_DEV_ATTRIB_RO(hw_max_sectors);
SE_DEV_ATTR_RO(hw_max_sectors);
DEF_DEV_ATTRIB(max_sectors);
SE_DEV_ATTR(max_sectors, S_IRUGO | S_IWUSR);
DEF_DEV_ATTRIB(fabric_max_sectors);
SE_DEV_ATTR(fabric_max_sectors, S_IRUGO | S_IWUSR);
@@ -727,7 +724,6 @@ static struct configfs_attribute *target_core_dev_attrib_attrs[] = {
&target_core_dev_attrib_hw_block_size.attr,
&target_core_dev_attrib_block_size.attr,
&target_core_dev_attrib_hw_max_sectors.attr,
&target_core_dev_attrib_max_sectors.attr,
&target_core_dev_attrib_fabric_max_sectors.attr,
&target_core_dev_attrib_optimal_sectors.attr,
&target_core_dev_attrib_hw_queue_depth.attr,
@@ -2450,6 +2446,26 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_trans_delay_msecs(
SE_DEV_ALUA_TG_PT_ATTR(trans_delay_msecs, S_IRUGO | S_IWUSR);
/*
* implict_trans_secs
*/
static ssize_t target_core_alua_tg_pt_gp_show_attr_implict_trans_secs(
struct t10_alua_tg_pt_gp *tg_pt_gp,
char *page)
{
return core_alua_show_implict_trans_secs(tg_pt_gp, page);
}
static ssize_t target_core_alua_tg_pt_gp_store_attr_implict_trans_secs(
struct t10_alua_tg_pt_gp *tg_pt_gp,
const char *page,
size_t count)
{
return core_alua_store_implict_trans_secs(tg_pt_gp, page, count);
}
SE_DEV_ALUA_TG_PT_ATTR(implict_trans_secs, S_IRUGO | S_IWUSR);
/*
* preferred
*/
@@ -2574,6 +2590,7 @@ static struct configfs_attribute *target_core_alua_tg_pt_gp_attrs[] = {
&target_core_alua_tg_pt_gp_alua_write_metadata.attr,
&target_core_alua_tg_pt_gp_nonop_delay_msecs.attr,
&target_core_alua_tg_pt_gp_trans_delay_msecs.attr,
&target_core_alua_tg_pt_gp_implict_trans_secs.attr,
&target_core_alua_tg_pt_gp_preferred.attr,
&target_core_alua_tg_pt_gp_tg_pt_gp_id.attr,
&target_core_alua_tg_pt_gp_members.attr,
+8 -76
View File
@@ -643,9 +643,8 @@ void core_dev_unexport(
lun->lun_se_dev = NULL;
}
int target_report_luns(struct se_task *se_task)
int target_report_luns(struct se_cmd *se_cmd)
{
struct se_cmd *se_cmd = se_task->task_se_cmd;
struct se_dev_entry *deve;
struct se_session *se_sess = se_cmd->se_sess;
unsigned char *buf;
@@ -696,8 +695,7 @@ done:
buf[3] = (lun_count & 0xff);
transport_kunmap_data_sg(se_cmd);
se_task->task_scsi_status = GOOD;
transport_complete_task(se_task, 1);
target_complete_cmd(se_cmd, GOOD);
return 0;
}
@@ -878,15 +876,12 @@ void se_dev_set_default_attribs(
dev->se_sub_dev->se_dev_attrib.hw_block_size = limits->logical_block_size;
dev->se_sub_dev->se_dev_attrib.block_size = limits->logical_block_size;
/*
* max_sectors is based on subsystem plugin dependent requirements.
* Align max_hw_sectors down to PAGE_SIZE I/O transfers
*/
dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors;
/*
* Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()
*/
limits->max_sectors = se_dev_align_max_sectors(limits->max_sectors,
limits->max_hw_sectors = se_dev_align_max_sectors(limits->max_hw_sectors,
limits->logical_block_size);
dev->se_sub_dev->se_dev_attrib.max_sectors = limits->max_sectors;
dev->se_sub_dev->se_dev_attrib.hw_max_sectors = limits->max_hw_sectors;
/*
* Set fabric_max_sectors, which is reported in block limits
* VPD page (B0h).
@@ -1170,64 +1165,6 @@ int se_dev_set_queue_depth(struct se_device *dev, u32 queue_depth)
return 0;
}
int se_dev_set_max_sectors(struct se_device *dev, u32 max_sectors)
{
int force = 0; /* Force setting for VDEVS */
if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
pr_err("dev[%p]: Unable to change SE Device"
" max_sectors while dev_export_obj: %d count exists\n",
dev, atomic_read(&dev->dev_export_obj.obj_access_count));
return -EINVAL;
}
if (!max_sectors) {
pr_err("dev[%p]: Illegal ZERO value for"
" max_sectors\n", dev);
return -EINVAL;
}
if (max_sectors < DA_STATUS_MAX_SECTORS_MIN) {
pr_err("dev[%p]: Passed max_sectors: %u less than"
" DA_STATUS_MAX_SECTORS_MIN: %u\n", dev, max_sectors,
DA_STATUS_MAX_SECTORS_MIN);
return -EINVAL;
}
if (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
if (max_sectors > dev->se_sub_dev->se_dev_attrib.hw_max_sectors) {
pr_err("dev[%p]: Passed max_sectors: %u"
" greater than TCM/SE_Device max_sectors:"
" %u\n", dev, max_sectors,
dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
return -EINVAL;
}
} else {
if (!force && (max_sectors >
dev->se_sub_dev->se_dev_attrib.hw_max_sectors)) {
pr_err("dev[%p]: Passed max_sectors: %u"
" greater than TCM/SE_Device max_sectors"
": %u, use force=1 to override.\n", dev,
max_sectors, dev->se_sub_dev->se_dev_attrib.hw_max_sectors);
return -EINVAL;
}
if (max_sectors > DA_STATUS_MAX_SECTORS_MAX) {
pr_err("dev[%p]: Passed max_sectors: %u"
" greater than DA_STATUS_MAX_SECTORS_MAX:"
" %u\n", dev, max_sectors,
DA_STATUS_MAX_SECTORS_MAX);
return -EINVAL;
}
}
/*
* Align max_sectors down to PAGE_SIZE to follow transport_allocate_data_tasks()
*/
max_sectors = se_dev_align_max_sectors(max_sectors,
dev->se_sub_dev->se_dev_attrib.block_size);
dev->se_sub_dev->se_dev_attrib.max_sectors = max_sectors;
pr_debug("dev[%p]: SE Device max_sectors changed to %u\n",
dev, max_sectors);
return 0;
}
int se_dev_set_fabric_max_sectors(struct se_device *dev, u32 fabric_max_sectors)
{
if (atomic_read(&dev->dev_export_obj.obj_access_count)) {
@@ -1341,7 +1278,6 @@ struct se_lun *core_dev_add_lun(
u32 lun)
{
struct se_lun *lun_p;
u32 lun_access = 0;
int rc;
if (atomic_read(&dev->dev_access_obj.obj_access_count) != 0) {
@@ -1354,12 +1290,8 @@ struct se_lun *core_dev_add_lun(
if (IS_ERR(lun_p))
return lun_p;
if (dev->dev_flags & DF_READ_ONLY)
lun_access = TRANSPORT_LUNFLAGS_READ_ONLY;
else
lun_access = TRANSPORT_LUNFLAGS_READ_WRITE;
rc = core_tpg_post_addlun(tpg, lun_p, lun_access, dev);
rc = core_tpg_post_addlun(tpg, lun_p,
TRANSPORT_LUNFLAGS_READ_WRITE, dev);
if (rc < 0)
return ERR_PTR(rc);

Some files were not shown because too many files have changed in this diff Show More