Commit 05c78081 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull SCSI target updates from Nicholas Bellinger:
 "Here are the outstanding target-pending updates for v4.3-rc1.

  Mostly bug-fixes and minor changes this round.  The fallout from the
  big v4.2-rc1 RCU conversion have (thus far) been minimal.

  The highlights this round include:

   - Move sense handling routines into scsi_common code (Sagi)

   - Return ABORTED_COMMAND sense key for PI errors (Sagi)

   - Add tpg_enabled_sendtargets attribute for disabled iscsi-target
     discovery (David)

   - Shrink target struct se_cmd by rearranging fields (Roland)

   - Drop iSCSI use of mutex around max_cmd_sn increment (Roland)

   - Replace iSCSI __kernel_sockaddr_storage with sockaddr_storage (Andy +
     Chris)

   - Honor fabric max_data_sg_nents I/O transfer limit (Arun + Himanshu +
     nab)

   - Fix EXTENDED_COPY >= v4.1 regression OOPsen (Alex + nab)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (37 commits)
  target: use stringify.h instead of own definition
  target/user: Fix UFLAG_UNKNOWN_OP handling
  target: Remove no-op conditional
  target/user: Remove unused variable
  target: Fix max_cmd_sn increment w/o cmdsn mutex regressions
  target: Attach EXTENDED_COPY local I/O descriptors to xcopy_pt_sess
  target/qla2xxx: Honor max_data_sg_nents I/O transfer limit
  target/iscsi: Replace __kernel_sockaddr_storage with sockaddr_storage
  target/iscsi: Replace conn->login_ip with login_sockaddr
  target/iscsi: Keep local_ip as the actual sockaddr
  target/iscsi: Fix np_ip bracket issue by removing np_ip
  target: Drop iSCSI use of mutex around max_cmd_sn increment
  qla2xxx: Update tcm_qla2xxx module description to 24xx+
  iscsi-target: Add tpg_enabled_sendtargets for disabled discovery
  drivers: target: Drop unlikely before IS_ERR(_OR_NULL)
  target: check DPO/FUA usage for COMPARE AND WRITE
  target: Shrink struct se_cmd by rearranging fields
  target: Remove cmd->se_ordered_id (unused except debug log lines)
  target: add support for START_STOP_UNIT SCSI opcode
  target: improve unsupported opcode message
  ...
parents 8e78b7dc ac64a2ce
...@@ -3095,7 +3095,7 @@ isert_setup_id(struct isert_np *isert_np) ...@@ -3095,7 +3095,7 @@ isert_setup_id(struct isert_np *isert_np)
static int static int
isert_setup_np(struct iscsi_np *np, isert_setup_np(struct iscsi_np *np,
struct __kernel_sockaddr_storage *ksockaddr) struct sockaddr_storage *ksockaddr)
{ {
struct isert_np *isert_np; struct isert_np *isert_np;
struct rdma_cm_id *isert_lid; struct rdma_cm_id *isert_lid;
...@@ -3117,7 +3117,7 @@ isert_setup_np(struct iscsi_np *np, ...@@ -3117,7 +3117,7 @@ isert_setup_np(struct iscsi_np *np,
* in iscsi_target_configfs.c code.. * in iscsi_target_configfs.c code..
*/ */
memcpy(&np->np_sockaddr, ksockaddr, memcpy(&np->np_sockaddr, ksockaddr,
sizeof(struct __kernel_sockaddr_storage)); sizeof(struct sockaddr_storage));
isert_lid = isert_setup_id(isert_np); isert_lid = isert_setup_id(isert_np);
if (IS_ERR(isert_lid)) { if (IS_ERR(isert_lid)) {
...@@ -3199,32 +3199,11 @@ isert_set_conn_info(struct iscsi_np *np, struct iscsi_conn *conn, ...@@ -3199,32 +3199,11 @@ isert_set_conn_info(struct iscsi_np *np, struct iscsi_conn *conn,
{ {
struct rdma_cm_id *cm_id = isert_conn->cm_id; struct rdma_cm_id *cm_id = isert_conn->cm_id;
struct rdma_route *cm_route = &cm_id->route; struct rdma_route *cm_route = &cm_id->route;
struct sockaddr_in *sock_in;
struct sockaddr_in6 *sock_in6;
conn->login_family = np->np_sockaddr.ss_family; conn->login_family = np->np_sockaddr.ss_family;
if (np->np_sockaddr.ss_family == AF_INET6) { conn->login_sockaddr = cm_route->addr.dst_addr;
sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.dst_addr; conn->local_sockaddr = cm_route->addr.src_addr;
snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
&sock_in6->sin6_addr.in6_u);
conn->login_port = ntohs(sock_in6->sin6_port);
sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.src_addr;
snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
&sock_in6->sin6_addr.in6_u);
conn->local_port = ntohs(sock_in6->sin6_port);
} else {
sock_in = (struct sockaddr_in *)&cm_route->addr.dst_addr;
sprintf(conn->login_ip, "%pI4",
&sock_in->sin_addr.s_addr);
conn->login_port = ntohs(sock_in->sin_port);
sock_in = (struct sockaddr_in *)&cm_route->addr.src_addr;
sprintf(conn->local_ip, "%pI4",
&sock_in->sin_addr.s_addr);
conn->local_port = ntohs(sock_in->sin_port);
}
} }
static int static int
......
...@@ -853,12 +853,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ...@@ -853,12 +853,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
SAM_STAT_CHECK_CONDITION; SAM_STAT_CHECK_CONDITION;
scsi_build_sense_buffer(1, sc->sense_buffer, scsi_build_sense_buffer(1, sc->sense_buffer,
ILLEGAL_REQUEST, 0x10, ascq); ILLEGAL_REQUEST, 0x10, ascq);
sc->sense_buffer[7] = 0xc; /* Additional sense length */ scsi_set_sense_information(sc->sense_buffer,
sc->sense_buffer[8] = 0; /* Information desc type */ SCSI_SENSE_BUFFERSIZE,
sc->sense_buffer[9] = 0xa; /* Additional desc length */ sector);
sc->sense_buffer[10] = 0x80; /* Validity bit */
put_unaligned_be64(sector, &sc->sense_buffer[12]);
goto out; goto out;
} }
} }
......
...@@ -32,10 +32,10 @@ config SCSI_QLA_FC ...@@ -32,10 +32,10 @@ config SCSI_QLA_FC
They are also included in the linux-firmware tree as well. They are also included in the linux-firmware tree as well.
config TCM_QLA2XXX config TCM_QLA2XXX
tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs" tristate "TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs"
depends on SCSI_QLA_FC && TARGET_CORE depends on SCSI_QLA_FC && TARGET_CORE
depends on LIBFC depends on LIBFC
select BTREE select BTREE
default n default n
---help--- ---help---
Say Y here to enable the TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs
...@@ -1359,9 +1359,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) ...@@ -1359,9 +1359,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
struct qla_hw_data *ha = tgt->ha; struct qla_hw_data *ha = tgt->ha;
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
struct se_session *se_sess; struct se_session *se_sess;
struct se_node_acl *se_nacl;
struct tcm_qla2xxx_lport *lport; struct tcm_qla2xxx_lport *lport;
struct tcm_qla2xxx_nacl *nacl;
BUG_ON(in_interrupt()); BUG_ON(in_interrupt());
...@@ -1371,8 +1369,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) ...@@ -1371,8 +1369,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
dump_stack(); dump_stack();
return; return;
} }
se_nacl = se_sess->se_node_acl;
nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
lport = vha->vha_tgt.target_lport_ptr; lport = vha->vha_tgt.target_lport_ptr;
if (!lport) { if (!lport) {
...@@ -1680,7 +1676,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, ...@@ -1680,7 +1676,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
(struct tcm_qla2xxx_lport *)target_lport_ptr; (struct tcm_qla2xxx_lport *)target_lport_ptr;
struct tcm_qla2xxx_lport *base_lport = struct tcm_qla2xxx_lport *base_lport =
(struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr; (struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr;
struct tcm_qla2xxx_tpg *base_tpg;
struct fc_vport_identifiers vport_id; struct fc_vport_identifiers vport_id;
if (!qla_tgt_mode_enabled(base_vha)) { if (!qla_tgt_mode_enabled(base_vha)) {
...@@ -1693,7 +1688,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, ...@@ -1693,7 +1688,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
pr_err("qla2xxx base_lport or tpg_1 not available\n"); pr_err("qla2xxx base_lport or tpg_1 not available\n");
return -EPERM; return -EPERM;
} }
base_tpg = base_lport->tpg_1;
memset(&vport_id, 0, sizeof(vport_id)); memset(&vport_id, 0, sizeof(vport_id));
vport_id.port_name = npiv_wwpn; vport_id.port_name = npiv_wwpn;
...@@ -1810,6 +1804,11 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = { ...@@ -1810,6 +1804,11 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "qla2xxx", .name = "qla2xxx",
.node_acl_size = sizeof(struct tcm_qla2xxx_nacl), .node_acl_size = sizeof(struct tcm_qla2xxx_nacl),
/*
* XXX: Limit assumes single page per scatter-gather-list entry.
* Current maximum is ~4.9 MB per se_cmd->t_data_sg with PAGE_SIZE=4096
*/
.max_data_sg_nents = 1200,
.get_fabric_name = tcm_qla2xxx_get_fabric_name, .get_fabric_name = tcm_qla2xxx_get_fabric_name,
.tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn,
.tpg_get_tag = tcm_qla2xxx_get_tag, .tpg_get_tag = tcm_qla2xxx_get_tag,
...@@ -1958,7 +1957,7 @@ static void __exit tcm_qla2xxx_exit(void) ...@@ -1958,7 +1957,7 @@ static void __exit tcm_qla2xxx_exit(void)
tcm_qla2xxx_deregister_configfs(); tcm_qla2xxx_deregister_configfs();
} }
MODULE_DESCRIPTION("TCM QLA2XXX series NPIV enabled fabric driver"); MODULE_DESCRIPTION("TCM QLA24XX+ series NPIV enabled fabric driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(tcm_qla2xxx_init); module_init(tcm_qla2xxx_init);
module_exit(tcm_qla2xxx_exit); module_exit(tcm_qla2xxx_exit);
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/errno.h>
#include <asm/unaligned.h>
#include <scsi/scsi_common.h> #include <scsi/scsi_common.h>
/* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
...@@ -176,3 +178,110 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, ...@@ -176,3 +178,110 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
return true; return true;
} }
EXPORT_SYMBOL(scsi_normalize_sense); EXPORT_SYMBOL(scsi_normalize_sense);
/**
* scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format.
* @sense_buffer: byte array of descriptor format sense data
* @sb_len: number of valid bytes in sense_buffer
* @desc_type: value of descriptor type to find
* (e.g. 0 -> information)
*
* Notes:
* only valid when sense data is in descriptor format
*
* Return value:
* pointer to start of (first) descriptor if found else NULL
*/
const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
int desc_type)
{
int add_sen_len, add_len, desc_len, k;
const u8 * descp;
if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
return NULL;
if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73))
return NULL;
add_sen_len = (add_sen_len < (sb_len - 8)) ?
add_sen_len : (sb_len - 8);
descp = &sense_buffer[8];
for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
descp += desc_len;
add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
desc_len = add_len + 2;
if (descp[0] == desc_type)
return descp;
if (add_len < 0) // short descriptor ??
break;
}
return NULL;
}
EXPORT_SYMBOL(scsi_sense_desc_find);
/**
* scsi_build_sense_buffer - build sense data in a buffer
* @desc: Sense format (non zero == descriptor format,
* 0 == fixed format)
* @buf: Where to build sense data
* @key: Sense key
* @asc: Additional sense code
* @ascq: Additional sense code qualifier
*
**/
void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
{
if (desc) {
buf[0] = 0x72; /* descriptor, current */
buf[1] = key;
buf[2] = asc;
buf[3] = ascq;
buf[7] = 0;
} else {
buf[0] = 0x70; /* fixed, current */
buf[2] = key;
buf[7] = 0xa;
buf[12] = asc;
buf[13] = ascq;
}
}
EXPORT_SYMBOL(scsi_build_sense_buffer);
/**
* scsi_set_sense_information - set the information field in a
* formatted sense data buffer
* @buf: Where to build sense data
* @buf_len: buffer length
* @info: 64-bit information value to be set
*
* Return value:
* 0 on success or EINVAL for invalid sense buffer length
**/
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info)
{
if ((buf[0] & 0x7f) == 0x72) {
u8 *ucp, len;
len = buf[7];
ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
if (!ucp) {
buf[7] = len + 0xc;
ucp = buf + 8 + len;
}
if (buf_len < len + 0xc)
/* Not enough room for info */
return -EINVAL;
ucp[0] = 0;
ucp[1] = 0xa;
ucp[2] = 0x80; /* Valid bit */
ucp[3] = 0;
put_unaligned_be64(info, &ucp[4]);
} else if ((buf[0] & 0x7f) == 0x70) {
buf[0] |= 0x80;
put_unaligned_be64(info, &buf[3]);
}
return 0;
}
EXPORT_SYMBOL(scsi_set_sense_information);
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h> #include <scsi/scsi_driver.h>
#include <scsi/scsi_eh.h> #include <scsi/scsi_eh.h>
#include <scsi/scsi_common.h>
#include <scsi/scsi_transport.h> #include <scsi/scsi_transport.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
...@@ -2424,45 +2425,6 @@ bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, ...@@ -2424,45 +2425,6 @@ bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd,
} }
EXPORT_SYMBOL(scsi_command_normalize_sense); EXPORT_SYMBOL(scsi_command_normalize_sense);
/**
* scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format.
* @sense_buffer: byte array of descriptor format sense data
* @sb_len: number of valid bytes in sense_buffer
* @desc_type: value of descriptor type to find
* (e.g. 0 -> information)
*
* Notes:
* only valid when sense data is in descriptor format
*
* Return value:
* pointer to start of (first) descriptor if found else NULL
*/
const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
int desc_type)
{
int add_sen_len, add_len, desc_len, k;
const u8 * descp;
if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
return NULL;
if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73))
return NULL;
add_sen_len = (add_sen_len < (sb_len - 8)) ?
add_sen_len : (sb_len - 8);
descp = &sense_buffer[8];
for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
descp += desc_len;
add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
desc_len = add_len + 2;
if (descp[0] == desc_type)
return descp;
if (add_len < 0) // short descriptor ??
break;
}
return NULL;
}
EXPORT_SYMBOL(scsi_sense_desc_find);
/** /**
* scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format) * scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format)
* @sense_buffer: byte array of sense data * @sense_buffer: byte array of sense data
...@@ -2512,31 +2474,3 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, ...@@ -2512,31 +2474,3 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
} }
} }
EXPORT_SYMBOL(scsi_get_sense_info_fld); EXPORT_SYMBOL(scsi_get_sense_info_fld);
/**
* scsi_build_sense_buffer - build sense data in a buffer
* @desc: Sense format (non zero == descriptor format,
* 0 == fixed format)
* @buf: Where to build sense data
* @key: Sense key
* @asc: Additional sense code
* @ascq: Additional sense code qualifier
*
**/
void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
{
if (desc) {
buf[0] = 0x72; /* descriptor, current */
buf[1] = key;
buf[2] = asc;
buf[3] = ascq;
buf[7] = 0;
} else {
buf[0] = 0x70; /* fixed, current */
buf[2] = key;
buf[7] = 0xa;
buf[12] = asc;
buf[13] = ascq;
}
}
EXPORT_SYMBOL(scsi_build_sense_buffer);
...@@ -269,14 +269,14 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg, ...@@ -269,14 +269,14 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg,
} }
bool iscsit_check_np_match( bool iscsit_check_np_match(
struct __kernel_sockaddr_storage *sockaddr, struct sockaddr_storage *sockaddr,
struct iscsi_np *np, struct iscsi_np *np,
int network_transport) int network_transport)
{ {
struct sockaddr_in *sock_in, *sock_in_e; struct sockaddr_in *sock_in, *sock_in_e;
struct sockaddr_in6 *sock_in6, *sock_in6_e; struct sockaddr_in6 *sock_in6, *sock_in6_e;
bool ip_match = false; bool ip_match = false;
u16 port; u16 port, port_e;
if (sockaddr->ss_family == AF_INET6) { if (sockaddr->ss_family == AF_INET6) {
sock_in6 = (struct sockaddr_in6 *)sockaddr; sock_in6 = (struct sockaddr_in6 *)sockaddr;
...@@ -288,6 +288,7 @@ bool iscsit_check_np_match( ...@@ -288,6 +288,7 @@ bool iscsit_check_np_match(
ip_match = true; ip_match = true;
port = ntohs(sock_in6->sin6_port); port = ntohs(sock_in6->sin6_port);
port_e = ntohs(sock_in6_e->sin6_port);
} else { } else {
sock_in = (struct sockaddr_in *)sockaddr; sock_in = (struct sockaddr_in *)sockaddr;
sock_in_e = (struct sockaddr_in *)&np->np_sockaddr; sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
...@@ -296,9 +297,10 @@ bool iscsit_check_np_match( ...@@ -296,9 +297,10 @@ bool iscsit_check_np_match(
ip_match = true; ip_match = true;
port = ntohs(sock_in->sin_port); port = ntohs(sock_in->sin_port);
port_e = ntohs(sock_in_e->sin_port);
} }
if (ip_match && (np->np_port == port) && if (ip_match && (port_e == port) &&
(np->np_network_transport == network_transport)) (np->np_network_transport == network_transport))
return true; return true;
...@@ -309,7 +311,7 @@ bool iscsit_check_np_match( ...@@ -309,7 +311,7 @@ bool iscsit_check_np_match(
* Called with mutex np_lock held * Called with mutex np_lock held
*/ */
static struct iscsi_np *iscsit_get_np( static struct iscsi_np *iscsit_get_np(
struct __kernel_sockaddr_storage *sockaddr, struct sockaddr_storage *sockaddr,
int network_transport) int network_transport)
{ {
struct iscsi_np *np; struct iscsi_np *np;
...@@ -340,12 +342,9 @@ static struct iscsi_np *iscsit_get_np( ...@@ -340,12 +342,9 @@ static struct iscsi_np *iscsit_get_np(
} }
struct iscsi_np *iscsit_add_np( struct iscsi_np *iscsit_add_np(
struct __kernel_sockaddr_storage *sockaddr, struct sockaddr_storage *sockaddr,
char *ip_str,
int network_transport) int network_transport)
{ {
struct sockaddr_in *sock_in;
struct sockaddr_in6 *sock_in6;
struct iscsi_np *np; struct iscsi_np *np;
int ret; int ret;
...@@ -368,16 +367,6 @@ struct iscsi_np *iscsit_add_np( ...@@ -368,16 +367,6 @@ struct iscsi_np *iscsit_add_np(
} }
np->np_flags |= NPF_IP_NETWORK; np->np_flags |= NPF_IP_NETWORK;
if (sockaddr->ss_family == AF_INET6) {
sock_in6 = (struct sockaddr_in6 *)sockaddr;
snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str);
np->np_port = ntohs(sock_in6->sin6_port);
} else {
sock_in = (struct sockaddr_in *)sockaddr;
sprintf(np->np_ip, "%s", ip_str);
np->np_port = ntohs(sock_in->sin_port);
}
np->np_network_transport = network_transport; np->np_network_transport = network_transport;
spin_lock_init(&np->np_thread_lock); spin_lock_init(&np->np_thread_lock);
init_completion(&np->np_restart_comp); init_completion(&np->np_restart_comp);
...@@ -411,8 +400,8 @@ struct iscsi_np *iscsit_add_np( ...@@ -411,8 +400,8 @@ struct iscsi_np *iscsit_add_np(
list_add_tail(&np->np_list, &g_np_list); list_add_tail(&np->np_list, &g_np_list);
mutex_unlock(&np_lock); mutex_unlock(&np_lock);
pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", pr_debug("CORE[0] - Added Network Portal: %pISpc on %s\n",
np->np_ip, np->np_port, np->np_transport->name); &np->np_sockaddr, np->np_transport->name);
return np; return np;
} }
...@@ -481,8 +470,8 @@ int iscsit_del_np(struct iscsi_np *np) ...@@ -481,8 +470,8 @@ int iscsit_del_np(struct iscsi_np *np)
list_del(&np->np_list); list_del(&np->np_list);
mutex_unlock(&np_lock); mutex_unlock(&np_lock);
pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", pr_debug("CORE[0] - Removed Network Portal: %pISpc on %s\n",
np->np_ip, np->np_port, np->np_transport->name); &np->np_sockaddr, np->np_transport->name);
iscsit_put_transport(np->np_transport); iscsit_put_transport(np->np_transport);
kfree(np); kfree(np);
...@@ -1209,7 +1198,6 @@ static u32 iscsit_do_crypto_hash_sg( ...@@ -1209,7 +1198,6 @@ static u32 iscsit_do_crypto_hash_sg(
u8 *pad_bytes) u8 *pad_bytes)
{ {
u32 data_crc; u32 data_crc;
u32 i;
struct scatterlist *sg; struct scatterlist *sg;
unsigned int page_off; unsigned int page_off;
...@@ -1218,15 +1206,15 @@ static u32 iscsit_do_crypto_hash_sg( ...@@ -1218,15 +1206,15 @@ static u32 iscsit_do_crypto_hash_sg(
sg = cmd->first_data_sg; sg = cmd->first_data_sg;
page_off = cmd->first_data_sg_off; page_off = cmd->first_data_sg_off;
i = 0;
while (data_length) { while (data_length) {
u32 cur_len = min_t(u32, data_length, (sg[i].length - page_off)); u32 cur_len = min_t(u32, data_length, (sg->length - page_off));
crypto_hash_update(hash, &sg[i], cur_len); crypto_hash_update(hash, sg, cur_len);
data_length -= cur_len; data_length -= cur_len;
page_off = 0; page_off = 0;
i++; /* iscsit_map_iovec has already checked for invalid sg pointers */
sg = sg_next(sg);
} }
if (padding) { if (padding) {
...@@ -2556,7 +2544,7 @@ static int iscsit_send_conn_drop_async_message( ...@@ -2556,7 +2544,7 @@ static int iscsit_send_conn_drop_async_message(
cmd->stat_sn = conn->stat_sn++; cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->statsn = cpu_to_be32(cmd->stat_sn);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION; hdr->async_event = ISCSI_ASYNC_MSG_DROPPING_CONNECTION;
hdr->param1 = cpu_to_be16(cmd->logout_cid); hdr->param1 = cpu_to_be16(cmd->logout_cid);
hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait); hdr->param2 = cpu_to_be16(conn->sess->sess_ops->DefaultTime2Wait);
...@@ -2628,7 +2616,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -2628,7 +2616,7 @@ iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
hdr->statsn = cpu_to_be32(0xFFFFFFFF); hdr->statsn = cpu_to_be32(0xFFFFFFFF);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
hdr->datasn = cpu_to_be32(datain->data_sn); hdr->datasn = cpu_to_be32(datain->data_sn);
hdr->offset = cpu_to_be32(datain->offset); hdr->offset = cpu_to_be32(datain->offset);
...@@ -2839,7 +2827,7 @@ iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -2839,7 +2827,7 @@ iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
iscsit_increment_maxcmdsn(cmd, conn->sess); iscsit_increment_maxcmdsn(cmd, conn->sess);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Built Logout Response ITT: 0x%08x StatSN:" pr_debug("Built Logout Response ITT: 0x%08x StatSN:"
" 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n", " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
...@@ -2902,7 +2890,7 @@ iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -2902,7 +2890,7 @@ iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
iscsit_increment_maxcmdsn(cmd, conn->sess); iscsit_increment_maxcmdsn(cmd, conn->sess);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x," pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x,"
" StatSN: 0x%08x, Length %u\n", (nopout_response) ? " StatSN: 0x%08x, Length %u\n", (nopout_response) ?
...@@ -3049,7 +3037,7 @@ static int iscsit_send_r2t( ...@@ -3049,7 +3037,7 @@ static int iscsit_send_r2t(
hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag); hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag);
hdr->statsn = cpu_to_be32(conn->stat_sn); hdr->statsn = cpu_to_be32(conn->stat_sn);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
hdr->r2tsn = cpu_to_be32(r2t->r2t_sn); hdr->r2tsn = cpu_to_be32(r2t->r2t_sn);
hdr->data_offset = cpu_to_be32(r2t->offset); hdr->data_offset = cpu_to_be32(r2t->offset);
hdr->data_length = cpu_to_be32(r2t->xfer_len); hdr->data_length = cpu_to_be32(r2t->xfer_len);
...@@ -3202,7 +3190,7 @@ void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -3202,7 +3190,7 @@ void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
iscsit_increment_maxcmdsn(cmd, conn->sess); iscsit_increment_maxcmdsn(cmd, conn->sess);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x," pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
" Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n", " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
...@@ -3321,7 +3309,7 @@ iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -3321,7 +3309,7 @@ iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
iscsit_increment_maxcmdsn(cmd, conn->sess); iscsit_increment_maxcmdsn(cmd, conn->sess);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Built Task Management Response ITT: 0x%08x," pr_debug("Built Task Management Response ITT: 0x%08x,"
" StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n", " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
...@@ -3399,6 +3387,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, ...@@ -3399,6 +3387,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
int target_name_printed; int target_name_printed;
unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
bool active;
buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength, buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength,
SENDTARGETS_BUF_LIMIT); SENDTARGETS_BUF_LIMIT);
...@@ -3452,19 +3441,18 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, ...@@ -3452,19 +3441,18 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
} }
spin_lock(&tpg->tpg_state_lock); spin_lock(&tpg->tpg_state_lock);
if ((tpg->tpg_state == TPG_STATE_FREE) || active = (tpg->tpg_state == TPG_STATE_ACTIVE);
(tpg->tpg_state == TPG_STATE_INACTIVE)) {
spin_unlock(&tpg->tpg_state_lock);
continue;
}
spin_unlock(&tpg->tpg_state_lock); spin_unlock(&tpg->tpg_state_lock);
if (!active && tpg->tpg_attrib.tpg_enabled_sendtargets)
continue;
spin_lock(&tpg->tpg_np_lock); spin_lock(&tpg->tpg_np_lock);
list_for_each_entry(tpg_np, &tpg->tpg_gnp_list, list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
tpg_np_list) { tpg_np_list) {
struct iscsi_np *np = tpg_np->tpg_np; struct iscsi_np *np = tpg_np->tpg_np;
bool inaddr_any = iscsit_check_inaddr_any(np); bool inaddr_any = iscsit_check_inaddr_any(np);
char *fmt_str; struct sockaddr_storage *sockaddr;
if (np->np_network_transport != network_transport) if (np->np_network_transport != network_transport)
continue; continue;
...@@ -3492,15 +3480,15 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, ...@@ -3492,15 +3480,15 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
} }
} }
if (np->np_sockaddr.ss_family == AF_INET6) if (inaddr_any)
fmt_str = "TargetAddress=[%s]:%hu,%hu"; sockaddr = &conn->local_sockaddr;
else else
fmt_str = "TargetAddress=%s:%hu,%hu"; sockaddr = &np->np_sockaddr;
len = sprintf(buf, fmt_str, len = sprintf(buf, "TargetAddress="
inaddr_any ? conn->local_ip : np->np_ip, "%pISpc,%hu",
np->np_port, sockaddr,
tpg->tpgt); tpg->tpgt);
len += 1; len += 1;
if ((len + payload_len) > buffer_len) { if ((len + payload_len) > buffer_len) {
...@@ -3576,7 +3564,7 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -3576,7 +3564,7 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
*/ */
cmd->maxcmdsn_inc = 0; cmd->maxcmdsn_inc = 0;
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x," pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x,"
" Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag, " Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag,
...@@ -3654,7 +3642,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn, ...@@ -3654,7 +3642,7 @@ iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
cmd->stat_sn = conn->stat_sn++; cmd->stat_sn = conn->stat_sn++;
hdr->statsn = cpu_to_be32(cmd->stat_sn); hdr->statsn = cpu_to_be32(cmd->stat_sn);
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); hdr->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
} }
EXPORT_SYMBOL(iscsit_build_reject); EXPORT_SYMBOL(iscsit_build_reject);
......
...@@ -10,10 +10,10 @@ extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *); ...@@ -10,10 +10,10 @@ extern int iscsit_access_np(struct iscsi_np *, struct iscsi_portal_group *);
extern void iscsit_login_kref_put(struct kref *); extern void iscsit_login_kref_put(struct kref *);
extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *, extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *,
struct iscsi_tpg_np *); struct iscsi_tpg_np *);
extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *, extern bool iscsit_check_np_match(struct sockaddr_storage *,
struct iscsi_np *, int); struct iscsi_np *, int);
extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, extern struct iscsi_np *iscsit_add_np(struct sockaddr_storage *,
char *, int); int);
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
struct iscsi_portal_group *, bool); struct iscsi_portal_group *, bool);
extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *);
......
...@@ -99,7 +99,7 @@ static ssize_t lio_target_np_store_sctp( ...@@ -99,7 +99,7 @@ static ssize_t lio_target_np_store_sctp(
* Use existing np->np_sockaddr for SCTP network portal reference * Use existing np->np_sockaddr for SCTP network portal reference
*/ */
tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr,
np->np_ip, tpg_np, ISCSI_SCTP_TCP); tpg_np, ISCSI_SCTP_TCP);
if (!tpg_np_sctp || IS_ERR(tpg_np_sctp)) if (!tpg_np_sctp || IS_ERR(tpg_np_sctp))
goto out; goto out;
} else { } else {
...@@ -177,7 +177,7 @@ static ssize_t lio_target_np_store_iser( ...@@ -177,7 +177,7 @@ static ssize_t lio_target_np_store_iser(
} }
tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr,
np->np_ip, tpg_np, ISCSI_INFINIBAND); tpg_np, ISCSI_INFINIBAND);
if (IS_ERR(tpg_np_iser)) { if (IS_ERR(tpg_np_iser)) {
rc = PTR_ERR(tpg_np_iser); rc = PTR_ERR(tpg_np_iser);
goto out; goto out;
...@@ -220,7 +220,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( ...@@ -220,7 +220,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
struct iscsi_tpg_np *tpg_np; struct iscsi_tpg_np *tpg_np;
char *str, *str2, *ip_str, *port_str; char *str, *str2, *ip_str, *port_str;
struct __kernel_sockaddr_storage sockaddr; struct sockaddr_storage sockaddr;
struct sockaddr_in *sock_in; struct sockaddr_in *sock_in;
struct sockaddr_in6 *sock_in6; struct sockaddr_in6 *sock_in6;
unsigned long port; unsigned long port;
...@@ -235,7 +235,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( ...@@ -235,7 +235,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
memset(buf, 0, MAX_PORTAL_LEN + 1); memset(buf, 0, MAX_PORTAL_LEN + 1);
snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name);
memset(&sockaddr, 0, sizeof(struct __kernel_sockaddr_storage)); memset(&sockaddr, 0, sizeof(struct sockaddr_storage));
str = strstr(buf, "["); str = strstr(buf, "[");
if (str) { if (str) {
...@@ -248,8 +248,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg( ...@@ -248,8 +248,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
str++; /* Skip over leading "[" */ str++; /* Skip over leading "[" */
*str2 = '\0'; /* Terminate the IPv6 address */ *str2 = '\0'; /* Terminate the unbracketed IPv6 address */
str2++; /* Skip over the "]" */ str2++; /* Skip over the \0 */
port_str = strstr(str2, ":"); port_str = strstr(str2, ":");
if (!port_str) { if (!port_str) {
pr_err("Unable to locate \":port\"" pr_err("Unable to locate \":port\""
...@@ -267,7 +267,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( ...@@ -267,7 +267,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
sock_in6 = (struct sockaddr_in6 *)&sockaddr; sock_in6 = (struct sockaddr_in6 *)&sockaddr;
sock_in6->sin6_family = AF_INET6; sock_in6->sin6_family = AF_INET6;
sock_in6->sin6_port = htons((unsigned short)port); sock_in6->sin6_port = htons((unsigned short)port);
ret = in6_pton(str, IPV6_ADDRESS_SPACE, ret = in6_pton(str, -1,
(void *)&sock_in6->sin6_addr.in6_u, -1, &end); (void *)&sock_in6->sin6_addr.in6_u, -1, &end);
if (ret <= 0) { if (ret <= 0) {
pr_err("in6_pton returned: %d\n", ret); pr_err("in6_pton returned: %d\n", ret);
...@@ -316,7 +316,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( ...@@ -316,7 +316,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
* sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/ * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/
* *
*/ */
tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, str, NULL, tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, NULL,
ISCSI_TCP); ISCSI_TCP);
if (IS_ERR(tpg_np)) { if (IS_ERR(tpg_np)) {
iscsit_put_tpg(tpg); iscsit_put_tpg(tpg);
...@@ -344,8 +344,8 @@ static void lio_target_call_delnpfromtpg( ...@@ -344,8 +344,8 @@ static void lio_target_call_delnpfromtpg(
se_tpg = &tpg->tpg_se_tpg; se_tpg = &tpg->tpg_se_tpg;
pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu" pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu"
" PORTAL: %s:%hu\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item), " PORTAL: %pISpc\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
tpg->tpgt, tpg_np->tpg_np->np_ip, tpg_np->tpg_np->np_port); tpg->tpgt, &tpg_np->tpg_np->np_sockaddr);
ret = iscsit_tpg_del_network_portal(tpg, tpg_np); ret = iscsit_tpg_del_network_portal(tpg, tpg_np);
if (ret < 0) if (ret < 0)
...@@ -656,6 +656,7 @@ static ssize_t lio_target_nacl_show_info( ...@@ -656,6 +656,7 @@ static ssize_t lio_target_nacl_show_info(
struct iscsi_conn *conn; struct iscsi_conn *conn;
struct se_session *se_sess; struct se_session *se_sess;
ssize_t rb = 0; ssize_t rb = 0;
u32 max_cmd_sn;
spin_lock_bh(&se_nacl->nacl_sess_lock); spin_lock_bh(&se_nacl->nacl_sess_lock);
se_sess = se_nacl->nacl_sess; se_sess = se_nacl->nacl_sess;
...@@ -703,11 +704,12 @@ static ssize_t lio_target_nacl_show_info( ...@@ -703,11 +704,12 @@ static ssize_t lio_target_nacl_show_info(
" Values]-----------------------\n"); " Values]-----------------------\n");
rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN"
" : MaxCmdSN : ITT : TTT\n"); " : MaxCmdSN : ITT : TTT\n");
max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn);
rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x" rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x"
" 0x%08x 0x%08x\n", " 0x%08x 0x%08x\n",
sess->cmdsn_window, sess->cmdsn_window,
(sess->max_cmd_sn - sess->exp_cmd_sn) + 1, (max_cmd_sn - sess->exp_cmd_sn) + 1,
sess->exp_cmd_sn, sess->max_cmd_sn, sess->exp_cmd_sn, max_cmd_sn,
sess->init_task_tag, sess->targ_xfer_tag); sess->init_task_tag, sess->targ_xfer_tag);
rb += sprintf(page+rb, "----------------------[iSCSI" rb += sprintf(page+rb, "----------------------[iSCSI"
" Connections]-------------------------\n"); " Connections]-------------------------\n");
...@@ -751,7 +753,7 @@ static ssize_t lio_target_nacl_show_info( ...@@ -751,7 +753,7 @@ static ssize_t lio_target_nacl_show_info(
break; break;
} }
rb += sprintf(page+rb, " Address %s %s", conn->login_ip, rb += sprintf(page+rb, " Address %pISc %s", &conn->login_sockaddr,
(conn->network_transport == ISCSI_TCP) ? (conn->network_transport == ISCSI_TCP) ?
"TCP" : "SCTP"); "TCP" : "SCTP");
rb += sprintf(page+rb, " StatSN: 0x%08x\n", rb += sprintf(page+rb, " StatSN: 0x%08x\n",
...@@ -1010,6 +1012,11 @@ TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR); ...@@ -1010,6 +1012,11 @@ TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR);
*/ */
DEF_TPG_ATTRIB(fabric_prot_type); DEF_TPG_ATTRIB(fabric_prot_type);
TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR); TPG_ATTR(fabric_prot_type, S_IRUGO | S_IWUSR);
/*
* Define iscsi_tpg_attrib_s_tpg_enabled_sendtargets
*/
DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
TPG_ATTR(tpg_enabled_sendtargets, S_IRUGO | S_IWUSR);
static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_authentication.attr, &iscsi_tpg_attrib_authentication.attr,
...@@ -1024,6 +1031,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { ...@@ -1024,6 +1031,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_default_erl.attr, &iscsi_tpg_attrib_default_erl.attr,
&iscsi_tpg_attrib_t10_pi.attr, &iscsi_tpg_attrib_t10_pi.attr,
&iscsi_tpg_attrib_fabric_prot_type.attr, &iscsi_tpg_attrib_fabric_prot_type.attr,
&iscsi_tpg_attrib_tpg_enabled_sendtargets.attr,
NULL, NULL,
}; };
......
...@@ -47,19 +47,19 @@ void iscsit_determine_maxcmdsn(struct iscsi_session *sess) ...@@ -47,19 +47,19 @@ void iscsit_determine_maxcmdsn(struct iscsi_session *sess)
* core_set_queue_depth_for_node(). * core_set_queue_depth_for_node().
*/ */
sess->cmdsn_window = se_nacl->queue_depth; sess->cmdsn_window = se_nacl->queue_depth;
sess->max_cmd_sn = (sess->max_cmd_sn + se_nacl->queue_depth) - 1; atomic_add(se_nacl->queue_depth - 1, &sess->max_cmd_sn);
} }
void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess) void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess)
{ {
u32 max_cmd_sn;
if (cmd->immediate_cmd || cmd->maxcmdsn_inc) if (cmd->immediate_cmd || cmd->maxcmdsn_inc)
return; return;
cmd->maxcmdsn_inc = 1; cmd->maxcmdsn_inc = 1;
mutex_lock(&sess->cmdsn_mutex); max_cmd_sn = atomic_inc_return(&sess->max_cmd_sn);
sess->max_cmd_sn += 1; pr_debug("Updated MaxCmdSN to 0x%08x\n", max_cmd_sn);
pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
mutex_unlock(&sess->cmdsn_mutex);
} }
EXPORT_SYMBOL(iscsit_increment_maxcmdsn); EXPORT_SYMBOL(iscsit_increment_maxcmdsn);
...@@ -331,7 +331,7 @@ static int iscsi_login_zero_tsih_s1( ...@@ -331,7 +331,7 @@ static int iscsi_login_zero_tsih_s1(
* The FFP CmdSN window values will be allocated from the TPG's * The FFP CmdSN window values will be allocated from the TPG's
* Initiator Node's ACL once the login has been successfully completed. * Initiator Node's ACL once the login has been successfully completed.
*/ */
sess->max_cmd_sn = be32_to_cpu(pdu->cmdsn); atomic_set(&sess->max_cmd_sn, be32_to_cpu(pdu->cmdsn));
sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
if (!sess->sess_ops) { if (!sess->sess_ops) {
...@@ -729,9 +729,9 @@ void iscsi_post_login_handler( ...@@ -729,9 +729,9 @@ void iscsi_post_login_handler(
stop_timer = 1; stop_timer = 1;
} }
pr_debug("iSCSI Login successful on CID: %hu from %s to" pr_debug("iSCSI Login successful on CID: %hu from %pISpc to"
" %s:%hu,%hu\n", conn->cid, conn->login_ip, " %pISpc,%hu\n", conn->cid, &conn->login_sockaddr,
conn->local_ip, conn->local_port, tpg->tpgt); &conn->local_sockaddr, tpg->tpgt);
list_add_tail(&conn->conn_list, &sess->sess_conn_list); list_add_tail(&conn->conn_list, &sess->sess_conn_list);
atomic_inc(&sess->nconn); atomic_inc(&sess->nconn);
...@@ -776,8 +776,8 @@ void iscsi_post_login_handler( ...@@ -776,8 +776,8 @@ void iscsi_post_login_handler(
pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n"); pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
sess->session_state = TARG_SESS_STATE_LOGGED_IN; sess->session_state = TARG_SESS_STATE_LOGGED_IN;
pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n", pr_debug("iSCSI Login successful on CID: %hu from %pISpc to %pISpc,%hu\n",
conn->cid, conn->login_ip, conn->local_ip, conn->local_port, conn->cid, &conn->login_sockaddr, &conn->local_sockaddr,
tpg->tpgt); tpg->tpgt);
spin_lock_bh(&sess->conn_lock); spin_lock_bh(&sess->conn_lock);
...@@ -823,8 +823,8 @@ static void iscsi_handle_login_thread_timeout(unsigned long data) ...@@ -823,8 +823,8 @@ static void iscsi_handle_login_thread_timeout(unsigned long data)
struct iscsi_np *np = (struct iscsi_np *) data; struct iscsi_np *np = (struct iscsi_np *) data;
spin_lock_bh(&np->np_thread_lock); spin_lock_bh(&np->np_thread_lock);
pr_err("iSCSI Login timeout on Network Portal %s:%hu\n", pr_err("iSCSI Login timeout on Network Portal %pISpc\n",
np->np_ip, np->np_port); &np->np_sockaddr);
if (np->np_login_timer_flags & ISCSI_TF_STOP) { if (np->np_login_timer_flags & ISCSI_TF_STOP) {
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
...@@ -877,7 +877,7 @@ static void iscsi_stop_login_thread_timer(struct iscsi_np *np) ...@@ -877,7 +877,7 @@ static void iscsi_stop_login_thread_timer(struct iscsi_np *np)
int iscsit_setup_np( int iscsit_setup_np(
struct iscsi_np *np, struct iscsi_np *np,
struct __kernel_sockaddr_storage *sockaddr) struct sockaddr_storage *sockaddr)
{ {
struct socket *sock = NULL; struct socket *sock = NULL;
int backlog = ISCSIT_TCP_BACKLOG, ret, opt = 0, len; int backlog = ISCSIT_TCP_BACKLOG, ret, opt = 0, len;
...@@ -916,7 +916,7 @@ int iscsit_setup_np( ...@@ -916,7 +916,7 @@ int iscsit_setup_np(
* in iscsi_target_configfs.c code.. * in iscsi_target_configfs.c code..
*/ */
memcpy(&np->np_sockaddr, sockaddr, memcpy(&np->np_sockaddr, sockaddr,
sizeof(struct __kernel_sockaddr_storage)); sizeof(struct sockaddr_storage));
if (sockaddr->ss_family == AF_INET6) if (sockaddr->ss_family == AF_INET6)
len = sizeof(struct sockaddr_in6); len = sizeof(struct sockaddr_in6);
...@@ -975,7 +975,7 @@ int iscsit_setup_np( ...@@ -975,7 +975,7 @@ int iscsit_setup_np(
int iscsi_target_setup_login_socket( int iscsi_target_setup_login_socket(
struct iscsi_np *np, struct iscsi_np *np,
struct __kernel_sockaddr_storage *sockaddr) struct sockaddr_storage *sockaddr)
{ {
struct iscsit_transport *t; struct iscsit_transport *t;
int rc; int rc;
...@@ -1015,44 +1015,42 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn) ...@@ -1015,44 +1015,42 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
rc = conn->sock->ops->getname(conn->sock, rc = conn->sock->ops->getname(conn->sock,
(struct sockaddr *)&sock_in6, &err, 1); (struct sockaddr *)&sock_in6, &err, 1);
if (!rc) { if (!rc) {
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
snprintf(conn->login_ip, sizeof(conn->login_ip), "[%pI6c]", memcpy(&conn->login_sockaddr, &sock_in6, sizeof(sock_in6));
&sock_in6.sin6_addr.in6_u); } else {
else /* Pretend to be an ipv4 socket */
snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI4", sock_in.sin_family = AF_INET;
&sock_in6.sin6_addr.s6_addr32[3]); sock_in.sin_port = sock_in6.sin6_port;
conn->login_port = ntohs(sock_in6.sin6_port); memcpy(&sock_in.sin_addr, &sock_in6.sin6_addr.s6_addr32[3], 4);
memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in));
}
} }
rc = conn->sock->ops->getname(conn->sock, rc = conn->sock->ops->getname(conn->sock,
(struct sockaddr *)&sock_in6, &err, 0); (struct sockaddr *)&sock_in6, &err, 0);
if (!rc) { if (!rc) {
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
snprintf(conn->local_ip, sizeof(conn->local_ip), "[%pI6c]", memcpy(&conn->local_sockaddr, &sock_in6, sizeof(sock_in6));
&sock_in6.sin6_addr.in6_u); } else {
else /* Pretend to be an ipv4 socket */
snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI4", sock_in.sin_family = AF_INET;
&sock_in6.sin6_addr.s6_addr32[3]); sock_in.sin_port = sock_in6.sin6_port;
conn->local_port = ntohs(sock_in6.sin6_port); memcpy(&sock_in.sin_addr, &sock_in6.sin6_addr.s6_addr32[3], 4);
memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in));
}
} }
} else { } else {
memset(&sock_in, 0, sizeof(struct sockaddr_in)); memset(&sock_in, 0, sizeof(struct sockaddr_in));
rc = conn->sock->ops->getname(conn->sock, rc = conn->sock->ops->getname(conn->sock,
(struct sockaddr *)&sock_in, &err, 1); (struct sockaddr *)&sock_in, &err, 1);
if (!rc) { if (!rc)
sprintf(conn->login_ip, "%pI4", memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in));
&sock_in.sin_addr.s_addr);
conn->login_port = ntohs(sock_in.sin_port);
}
rc = conn->sock->ops->getname(conn->sock, rc = conn->sock->ops->getname(conn->sock,
(struct sockaddr *)&sock_in, &err, 0); (struct sockaddr *)&sock_in, &err, 0);
if (!rc) { if (!rc)
sprintf(conn->local_ip, "%pI4", memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in));
&sock_in.sin_addr.s_addr);
conn->local_port = ntohs(sock_in.sin_port);
}
} }
return 0; return 0;
...@@ -1302,8 +1300,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1302,8 +1300,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
spin_lock_bh(&np->np_thread_lock); spin_lock_bh(&np->np_thread_lock);
if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
spin_unlock_bh(&np->np_thread_lock); spin_unlock_bh(&np->np_thread_lock);
pr_err("iSCSI Network Portal on %s:%hu currently not" pr_err("iSCSI Network Portal on %pISpc currently not"
" active.\n", np->np_ip, np->np_port); " active.\n", &np->np_sockaddr);
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
goto new_sess_out; goto new_sess_out;
...@@ -1312,9 +1310,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) ...@@ -1312,9 +1310,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
conn->network_transport = np->np_network_transport; conn->network_transport = np->np_network_transport;
pr_debug("Received iSCSI login request from %s on %s Network" pr_debug("Received iSCSI login request from %pISpc on %s Network"
" Portal %s:%hu\n", conn->login_ip, np->np_transport->name, " Portal %pISpc\n", &conn->login_sockaddr, np->np_transport->name,
conn->local_ip, conn->local_port); &conn->local_sockaddr);
pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n"); pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
conn->conn_state = TARG_CONN_STATE_IN_LOGIN; conn->conn_state = TARG_CONN_STATE_IN_LOGIN;
......
...@@ -5,9 +5,9 @@ extern int iscsi_login_setup_crypto(struct iscsi_conn *); ...@@ -5,9 +5,9 @@ extern int iscsi_login_setup_crypto(struct iscsi_conn *);
extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *); extern int iscsi_check_for_session_reinstatement(struct iscsi_conn *);
extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32); extern int iscsi_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32);
extern int iscsit_setup_np(struct iscsi_np *, extern int iscsit_setup_np(struct iscsi_np *,
struct __kernel_sockaddr_storage *); struct sockaddr_storage *);
extern int iscsi_target_setup_login_socket(struct iscsi_np *, extern int iscsi_target_setup_login_socket(struct iscsi_np *,
struct __kernel_sockaddr_storage *); struct sockaddr_storage *);
extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *); extern int iscsit_accept_np(struct iscsi_np *, struct iscsi_conn *);
extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *); extern int iscsit_get_login_rx(struct iscsi_conn *, struct iscsi_login *);
extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32); extern int iscsit_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32);
......
...@@ -341,7 +341,6 @@ static int iscsi_target_check_first_request( ...@@ -341,7 +341,6 @@ static int iscsi_target_check_first_request(
static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login) static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
{ {
u32 padding = 0; u32 padding = 0;
struct iscsi_session *sess = conn->sess;
struct iscsi_login_rsp *login_rsp; struct iscsi_login_rsp *login_rsp;
login_rsp = (struct iscsi_login_rsp *) login->rsp; login_rsp = (struct iscsi_login_rsp *) login->rsp;
...@@ -353,7 +352,7 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log ...@@ -353,7 +352,7 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
login_rsp->itt = login->init_task_tag; login_rsp->itt = login->init_task_tag;
login_rsp->statsn = cpu_to_be32(conn->stat_sn++); login_rsp->statsn = cpu_to_be32(conn->stat_sn++);
login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); login_rsp->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
login_rsp->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); login_rsp->max_cmdsn = cpu_to_be32((u32) atomic_read(&conn->sess->max_cmd_sn));
pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x," pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
" ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:" " ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
...@@ -382,10 +381,6 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log ...@@ -382,10 +381,6 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
goto err; goto err;
login->rsp_length = 0; login->rsp_length = 0;
mutex_lock(&sess->cmdsn_mutex);
login_rsp->exp_cmdsn = cpu_to_be32(sess->exp_cmd_sn);
login_rsp->max_cmdsn = cpu_to_be32(sess->max_cmd_sn);
mutex_unlock(&sess->cmdsn_mutex);
return 0; return 0;
......
...@@ -430,7 +430,7 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr( ...@@ -430,7 +430,7 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
int ret; int ret;
spin_lock(&lstat->lock); spin_lock(&lstat->lock);
ret = snprintf(page, PAGE_SIZE, "%s\n", lstat->last_intr_fail_ip_addr); ret = snprintf(page, PAGE_SIZE, "%pISc\n", &lstat->last_intr_fail_sockaddr);
spin_unlock(&lstat->lock); spin_unlock(&lstat->lock);
return ret; return ret;
......
...@@ -50,7 +50,7 @@ u8 iscsit_tmr_abort_task( ...@@ -50,7 +50,7 @@ u8 iscsit_tmr_abort_task(
pr_err("Unable to locate RefTaskTag: 0x%08x on CID:" pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
" %hu.\n", hdr->rtt, conn->cid); " %hu.\n", hdr->rtt, conn->cid);
return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) && return (iscsi_sna_gte(be32_to_cpu(hdr->refcmdsn), conn->sess->exp_cmd_sn) &&
iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), conn->sess->max_cmd_sn)) ? iscsi_sna_lte(be32_to_cpu(hdr->refcmdsn), (u32) atomic_read(&conn->sess->max_cmd_sn))) ?
ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK; ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
} }
if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) { if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
......
...@@ -226,6 +226,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg) ...@@ -226,6 +226,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
a->default_erl = TA_DEFAULT_ERL; a->default_erl = TA_DEFAULT_ERL;
a->t10_pi = TA_DEFAULT_T10_PI; a->t10_pi = TA_DEFAULT_T10_PI;
a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
} }
int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
...@@ -430,7 +431,7 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np( ...@@ -430,7 +431,7 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
static bool iscsit_tpg_check_network_portal( static bool iscsit_tpg_check_network_portal(
struct iscsi_tiqn *tiqn, struct iscsi_tiqn *tiqn,
struct __kernel_sockaddr_storage *sockaddr, struct sockaddr_storage *sockaddr,
int network_transport) int network_transport)
{ {
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
...@@ -459,8 +460,7 @@ static bool iscsit_tpg_check_network_portal( ...@@ -459,8 +460,7 @@ static bool iscsit_tpg_check_network_portal(
struct iscsi_tpg_np *iscsit_tpg_add_network_portal( struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
struct iscsi_portal_group *tpg, struct iscsi_portal_group *tpg,
struct __kernel_sockaddr_storage *sockaddr, struct sockaddr_storage *sockaddr,
char *ip_str,
struct iscsi_tpg_np *tpg_np_parent, struct iscsi_tpg_np *tpg_np_parent,
int network_transport) int network_transport)
{ {
...@@ -470,8 +470,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( ...@@ -470,8 +470,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
if (!tpg_np_parent) { if (!tpg_np_parent) {
if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
network_transport)) { network_transport)) {
pr_err("Network Portal: %s already exists on a" pr_err("Network Portal: %pISc already exists on a"
" different TPG on %s\n", ip_str, " different TPG on %s\n", sockaddr,
tpg->tpg_tiqn->tiqn); tpg->tpg_tiqn->tiqn);
return ERR_PTR(-EEXIST); return ERR_PTR(-EEXIST);
} }
...@@ -484,7 +484,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( ...@@ -484,7 +484,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
np = iscsit_add_np(sockaddr, ip_str, network_transport); np = iscsit_add_np(sockaddr, network_transport);
if (IS_ERR(np)) { if (IS_ERR(np)) {
kfree(tpg_np); kfree(tpg_np);
return ERR_CAST(np); return ERR_CAST(np);
...@@ -514,8 +514,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( ...@@ -514,8 +514,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
spin_unlock(&tpg_np_parent->tpg_np_parent_lock); spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
} }
pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n", pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n",
tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
np->np_transport->name); np->np_transport->name);
return tpg_np; return tpg_np;
...@@ -528,8 +528,8 @@ static int iscsit_tpg_release_np( ...@@ -528,8 +528,8 @@ static int iscsit_tpg_release_np(
{ {
iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true); iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n", pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n",
tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
np->np_transport->name); np->np_transport->name);
tpg_np->tpg_np = NULL; tpg_np->tpg_np = NULL;
...@@ -892,3 +892,21 @@ int iscsit_ta_fabric_prot_type( ...@@ -892,3 +892,21 @@ int iscsit_ta_fabric_prot_type(
return 0; return 0;
} }
int iscsit_ta_tpg_enabled_sendtargets(
struct iscsi_portal_group *tpg,
u32 flag)
{
struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
if ((flag != 0) && (flag != 1)) {
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}
a->tpg_enabled_sendtargets = flag;
pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:"
" %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF");
return 0;
}
...@@ -22,7 +22,7 @@ extern struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(struct iscsi_session ...@@ -22,7 +22,7 @@ extern struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(struct iscsi_session
extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *); extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *);
extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int); extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int);
extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *, extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *,
struct __kernel_sockaddr_storage *, char *, struct iscsi_tpg_np *, struct sockaddr_storage *, struct iscsi_tpg_np *,
int); int);
extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *, extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *,
struct iscsi_tpg_np *); struct iscsi_tpg_np *);
...@@ -40,5 +40,6 @@ extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32); ...@@ -40,5 +40,6 @@ extern int iscsit_ta_demo_mode_discovery(struct iscsi_portal_group *, u32);
extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32);
extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);
extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32);
extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32);
#endif /* ISCSI_TARGET_TPG_H */ #endif /* ISCSI_TARGET_TPG_H */
...@@ -233,6 +233,7 @@ struct iscsi_r2t *iscsit_get_holder_for_r2tsn( ...@@ -233,6 +233,7 @@ struct iscsi_r2t *iscsit_get_holder_for_r2tsn(
static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn) static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cmdsn)
{ {
u32 max_cmdsn;
int ret; int ret;
/* /*
...@@ -241,10 +242,10 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm ...@@ -241,10 +242,10 @@ static inline int iscsit_check_received_cmdsn(struct iscsi_session *sess, u32 cm
* or order CmdSNs due to multiple connection sessions and/or * or order CmdSNs due to multiple connection sessions and/or
* CRC failures. * CRC failures.
*/ */
if (iscsi_sna_gt(cmdsn, sess->max_cmd_sn)) { max_cmdsn = atomic_read(&sess->max_cmd_sn);
if (iscsi_sna_gt(cmdsn, max_cmdsn)) {
pr_err("Received CmdSN: 0x%08x is greater than" pr_err("Received CmdSN: 0x%08x is greater than"
" MaxCmdSN: 0x%08x, ignoring.\n", cmdsn, " MaxCmdSN: 0x%08x, ignoring.\n", cmdsn, max_cmdsn);
sess->max_cmd_sn);
ret = CMDSN_MAXCMDSN_OVERRUN; ret = CMDSN_MAXCMDSN_OVERRUN;
} else if (cmdsn == sess->exp_cmd_sn) { } else if (cmdsn == sess->exp_cmd_sn) {
...@@ -1371,6 +1372,33 @@ int tx_data( ...@@ -1371,6 +1372,33 @@ int tx_data(
return iscsit_do_tx_data(conn, &c); return iscsit_do_tx_data(conn, &c);
} }
static bool sockaddr_equal(struct sockaddr_storage *x, struct sockaddr_storage *y)
{
switch (x->ss_family) {
case AF_INET: {
struct sockaddr_in *sinx = (struct sockaddr_in *)x;
struct sockaddr_in *siny = (struct sockaddr_in *)y;
if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr)
return false;
if (sinx->sin_port != siny->sin_port)
return false;
break;
}
case AF_INET6: {
struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x;
struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y;
if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr))
return false;
if (sinx->sin6_port != siny->sin6_port)
return false;
break;
}
default:
return false;
}
return true;
}
void iscsit_collect_login_stats( void iscsit_collect_login_stats(
struct iscsi_conn *conn, struct iscsi_conn *conn,
u8 status_class, u8 status_class,
...@@ -1387,7 +1415,7 @@ void iscsit_collect_login_stats( ...@@ -1387,7 +1415,7 @@ void iscsit_collect_login_stats(
ls = &tiqn->login_stats; ls = &tiqn->login_stats;
spin_lock(&ls->lock); spin_lock(&ls->lock);
if (!strcmp(conn->login_ip, ls->last_intr_fail_ip_addr) && if (sockaddr_equal(&conn->login_sockaddr, &ls->last_intr_fail_sockaddr) &&
((get_jiffies_64() - ls->last_fail_time) < 10)) { ((get_jiffies_64() - ls->last_fail_time) < 10)) {
/* We already have the failure info for this login */ /* We already have the failure info for this login */
spin_unlock(&ls->lock); spin_unlock(&ls->lock);
...@@ -1427,8 +1455,7 @@ void iscsit_collect_login_stats( ...@@ -1427,8 +1455,7 @@ void iscsit_collect_login_stats(
ls->last_intr_fail_ip_family = conn->login_family; ls->last_intr_fail_ip_family = conn->login_family;
snprintf(ls->last_intr_fail_ip_addr, IPV6_ADDRESS_SPACE, ls->last_intr_fail_sockaddr = conn->login_sockaddr;
"%s", conn->login_ip);
ls->last_fail_time = get_jiffies_64(); ls->last_fail_time = get_jiffies_64();
} }
......
...@@ -526,7 +526,7 @@ static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg) ...@@ -526,7 +526,7 @@ static inline struct tcm_loop_tpg *tl_tpg(struct se_portal_group *se_tpg)
static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg) static char *tcm_loop_get_endpoint_wwn(struct se_portal_group *se_tpg)
{ {
/* /*
* Return the passed NAA identifier for the SAS Target Port * Return the passed NAA identifier for the Target Port
*/ */
return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0]; return &tl_tpg(se_tpg)->tl_hba->tl_wwn_address[0];
} }
...@@ -845,7 +845,7 @@ static int tcm_loop_make_nexus( ...@@ -845,7 +845,7 @@ static int tcm_loop_make_nexus(
transport_free_session(tl_nexus->se_sess); transport_free_session(tl_nexus->se_sess);
goto out; goto out;
} }
/* Now, register the SAS I_T Nexus as active. */ /* Now, register the I_T Nexus as active. */
transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl, transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
tl_nexus->se_sess, tl_nexus); tl_nexus->se_sess, tl_nexus);
tl_tpg->tl_nexus = tl_nexus; tl_tpg->tl_nexus = tl_nexus;
...@@ -884,7 +884,7 @@ static int tcm_loop_drop_nexus( ...@@ -884,7 +884,7 @@ static int tcm_loop_drop_nexus(
" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba), " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
tl_nexus->se_sess->se_node_acl->initiatorname); tl_nexus->se_sess->se_node_acl->initiatorname);
/* /*
* Release the SCSI I_T Nexus to the emulated SAS Target Port * Release the SCSI I_T Nexus to the emulated Target Port
*/ */
transport_deregister_session(tl_nexus->se_sess); transport_deregister_session(tl_nexus->se_sess);
tpg->tl_nexus = NULL; tpg->tl_nexus = NULL;
...@@ -1034,6 +1034,11 @@ static ssize_t tcm_loop_tpg_store_transport_status( ...@@ -1034,6 +1034,11 @@ static ssize_t tcm_loop_tpg_store_transport_status(
} }
if (!strncmp(page, "offline", 7)) { if (!strncmp(page, "offline", 7)) {
tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE; tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE;
if (tl_tpg->tl_nexus) {
struct se_session *tl_sess = tl_tpg->tl_nexus->se_sess;
core_allocate_nexus_loss_ua(tl_sess->se_node_acl);
}
return count; return count;
} }
return -EINVAL; return -EINVAL;
...@@ -1077,7 +1082,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( ...@@ -1077,7 +1082,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
tl_tpg->tl_hba = tl_hba; tl_tpg->tl_hba = tl_hba;
tl_tpg->tl_tpgt = tpgt; tl_tpg->tl_tpgt = tpgt;
/* /*
* Register the tl_tpg as a emulated SAS TCM Target Endpoint * Register the tl_tpg as a emulated TCM Target Endpoint
*/ */
ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id); ret = core_tpg_register(wwn, &tl_tpg->tl_se_tpg, tl_hba->tl_proto_id);
if (ret < 0) if (ret < 0)
...@@ -1102,11 +1107,11 @@ static void tcm_loop_drop_naa_tpg( ...@@ -1102,11 +1107,11 @@ static void tcm_loop_drop_naa_tpg(
tl_hba = tl_tpg->tl_hba; tl_hba = tl_tpg->tl_hba;
tpgt = tl_tpg->tl_tpgt; tpgt = tl_tpg->tl_tpgt;
/* /*
* Release the I_T Nexus for the Virtual SAS link if present * Release the I_T Nexus for the Virtual target link if present
*/ */
tcm_loop_drop_nexus(tl_tpg); tcm_loop_drop_nexus(tl_tpg);
/* /*
* Deregister the tl_tpg as a emulated SAS TCM Target Endpoint * Deregister the tl_tpg as a emulated TCM Target Endpoint
*/ */
core_tpg_deregister(se_tpg); core_tpg_deregister(se_tpg);
...@@ -1199,8 +1204,9 @@ static void tcm_loop_drop_scsi_hba( ...@@ -1199,8 +1204,9 @@ static void tcm_loop_drop_scsi_hba(
struct tcm_loop_hba, tl_hba_wwn); struct tcm_loop_hba, tl_hba_wwn);
pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target"
" SAS Address: %s at Linux/SCSI Host ID: %d\n", " %s Address: %s at Linux/SCSI Host ID: %d\n",
tl_hba->tl_wwn_address, tl_hba->sh->host_no); tcm_loop_dump_proto_id(tl_hba), tl_hba->tl_wwn_address,
tl_hba->sh->host_no);
/* /*
* Call device_unregister() on the original tl_hba->dev. * Call device_unregister() on the original tl_hba->dev.
* tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will
......
...@@ -620,8 +620,6 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( ...@@ -620,8 +620,6 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl(
lacl->mapped_lun = mapped_lun; lacl->mapped_lun = mapped_lun;
lacl->se_lun_nacl = nacl; lacl->se_lun_nacl = nacl;
snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s",
nacl->initiatorname);
return lacl; return lacl;
} }
...@@ -656,7 +654,7 @@ int core_dev_add_initiator_node_lun_acl( ...@@ -656,7 +654,7 @@ int core_dev_add_initiator_node_lun_acl(
" InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(), " InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(),
tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun, tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun,
(lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO", (lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO",
lacl->initiatorname); nacl->initiatorname);
/* /*
* Check to see if there are any existing persistent reservation APTPL * Check to see if there are any existing persistent reservation APTPL
* pre-registrations that need to be enabled for this LUN ACL.. * pre-registrations that need to be enabled for this LUN ACL..
...@@ -688,7 +686,7 @@ int core_dev_del_initiator_node_lun_acl( ...@@ -688,7 +686,7 @@ int core_dev_del_initiator_node_lun_acl(
" InitiatorNode: %s Mapped LUN: %llu\n", " InitiatorNode: %s Mapped LUN: %llu\n",
tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->get_fabric_name(),
tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
lacl->initiatorname, lacl->mapped_lun); nacl->initiatorname, lacl->mapped_lun);
return 0; return 0;
} }
...@@ -701,7 +699,7 @@ void core_dev_free_initiator_node_lun_acl( ...@@ -701,7 +699,7 @@ void core_dev_free_initiator_node_lun_acl(
" Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(), " Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(),
tpg->se_tpg_tfo->tpg_get_tag(tpg), tpg->se_tpg_tfo->tpg_get_tag(tpg),
tpg->se_tpg_tfo->get_fabric_name(), tpg->se_tpg_tfo->get_fabric_name(),
lacl->initiatorname, lacl->mapped_lun); lacl->se_lun_nacl->initiatorname, lacl->mapped_lun);
kfree(lacl); kfree(lacl);
} }
...@@ -754,7 +752,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) ...@@ -754,7 +752,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
dev->dev_link_magic = SE_DEV_LINK_MAGIC; dev->dev_link_magic = SE_DEV_LINK_MAGIC;
dev->se_hba = hba; dev->se_hba = hba;
dev->transport = hba->backend->ops; dev->transport = hba->backend->ops;
dev->prot_length = sizeof(struct se_dif_v1_tuple); dev->prot_length = sizeof(struct t10_pi_tuple);
dev->hba_index = hba->hba_index; dev->hba_index = hba->hba_index;
INIT_LIST_HEAD(&dev->dev_list); INIT_LIST_HEAD(&dev->dev_list);
...@@ -771,7 +769,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) ...@@ -771,7 +769,6 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
spin_lock_init(&dev->se_tmr_lock); spin_lock_init(&dev->se_tmr_lock);
spin_lock_init(&dev->qf_cmd_lock); spin_lock_init(&dev->qf_cmd_lock);
sema_init(&dev->caw_sem, 1); sema_init(&dev->caw_sem, 1);
atomic_set(&dev->dev_ordered_id, 0);
INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list); INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list);
spin_lock_init(&dev->t10_wwn.t10_vpd_lock); spin_lock_init(&dev->t10_wwn.t10_vpd_lock);
INIT_LIST_HEAD(&dev->t10_pr.registration_list); INIT_LIST_HEAD(&dev->t10_pr.registration_list);
......
...@@ -203,7 +203,7 @@ static ssize_t target_fabric_mappedlun_store_write_protect( ...@@ -203,7 +203,7 @@ static ssize_t target_fabric_mappedlun_store_write_protect(
pr_debug("%s_ConfigFS: Changed Initiator ACL: %s" pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
" Mapped LUN: %llu Write Protect bit to %s\n", " Mapped LUN: %llu Write Protect bit to %s\n",
se_tpg->se_tpg_tfo->get_fabric_name(), se_tpg->se_tpg_tfo->get_fabric_name(),
lacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF"); se_nacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF");
return count; return count;
......
...@@ -184,3 +184,8 @@ core_delete_hba(struct se_hba *hba) ...@@ -184,3 +184,8 @@ core_delete_hba(struct se_hba *hba)
kfree(hba); kfree(hba);
return 0; return 0;
} }
bool target_sense_desc_format(struct se_device *dev)
{
return dev->transport->get_blocks(dev) > U32_MAX;
}
...@@ -154,6 +154,38 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd) ...@@ -154,6 +154,38 @@ sbc_emulate_readcapacity_16(struct se_cmd *cmd)
return 0; return 0;
} }
static sense_reason_t
sbc_emulate_startstop(struct se_cmd *cmd)
{
unsigned char *cdb = cmd->t_task_cdb;
/*
* See sbc3r36 section 5.25
* Immediate bit should be set since there is nothing to complete
* POWER CONDITION MODIFIER 0h
*/
if (!(cdb[1] & 1) || cdb[2] || cdb[3])
return TCM_INVALID_CDB_FIELD;
/*
* See sbc3r36 section 5.25
* POWER CONDITION 0h START_VALID - process START and LOEJ
*/
if (cdb[4] >> 4 & 0xf)
return TCM_INVALID_CDB_FIELD;
/*
* See sbc3r36 section 5.25
* LOEJ 0h - nothing to load or unload
* START 1h - we are ready
*/
if (!(cdb[4] & 1) || (cdb[4] & 2) || (cdb[4] & 4))
return TCM_INVALID_CDB_FIELD;
target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
}
sector_t sbc_get_write_same_sectors(struct se_cmd *cmd) sector_t sbc_get_write_same_sectors(struct se_cmd *cmd)
{ {
u32 num_blocks; u32 num_blocks;
...@@ -960,6 +992,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) ...@@ -960,6 +992,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
" than 1\n", sectors); " than 1\n", sectors);
return TCM_INVALID_CDB_FIELD; return TCM_INVALID_CDB_FIELD;
} }
if (sbc_check_dpofua(dev, cmd, cdb))
return TCM_INVALID_CDB_FIELD;
/* /*
* Double size because we have two buffers, note that * Double size because we have two buffers, note that
* zero is not an error.. * zero is not an error..
...@@ -1069,6 +1104,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) ...@@ -1069,6 +1104,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
size = 0; size = 0;
cmd->execute_cmd = sbc_emulate_noop; cmd->execute_cmd = sbc_emulate_noop;
break; break;
case START_STOP:
size = 0;
cmd->execute_cmd = sbc_emulate_startstop;
break;
default: default:
ret = spc_parse_cdb(cmd, &size); ret = spc_parse_cdb(cmd, &size);
if (ret) if (ret)
...@@ -1191,7 +1230,7 @@ void ...@@ -1191,7 +1230,7 @@ void
sbc_dif_generate(struct se_cmd *cmd) sbc_dif_generate(struct se_cmd *cmd)
{ {
struct se_device *dev = cmd->se_dev; struct se_device *dev = cmd->se_dev;
struct se_dif_v1_tuple *sdt; struct t10_pi_tuple *sdt;
struct scatterlist *dsg = cmd->t_data_sg, *psg; struct scatterlist *dsg = cmd->t_data_sg, *psg;
sector_t sector = cmd->t_task_lba; sector_t sector = cmd->t_task_lba;
void *daddr, *paddr; void *daddr, *paddr;
...@@ -1203,7 +1242,7 @@ sbc_dif_generate(struct se_cmd *cmd) ...@@ -1203,7 +1242,7 @@ sbc_dif_generate(struct se_cmd *cmd)
daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
for (j = 0; j < psg->length; for (j = 0; j < psg->length;
j += sizeof(struct se_dif_v1_tuple)) { j += sizeof(*sdt)) {
__u16 crc; __u16 crc;
unsigned int avail; unsigned int avail;
...@@ -1256,7 +1295,7 @@ sbc_dif_generate(struct se_cmd *cmd) ...@@ -1256,7 +1295,7 @@ sbc_dif_generate(struct se_cmd *cmd)
} }
static sense_reason_t static sense_reason_t
sbc_dif_v1_verify(struct se_cmd *cmd, struct se_dif_v1_tuple *sdt, sbc_dif_v1_verify(struct se_cmd *cmd, struct t10_pi_tuple *sdt,
__u16 crc, sector_t sector, unsigned int ei_lba) __u16 crc, sector_t sector, unsigned int ei_lba)
{ {
__be16 csum; __be16 csum;
...@@ -1346,7 +1385,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, ...@@ -1346,7 +1385,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
unsigned int ei_lba, struct scatterlist *psg, int psg_off) unsigned int ei_lba, struct scatterlist *psg, int psg_off)
{ {
struct se_device *dev = cmd->se_dev; struct se_device *dev = cmd->se_dev;
struct se_dif_v1_tuple *sdt; struct t10_pi_tuple *sdt;
struct scatterlist *dsg = cmd->t_data_sg; struct scatterlist *dsg = cmd->t_data_sg;
sector_t sector = start; sector_t sector = start;
void *daddr, *paddr; void *daddr, *paddr;
...@@ -1361,7 +1400,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, ...@@ -1361,7 +1400,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
for (i = psg_off; i < psg->length && for (i = psg_off; i < psg->length &&
sector < start + sectors; sector < start + sectors;
i += sizeof(struct se_dif_v1_tuple)) { i += sizeof(*sdt)) {
__u16 crc; __u16 crc;
unsigned int avail; unsigned int avail;
......
...@@ -484,8 +484,8 @@ static sense_reason_t ...@@ -484,8 +484,8 @@ static sense_reason_t
spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
{ {
struct se_device *dev = cmd->se_dev; struct se_device *dev = cmd->se_dev;
int have_tp = 0; u32 mtl = 0;
int opt, min; int have_tp = 0, opt, min;
/* /*
* Following spc3r22 section 6.5.3 Block Limits VPD page, when * Following spc3r22 section 6.5.3 Block Limits VPD page, when
...@@ -516,8 +516,15 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) ...@@ -516,8 +516,15 @@ spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
/* /*
* Set MAXIMUM TRANSFER LENGTH * Set MAXIMUM TRANSFER LENGTH
*
* XXX: Currently assumes single PAGE_SIZE per scatterlist for fabrics
* enforcing maximum HW scatter-gather-list entry limit
*/ */
put_unaligned_be32(dev->dev_attrib.hw_max_sectors, &buf[8]); if (cmd->se_tfo->max_data_sg_nents) {
mtl = (cmd->se_tfo->max_data_sg_nents * PAGE_SIZE) /
dev->dev_attrib.block_size;
}
put_unaligned_be32(min_not_zero(mtl, dev->dev_attrib.hw_max_sectors), &buf[8]);
/* /*
* Set OPTIMAL TRANSFER LENGTH * Set OPTIMAL TRANSFER LENGTH
...@@ -768,7 +775,12 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p) ...@@ -768,7 +775,12 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p)
if (pc == 1) if (pc == 1)
goto out; goto out;
p[2] = 2; /* GLTSD: No implicit save of log parameters */
p[2] = (1 << 1);
if (target_sense_desc_format(dev))
/* D_SENSE: Descriptor format sense data for 64bit sectors */
p[2] |= (1 << 2);
/* /*
* From spc4r23, 7.4.7 Control mode page * From spc4r23, 7.4.7 Control mode page
* *
...@@ -1151,6 +1163,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) ...@@ -1151,6 +1163,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
unsigned char *rbuf; unsigned char *rbuf;
u8 ua_asc = 0, ua_ascq = 0; u8 ua_asc = 0, ua_ascq = 0;
unsigned char buf[SE_SENSE_BUF]; unsigned char buf[SE_SENSE_BUF];
bool desc_format = target_sense_desc_format(cmd->se_dev);
memset(buf, 0, SE_SENSE_BUF); memset(buf, 0, SE_SENSE_BUF);
...@@ -1164,32 +1177,11 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) ...@@ -1164,32 +1177,11 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
if (!rbuf) if (!rbuf)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))
/* scsi_build_sense_buffer(desc_format, buf, UNIT_ATTENTION,
* CURRENT ERROR, UNIT ATTENTION ua_asc, ua_ascq);
*/ else
buf[0] = 0x70; scsi_build_sense_buffer(desc_format, buf, NO_SENSE, 0x0, 0x0);
buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
/*
* The Additional Sense Code (ASC) from the UNIT ATTENTION
*/
buf[SPC_ASC_KEY_OFFSET] = ua_asc;
buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
buf[7] = 0x0A;
} else {
/*
* CURRENT ERROR, NO SENSE
*/
buf[0] = 0x70;
buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
/*
* NO ADDITIONAL SENSE INFORMATION
*/
buf[SPC_ASC_KEY_OFFSET] = 0x00;
buf[7] = 0x0A;
}
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd); transport_kunmap_data_sg(cmd);
...@@ -1418,9 +1410,6 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) ...@@ -1418,9 +1410,6 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
} }
break; break;
default: default:
pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode"
" 0x%02x, sending CHECK_CONDITION.\n",
cmd->se_tfo->get_fabric_name(), cdb[0]);
return TCM_UNSUPPORTED_SCSI_OPCODE; return TCM_UNSUPPORTED_SCSI_OPCODE;
} }
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "target_core_internal.h" #include "target_core_internal.h"
#include "target_core_alua.h" #include "target_core_alua.h"
#include "target_core_pr.h" #include "target_core_pr.h"
#include "target_core_ua.h"
extern struct se_device *g_lun0_dev; extern struct se_device *g_lun0_dev;
...@@ -83,6 +84,22 @@ struct se_node_acl *core_tpg_get_initiator_node_acl( ...@@ -83,6 +84,22 @@ struct se_node_acl *core_tpg_get_initiator_node_acl(
} }
EXPORT_SYMBOL(core_tpg_get_initiator_node_acl); EXPORT_SYMBOL(core_tpg_get_initiator_node_acl);
void core_allocate_nexus_loss_ua(
struct se_node_acl *nacl)
{
struct se_dev_entry *deve;
if (!nacl)
return;
rcu_read_lock();
hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link)
core_scsi3_ua_allocate(deve, 0x29,
ASCQ_29H_NEXUS_LOSS_OCCURRED);
rcu_read_unlock();
}
EXPORT_SYMBOL(core_allocate_nexus_loss_ua);
/* core_tpg_add_node_to_devs(): /* core_tpg_add_node_to_devs():
* *
* *
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <scsi/scsi_proto.h> #include <scsi/scsi_proto.h>
#include <scsi/scsi_common.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#include <target/target_core_backend.h> #include <target/target_core_backend.h>
...@@ -1074,6 +1075,55 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83) ...@@ -1074,6 +1075,55 @@ transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
} }
EXPORT_SYMBOL(transport_set_vpd_ident); EXPORT_SYMBOL(transport_set_vpd_ident);
static sense_reason_t
target_check_max_data_sg_nents(struct se_cmd *cmd, struct se_device *dev,
unsigned int size)
{
u32 mtl;
if (!cmd->se_tfo->max_data_sg_nents)
return TCM_NO_SENSE;
/*
* Check if fabric enforced maximum SGL entries per I/O descriptor
* exceeds se_cmd->data_length. If true, set SCF_UNDERFLOW_BIT +
* residual_count and reduce original cmd->data_length to maximum
* length based on single PAGE_SIZE entry scatter-lists.
*/
mtl = (cmd->se_tfo->max_data_sg_nents * PAGE_SIZE);
if (cmd->data_length > mtl) {
/*
* If an existing CDB overflow is present, calculate new residual
* based on CDB size minus fabric maximum transfer length.
*
* If an existing CDB underflow is present, calculate new residual
* based on original cmd->data_length minus fabric maximum transfer
* length.
*
* Otherwise, set the underflow residual based on cmd->data_length
* minus fabric maximum transfer length.
*/
if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) {
cmd->residual_count = (size - mtl);
} else if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
u32 orig_dl = size + cmd->residual_count;
cmd->residual_count = (orig_dl - mtl);
} else {
cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT;
cmd->residual_count = (cmd->data_length - mtl);
}
cmd->data_length = mtl;
/*
* Reset sbc_check_prot() calculated protection payload
* length based upon the new smaller MTL.
*/
if (cmd->prot_length) {
u32 sectors = (mtl / dev->dev_attrib.block_size);
cmd->prot_length = dev->prot_length * sectors;
}
}
return TCM_NO_SENSE;
}
sense_reason_t sense_reason_t
target_cmd_size_check(struct se_cmd *cmd, unsigned int size) target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
{ {
...@@ -1087,9 +1137,9 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) ...@@ -1087,9 +1137,9 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
" 0x%02x\n", cmd->se_tfo->get_fabric_name(), " 0x%02x\n", cmd->se_tfo->get_fabric_name(),
cmd->data_length, size, cmd->t_task_cdb[0]); cmd->data_length, size, cmd->t_task_cdb[0]);
if (cmd->data_direction == DMA_TO_DEVICE) { if (cmd->data_direction == DMA_TO_DEVICE &&
pr_err("Rejecting underflow/overflow" cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) {
" WRITE data\n"); pr_err("Rejecting underflow/overflow WRITE data\n");
return TCM_INVALID_CDB_FIELD; return TCM_INVALID_CDB_FIELD;
} }
/* /*
...@@ -1119,7 +1169,7 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) ...@@ -1119,7 +1169,7 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size)
} }
} }
return 0; return target_check_max_data_sg_nents(cmd, dev, size);
} }
...@@ -1177,14 +1227,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd) ...@@ -1177,14 +1227,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd)
" emulation is not supported\n"); " emulation is not supported\n");
return TCM_INVALID_CDB_FIELD; return TCM_INVALID_CDB_FIELD;
} }
/*
* Used to determine when ORDERED commands should go from
* Dormant to Active status.
*/
cmd->se_ordered_id = atomic_inc_return(&dev->dev_ordered_id);
pr_debug("Allocated se_ordered_id: %u for Task Attr: 0x%02x on %s\n",
cmd->se_ordered_id, cmd->sam_task_attr,
dev->transport->name);
return 0; return 0;
} }
...@@ -1246,6 +1289,11 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb) ...@@ -1246,6 +1289,11 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
} }
ret = dev->transport->parse_cdb(cmd); ret = dev->transport->parse_cdb(cmd);
if (ret == TCM_UNSUPPORTED_SCSI_OPCODE)
pr_warn_ratelimited("%s/%s: Unsupported SCSI Opcode 0x%02x, sending CHECK_CONDITION.\n",
cmd->se_tfo->get_fabric_name(),
cmd->se_sess->se_node_acl->initiatorname,
cmd->t_task_cdb[0]);
if (ret) if (ret)
return ret; return ret;
...@@ -1693,8 +1741,7 @@ void transport_generic_request_failure(struct se_cmd *cmd, ...@@ -1693,8 +1741,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
check_stop: check_stop:
transport_lun_remove_cmd(cmd); transport_lun_remove_cmd(cmd);
if (!transport_cmd_check_stop_to_fabric(cmd)) transport_cmd_check_stop_to_fabric(cmd);
;
return; return;
queue_full: queue_full:
...@@ -1767,16 +1814,14 @@ static bool target_handle_task_attr(struct se_cmd *cmd) ...@@ -1767,16 +1814,14 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
*/ */
switch (cmd->sam_task_attr) { switch (cmd->sam_task_attr) {
case TCM_HEAD_TAG: case TCM_HEAD_TAG:
pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x, " pr_debug("Added HEAD_OF_QUEUE for CDB: 0x%02x\n",
"se_ordered_id: %u\n", cmd->t_task_cdb[0]);
cmd->t_task_cdb[0], cmd->se_ordered_id);
return false; return false;
case TCM_ORDERED_TAG: case TCM_ORDERED_TAG:
atomic_inc_mb(&dev->dev_ordered_sync); atomic_inc_mb(&dev->dev_ordered_sync);
pr_debug("Added ORDERED for CDB: 0x%02x to ordered list, " pr_debug("Added ORDERED for CDB: 0x%02x to ordered list\n",
" se_ordered_id: %u\n", cmd->t_task_cdb[0]);
cmd->t_task_cdb[0], cmd->se_ordered_id);
/* /*
* Execute an ORDERED command if no other older commands * Execute an ORDERED command if no other older commands
...@@ -1800,10 +1845,8 @@ static bool target_handle_task_attr(struct se_cmd *cmd) ...@@ -1800,10 +1845,8 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list); list_add_tail(&cmd->se_delayed_node, &dev->delayed_cmd_list);
spin_unlock(&dev->delayed_cmd_lock); spin_unlock(&dev->delayed_cmd_lock);
pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to" pr_debug("Added CDB: 0x%02x Task Attr: 0x%02x to delayed CMD listn",
" delayed CMD list, se_ordered_id: %u\n", cmd->t_task_cdb[0], cmd->sam_task_attr);
cmd->t_task_cdb[0], cmd->sam_task_attr,
cmd->se_ordered_id);
return true; return true;
} }
...@@ -1888,20 +1931,18 @@ static void transport_complete_task_attr(struct se_cmd *cmd) ...@@ -1888,20 +1931,18 @@ static void transport_complete_task_attr(struct se_cmd *cmd)
if (cmd->sam_task_attr == TCM_SIMPLE_TAG) { if (cmd->sam_task_attr == TCM_SIMPLE_TAG) {
atomic_dec_mb(&dev->simple_cmds); atomic_dec_mb(&dev->simple_cmds);
dev->dev_cur_ordered_id++; dev->dev_cur_ordered_id++;
pr_debug("Incremented dev->dev_cur_ordered_id: %u for" pr_debug("Incremented dev->dev_cur_ordered_id: %u for SIMPLE\n",
" SIMPLE: %u\n", dev->dev_cur_ordered_id, dev->dev_cur_ordered_id);
cmd->se_ordered_id);
} else if (cmd->sam_task_attr == TCM_HEAD_TAG) { } else if (cmd->sam_task_attr == TCM_HEAD_TAG) {
dev->dev_cur_ordered_id++; dev->dev_cur_ordered_id++;
pr_debug("Incremented dev_cur_ordered_id: %u for" pr_debug("Incremented dev_cur_ordered_id: %u for HEAD_OF_QUEUE\n",
" HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, dev->dev_cur_ordered_id);
cmd->se_ordered_id);
} else if (cmd->sam_task_attr == TCM_ORDERED_TAG) { } else if (cmd->sam_task_attr == TCM_ORDERED_TAG) {
atomic_dec_mb(&dev->dev_ordered_sync); atomic_dec_mb(&dev->dev_ordered_sync);
dev->dev_cur_ordered_id++; dev->dev_cur_ordered_id++;
pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED\n",
" %u\n", dev->dev_cur_ordered_id, cmd->se_ordered_id); dev->dev_cur_ordered_id);
} }
target_restart_delayed_cmds(dev); target_restart_delayed_cmds(dev);
...@@ -2615,37 +2656,159 @@ bool transport_wait_for_tasks(struct se_cmd *cmd) ...@@ -2615,37 +2656,159 @@ bool transport_wait_for_tasks(struct se_cmd *cmd)
} }
EXPORT_SYMBOL(transport_wait_for_tasks); EXPORT_SYMBOL(transport_wait_for_tasks);
static int transport_get_sense_codes( struct sense_info {
struct se_cmd *cmd, u8 key;
u8 *asc, u8 asc;
u8 *ascq) u8 ascq;
bool add_sector_info;
};
static const struct sense_info sense_info_table[] = {
[TCM_NO_SENSE] = {
.key = NOT_READY
},
[TCM_NON_EXISTENT_LUN] = {
.key = ILLEGAL_REQUEST,
.asc = 0x25 /* LOGICAL UNIT NOT SUPPORTED */
},
[TCM_UNSUPPORTED_SCSI_OPCODE] = {
.key = ILLEGAL_REQUEST,
.asc = 0x20, /* INVALID COMMAND OPERATION CODE */
},
[TCM_SECTOR_COUNT_TOO_MANY] = {
.key = ILLEGAL_REQUEST,
.asc = 0x20, /* INVALID COMMAND OPERATION CODE */
},
[TCM_UNKNOWN_MODE_PAGE] = {
.key = ILLEGAL_REQUEST,
.asc = 0x24, /* INVALID FIELD IN CDB */
},
[TCM_CHECK_CONDITION_ABORT_CMD] = {
.key = ABORTED_COMMAND,
.asc = 0x29, /* BUS DEVICE RESET FUNCTION OCCURRED */
.ascq = 0x03,
},
[TCM_INCORRECT_AMOUNT_OF_DATA] = {
.key = ABORTED_COMMAND,
.asc = 0x0c, /* WRITE ERROR */
.ascq = 0x0d, /* NOT ENOUGH UNSOLICITED DATA */
},
[TCM_INVALID_CDB_FIELD] = {
.key = ILLEGAL_REQUEST,
.asc = 0x24, /* INVALID FIELD IN CDB */
},
[TCM_INVALID_PARAMETER_LIST] = {
.key = ILLEGAL_REQUEST,
.asc = 0x26, /* INVALID FIELD IN PARAMETER LIST */
},
[TCM_PARAMETER_LIST_LENGTH_ERROR] = {
.key = ILLEGAL_REQUEST,
.asc = 0x1a, /* PARAMETER LIST LENGTH ERROR */
},
[TCM_UNEXPECTED_UNSOLICITED_DATA] = {
.key = ILLEGAL_REQUEST,
.asc = 0x0c, /* WRITE ERROR */
.ascq = 0x0c, /* UNEXPECTED_UNSOLICITED_DATA */
},
[TCM_SERVICE_CRC_ERROR] = {
.key = ABORTED_COMMAND,
.asc = 0x47, /* PROTOCOL SERVICE CRC ERROR */
.ascq = 0x05, /* N/A */
},
[TCM_SNACK_REJECTED] = {
.key = ABORTED_COMMAND,
.asc = 0x11, /* READ ERROR */
.ascq = 0x13, /* FAILED RETRANSMISSION REQUEST */
},
[TCM_WRITE_PROTECTED] = {
.key = DATA_PROTECT,
.asc = 0x27, /* WRITE PROTECTED */
},
[TCM_ADDRESS_OUT_OF_RANGE] = {
.key = ILLEGAL_REQUEST,
.asc = 0x21, /* LOGICAL BLOCK ADDRESS OUT OF RANGE */
},
[TCM_CHECK_CONDITION_UNIT_ATTENTION] = {
.key = UNIT_ATTENTION,
},
[TCM_CHECK_CONDITION_NOT_READY] = {
.key = NOT_READY,
},
[TCM_MISCOMPARE_VERIFY] = {
.key = MISCOMPARE,
.asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */
.ascq = 0x00,
},
[TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = {
.key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x01, /* LOGICAL BLOCK GUARD CHECK FAILED */
.add_sector_info = true,
},
[TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED] = {
.key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x02, /* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
.add_sector_info = true,
},
[TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED] = {
.key = ABORTED_COMMAND,
.asc = 0x10,
.ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
.add_sector_info = true,
},
[TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = {
/*
* Returning ILLEGAL REQUEST would cause immediate IO errors on
* Solaris initiators. Returning NOT READY instead means the
* operations will be retried a finite number of times and we
* can survive intermittent errors.
*/
.key = NOT_READY,
.asc = 0x08, /* LOGICAL UNIT COMMUNICATION FAILURE */
},
};
static int translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
{ {
*asc = cmd->scsi_asc; const struct sense_info *si;
*ascq = cmd->scsi_ascq; u8 *buffer = cmd->sense_buffer;
int r = (__force int)reason;
u8 asc, ascq;
bool desc_format = target_sense_desc_format(cmd->se_dev);
return 0; if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key)
} si = &sense_info_table[r];
else
si = &sense_info_table[(__force int)
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE];
static if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) {
void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector) core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
{ WARN_ON_ONCE(asc == 0);
/* Place failed LBA in sense data information descriptor 0. */ } else if (si->asc == 0) {
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 0xc; WARN_ON_ONCE(cmd->scsi_asc == 0);
buffer[SPC_DESC_TYPE_OFFSET] = 0; /* Information */ asc = cmd->scsi_asc;
buffer[SPC_ADDITIONAL_DESC_LEN_OFFSET] = 0xa; ascq = cmd->scsi_ascq;
buffer[SPC_VALIDITY_OFFSET] = 0x80; } else {
asc = si->asc;
ascq = si->ascq;
}
scsi_build_sense_buffer(desc_format, buffer, si->key, asc, ascq);
if (si->add_sector_info)
return scsi_set_sense_information(buffer,
cmd->scsi_sense_length,
cmd->bad_sector);
/* Descriptor Information: failing sector */ return 0;
put_unaligned_be64(bad_sector, &buffer[12]);
} }
int int
transport_send_check_condition_and_sense(struct se_cmd *cmd, transport_send_check_condition_and_sense(struct se_cmd *cmd,
sense_reason_t reason, int from_transport) sense_reason_t reason, int from_transport)
{ {
unsigned char *buffer = cmd->sense_buffer;
unsigned long flags; unsigned long flags;
u8 asc = 0, ascq = 0;
spin_lock_irqsave(&cmd->t_state_lock, flags); spin_lock_irqsave(&cmd->t_state_lock, flags);
if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) {
...@@ -2655,243 +2818,17 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd, ...@@ -2655,243 +2818,17 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
cmd->se_cmd_flags |= SCF_SENT_CHECK_CONDITION; cmd->se_cmd_flags |= SCF_SENT_CHECK_CONDITION;
spin_unlock_irqrestore(&cmd->t_state_lock, flags); spin_unlock_irqrestore(&cmd->t_state_lock, flags);
if (!reason && from_transport) if (!from_transport) {
goto after_reason; int rc;
if (!from_transport)
cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
/* cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
* Actual SENSE DATA, see SPC-3 7.23.2 SPC_SENSE_KEY_OFFSET uses rc = translate_sense_reason(cmd, reason);
* SENSE KEY values from include/scsi/scsi.h if (rc)
*/ return rc;
switch (reason) {
case TCM_NO_SENSE:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */
buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
/* NO ADDITIONAL SENSE INFORMATION */
buffer[SPC_ASC_KEY_OFFSET] = 0;
buffer[SPC_ASCQ_KEY_OFFSET] = 0;
break;
case TCM_NON_EXISTENT_LUN:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL UNIT NOT SUPPORTED */
buffer[SPC_ASC_KEY_OFFSET] = 0x25;
break;
case TCM_UNSUPPORTED_SCSI_OPCODE:
case TCM_SECTOR_COUNT_TOO_MANY:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID COMMAND OPERATION CODE */
buffer[SPC_ASC_KEY_OFFSET] = 0x20;
break;
case TCM_UNKNOWN_MODE_PAGE:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_CHECK_CONDITION_ABORT_CMD:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* BUS DEVICE RESET FUNCTION OCCURRED */
buffer[SPC_ASC_KEY_OFFSET] = 0x29;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
break;
case TCM_INCORRECT_AMOUNT_OF_DATA:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* NOT ENOUGH UNSOLICITED DATA */
buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d;
break;
case TCM_INVALID_CDB_FIELD:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN CDB */
buffer[SPC_ASC_KEY_OFFSET] = 0x24;
break;
case TCM_INVALID_PARAMETER_LIST:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* INVALID FIELD IN PARAMETER LIST */
buffer[SPC_ASC_KEY_OFFSET] = 0x26;
break;
case TCM_PARAMETER_LIST_LENGTH_ERROR:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* PARAMETER LIST LENGTH ERROR */
buffer[SPC_ASC_KEY_OFFSET] = 0x1a;
break;
case TCM_UNEXPECTED_UNSOLICITED_DATA:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* WRITE ERROR */
buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
/* UNEXPECTED_UNSOLICITED_DATA */
buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c;
break;
case TCM_SERVICE_CRC_ERROR:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* PROTOCOL SERVICE CRC ERROR */
buffer[SPC_ASC_KEY_OFFSET] = 0x47;
/* N/A */
buffer[SPC_ASCQ_KEY_OFFSET] = 0x05;
break;
case TCM_SNACK_REJECTED:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ABORTED COMMAND */
buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
/* READ ERROR */
buffer[SPC_ASC_KEY_OFFSET] = 0x11;
/* FAILED RETRANSMISSION REQUEST */
buffer[SPC_ASCQ_KEY_OFFSET] = 0x13;
break;
case TCM_WRITE_PROTECTED:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* DATA PROTECT */
buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
/* WRITE PROTECTED */
buffer[SPC_ASC_KEY_OFFSET] = 0x27;
break;
case TCM_ADDRESS_OUT_OF_RANGE:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
buffer[SPC_ASC_KEY_OFFSET] = 0x21;
break;
case TCM_CHECK_CONDITION_UNIT_ATTENTION:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* UNIT ATTENTION */
buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
buffer[SPC_ASC_KEY_OFFSET] = asc;
buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_CHECK_CONDITION_NOT_READY:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* Not Ready */
buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
transport_get_sense_codes(cmd, &asc, &ascq);
buffer[SPC_ASC_KEY_OFFSET] = asc;
buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
break;
case TCM_MISCOMPARE_VERIFY:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
buffer[SPC_SENSE_KEY_OFFSET] = MISCOMPARE;
/* MISCOMPARE DURING VERIFY OPERATION */
buffer[SPC_ASC_KEY_OFFSET] = 0x1d;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x00;
break;
case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK GUARD CHECK FAILED */
buffer[SPC_ASC_KEY_OFFSET] = 0x10;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x01;
transport_err_sector_info(buffer, cmd->bad_sector);
break;
case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
buffer[SPC_ASC_KEY_OFFSET] = 0x10;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x02;
transport_err_sector_info(buffer, cmd->bad_sector);
break;
case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/* ILLEGAL REQUEST */
buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
/* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
buffer[SPC_ASC_KEY_OFFSET] = 0x10;
buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
transport_err_sector_info(buffer, cmd->bad_sector);
break;
case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
default:
/* CURRENT ERROR */
buffer[0] = 0x70;
buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
/*
* Returning ILLEGAL REQUEST would cause immediate IO errors on
* Solaris initiators. Returning NOT READY instead means the
* operations will be retried a finite number of times and we
* can survive intermittent errors.
*/
buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
/* LOGICAL UNIT COMMUNICATION FAILURE */
buffer[SPC_ASC_KEY_OFFSET] = 0x08;
break;
} }
/*
* This code uses linux/include/scsi/scsi.h SAM status codes!
*/
cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
/*
* Automatically padded, this value is encoded in the fabric's
* data_length response PDU containing the SCSI defined sense data.
*/
cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
after_reason:
trace_target_cmd_complete(cmd); trace_target_cmd_complete(cmd);
return cmd->se_tfo->queue_status(cmd); return cmd->se_tfo->queue_status(cmd);
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/uio_driver.h> #include <linux/uio_driver.h>
#include <linux/stringify.h>
#include <net/genetlink.h> #include <net/genetlink.h>
#include <scsi/scsi_common.h> #include <scsi/scsi_common.h>
#include <scsi/scsi_proto.h> #include <scsi/scsi_proto.h>
...@@ -538,14 +539,8 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * ...@@ -538,14 +539,8 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
UPDATE_HEAD(udev->data_tail, cmd->data_length, udev->data_size); UPDATE_HEAD(udev->data_tail, cmd->data_length, udev->data_size);
pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n", pr_warn("TCMU: Userspace set UNKNOWN_OP flag on se_cmd %p\n",
cmd->se_cmd); cmd->se_cmd);
transport_generic_request_failure(cmd->se_cmd, entry->rsp.scsi_status = SAM_STAT_CHECK_CONDITION;
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE); } else if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) {
cmd->se_cmd = NULL;
kmem_cache_free(tcmu_cmd_cache, cmd);
return;
}
if (entry->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) {
memcpy(se_cmd->sense_buffer, entry->rsp.sense_buffer, memcpy(se_cmd->sense_buffer, entry->rsp.sense_buffer,
se_cmd->scsi_sense_length); se_cmd->scsi_sense_length);
...@@ -577,7 +572,6 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry * ...@@ -577,7 +572,6 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) static unsigned int tcmu_handle_completions(struct tcmu_dev *udev)
{ {
struct tcmu_mailbox *mb; struct tcmu_mailbox *mb;
LIST_HEAD(cpl_cmds);
unsigned long flags; unsigned long flags;
int handled = 0; int handled = 0;
...@@ -905,7 +899,7 @@ static int tcmu_configure_device(struct se_device *dev) ...@@ -905,7 +899,7 @@ static int tcmu_configure_device(struct se_device *dev)
WARN_ON(!PAGE_ALIGNED(udev->data_off)); WARN_ON(!PAGE_ALIGNED(udev->data_off));
WARN_ON(udev->data_size % PAGE_SIZE); WARN_ON(udev->data_size % PAGE_SIZE);
info->version = xstr(TCMU_MAILBOX_VERSION); info->version = __stringify(TCMU_MAILBOX_VERSION);
info->mem[0].name = "tcm-user command & data buffer"; info->mem[0].name = "tcm-user command & data buffer";
info->mem[0].addr = (phys_addr_t) udev->mb_addr; info->mem[0].addr = (phys_addr_t) udev->mb_addr;
......
...@@ -450,6 +450,8 @@ int target_xcopy_setup_pt(void) ...@@ -450,6 +450,8 @@ int target_xcopy_setup_pt(void)
memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
INIT_LIST_HEAD(&xcopy_pt_sess.sess_list); INIT_LIST_HEAD(&xcopy_pt_sess.sess_list);
INIT_LIST_HEAD(&xcopy_pt_sess.sess_acl_list); INIT_LIST_HEAD(&xcopy_pt_sess.sess_acl_list);
INIT_LIST_HEAD(&xcopy_pt_sess.sess_cmd_list);
spin_lock_init(&xcopy_pt_sess.sess_cmd_lock);
xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
...@@ -644,7 +646,7 @@ static int target_xcopy_read_source( ...@@ -644,7 +646,7 @@ static int target_xcopy_read_source(
pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n",
(unsigned long long)src_lba, src_sectors, length); (unsigned long long)src_lba, src_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]);
xop->src_pt_cmd = xpt_cmd; xop->src_pt_cmd = xpt_cmd;
...@@ -704,7 +706,7 @@ static int target_xcopy_write_destination( ...@@ -704,7 +706,7 @@ static int target_xcopy_write_destination(
pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n",
(unsigned long long)dst_lba, dst_sectors, length); (unsigned long long)dst_lba, dst_sectors, length);
transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length,
DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]);
xop->dst_pt_cmd = xpt_cmd; xop->dst_pt_cmd = xpt_cmd;
......
...@@ -255,7 +255,7 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg) ...@@ -255,7 +255,7 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
struct ft_cmd *cmd = arg; struct ft_cmd *cmd = arg;
struct fc_frame_header *fh; struct fc_frame_header *fh;
if (unlikely(IS_ERR(fp))) { if (IS_ERR(fp)) {
/* XXX need to find cmd if queued */ /* XXX need to find cmd if queued */
cmd->seq = NULL; cmd->seq = NULL;
cmd->aborted = true; cmd->aborted = true;
......
...@@ -61,4 +61,9 @@ static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr) ...@@ -61,4 +61,9 @@ static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr)
extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
struct scsi_sense_hdr *sshdr); struct scsi_sense_hdr *sshdr);
extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info);
extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
int desc_type);
#endif /* _SCSI_COMMON_H_ */ #endif /* _SCSI_COMMON_H_ */
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_common.h>
struct scsi_device; struct scsi_device;
struct Scsi_Host; struct Scsi_Host;
...@@ -21,14 +22,9 @@ static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) ...@@ -21,14 +22,9 @@ static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr)
return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1)); return ((sshdr->response_code >= 0x70) && (sshdr->response_code & 1));
} }
extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
int desc_type);
extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,
u64 * info_out); u64 * info_out);
extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
extern int scsi_ioctl_reset(struct scsi_device *, int __user *); extern int scsi_ioctl_reset(struct scsi_device *, int __user *);
struct scsi_eh_save { struct scsi_eh_save {
......
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
/* T10 protection information disabled by default */ /* T10 protection information disabled by default */
#define TA_DEFAULT_T10_PI 0 #define TA_DEFAULT_T10_PI 0
#define TA_DEFAULT_FABRIC_PROT_TYPE 0 #define TA_DEFAULT_FABRIC_PROT_TYPE 0
/* TPG status needs to be enabled to return sendtargets discovery endpoint info */
#define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1
#define ISCSI_IOV_DATA_BUFFER 5 #define ISCSI_IOV_DATA_BUFFER 5
...@@ -517,7 +519,6 @@ struct iscsi_conn { ...@@ -517,7 +519,6 @@ struct iscsi_conn {
u16 cid; u16 cid;
/* Remote TCP Port */ /* Remote TCP Port */
u16 login_port; u16 login_port;
u16 local_port;
int net_size; int net_size;
int login_family; int login_family;
u32 auth_id; u32 auth_id;
...@@ -527,9 +528,8 @@ struct iscsi_conn { ...@@ -527,9 +528,8 @@ struct iscsi_conn {
u32 exp_statsn; u32 exp_statsn;
/* Per connection status sequence number */ /* Per connection status sequence number */
u32 stat_sn; u32 stat_sn;
#define IPV6_ADDRESS_SPACE 48 struct sockaddr_storage login_sockaddr;
unsigned char login_ip[IPV6_ADDRESS_SPACE]; struct sockaddr_storage local_sockaddr;
unsigned char local_ip[IPV6_ADDRESS_SPACE];
int conn_usage_count; int conn_usage_count;
int conn_waiting_on_uc; int conn_waiting_on_uc;
atomic_t check_immediate_queue; atomic_t check_immediate_queue;
...@@ -636,7 +636,7 @@ struct iscsi_session { ...@@ -636,7 +636,7 @@ struct iscsi_session {
/* session wide counter: expected command sequence number */ /* session wide counter: expected command sequence number */
u32 exp_cmd_sn; u32 exp_cmd_sn;
/* session wide counter: maximum allowed command sequence number */ /* session wide counter: maximum allowed command sequence number */
u32 max_cmd_sn; atomic_t max_cmd_sn;
struct list_head sess_ooo_cmdsn_list; struct list_head sess_ooo_cmdsn_list;
/* LIO specific session ID */ /* LIO specific session ID */
...@@ -764,6 +764,7 @@ struct iscsi_tpg_attrib { ...@@ -764,6 +764,7 @@ struct iscsi_tpg_attrib {
u32 default_erl; u32 default_erl;
u8 t10_pi; u8 t10_pi;
u32 fabric_prot_type; u32 fabric_prot_type;
u32 tpg_enabled_sendtargets;
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
}; };
...@@ -776,12 +777,10 @@ struct iscsi_np { ...@@ -776,12 +777,10 @@ struct iscsi_np {
enum iscsi_timer_flags_table np_login_timer_flags; enum iscsi_timer_flags_table np_login_timer_flags;
u32 np_exports; u32 np_exports;
enum np_flags_table np_flags; enum np_flags_table np_flags;
unsigned char np_ip[IPV6_ADDRESS_SPACE];
u16 np_port;
spinlock_t np_thread_lock; spinlock_t np_thread_lock;
struct completion np_restart_comp; struct completion np_restart_comp;
struct socket *np_socket; struct socket *np_socket;
struct __kernel_sockaddr_storage np_sockaddr; struct sockaddr_storage np_sockaddr;
struct task_struct *np_thread; struct task_struct *np_thread;
struct timer_list np_login_timer; struct timer_list np_login_timer;
void *np_context; void *np_context;
......
...@@ -50,7 +50,7 @@ struct iscsi_login_stats { ...@@ -50,7 +50,7 @@ struct iscsi_login_stats {
u64 last_fail_time; /* time stamp (jiffies) */ u64 last_fail_time; /* time stamp (jiffies) */
u32 last_fail_type; u32 last_fail_type;
int last_intr_fail_ip_family; int last_intr_fail_ip_family;
unsigned char last_intr_fail_ip_addr[IPV6_ADDRESS_SPACE]; struct sockaddr_storage last_intr_fail_sockaddr;
char last_intr_fail_name[224]; char last_intr_fail_name[224];
} ____cacheline_aligned; } ____cacheline_aligned;
......
...@@ -9,7 +9,7 @@ struct iscsit_transport { ...@@ -9,7 +9,7 @@ struct iscsit_transport {
int priv_size; int priv_size;
struct module *owner; struct module *owner;
struct list_head t_node; struct list_head t_node;
int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); int (*iscsit_setup_np)(struct iscsi_np *, struct sockaddr_storage *);
int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *);
void (*iscsit_free_np)(struct iscsi_np *); void (*iscsit_free_np)(struct iscsi_np *);
void (*iscsit_wait_conn)(struct iscsi_conn *); void (*iscsit_wait_conn)(struct iscsi_conn *);
......
...@@ -93,4 +93,6 @@ bool target_lun_is_rdonly(struct se_cmd *); ...@@ -93,4 +93,6 @@ bool target_lun_is_rdonly(struct se_cmd *);
sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd, sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd,
sense_reason_t (*exec_cmd)(struct se_cmd *cmd)); sense_reason_t (*exec_cmd)(struct se_cmd *cmd));
bool target_sense_desc_format(struct se_device *dev);
#endif /* TARGET_CORE_BACKEND_H */ #endif /* TARGET_CORE_BACKEND_H */
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/percpu_ida.h> #include <linux/percpu_ida.h>
#include <linux/t10-pi.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
...@@ -426,12 +427,6 @@ enum target_core_dif_check { ...@@ -426,12 +427,6 @@ enum target_core_dif_check {
TARGET_DIF_CHECK_REFTAG = 0x1 << 2, TARGET_DIF_CHECK_REFTAG = 0x1 << 2,
}; };
struct se_dif_v1_tuple {
__be16 guard_tag;
__be16 app_tag;
__be32 ref_tag;
};
/* for sam_task_attr */ /* for sam_task_attr */
#define TCM_SIMPLE_TAG 0x20 #define TCM_SIMPLE_TAG 0x20
#define TCM_HEAD_TAG 0x21 #define TCM_HEAD_TAG 0x21
...@@ -444,6 +439,9 @@ struct se_cmd { ...@@ -444,6 +439,9 @@ struct se_cmd {
u8 scsi_asc; u8 scsi_asc;
u8 scsi_ascq; u8 scsi_ascq;
u16 scsi_sense_length; u16 scsi_sense_length;
unsigned cmd_wait_set:1;
unsigned unknown_data_length:1;
bool state_active:1;
u64 tag; /* SAM command identifier aka task tag */ u64 tag; /* SAM command identifier aka task tag */
/* Delay for ALUA Active/NonOptimized state access in milliseconds */ /* Delay for ALUA Active/NonOptimized state access in milliseconds */
int alua_nonop_delay; int alua_nonop_delay;
...@@ -455,11 +453,8 @@ struct se_cmd { ...@@ -455,11 +453,8 @@ struct se_cmd {
unsigned int map_tag; unsigned int map_tag;
/* Transport protocol dependent state, see transport_state_table */ /* Transport protocol dependent state, see transport_state_table */
enum transport_state_table t_state; enum transport_state_table t_state;
unsigned cmd_wait_set:1;
unsigned unknown_data_length:1;
/* See se_cmd_flags_table */ /* See se_cmd_flags_table */
u32 se_cmd_flags; u32 se_cmd_flags;
u32 se_ordered_id;
/* Total size in bytes associated with command */ /* Total size in bytes associated with command */
u32 data_length; u32 data_length;
u32 residual_count; u32 residual_count;
...@@ -477,7 +472,6 @@ struct se_cmd { ...@@ -477,7 +472,6 @@ struct se_cmd {
struct se_tmr_req *se_tmr_req; struct se_tmr_req *se_tmr_req;
struct list_head se_cmd_list; struct list_head se_cmd_list;
struct completion cmd_wait_comp; struct completion cmd_wait_comp;
struct kref cmd_kref;
const struct target_core_fabric_ops *se_tfo; const struct target_core_fabric_ops *se_tfo;
sense_reason_t (*execute_cmd)(struct se_cmd *); sense_reason_t (*execute_cmd)(struct se_cmd *);
sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool); sense_reason_t (*transport_complete_callback)(struct se_cmd *, bool);
...@@ -497,6 +491,7 @@ struct se_cmd { ...@@ -497,6 +491,7 @@ struct se_cmd {
#define CMD_T_REQUEST_STOP (1 << 8) #define CMD_T_REQUEST_STOP (1 << 8)
#define CMD_T_BUSY (1 << 9) #define CMD_T_BUSY (1 << 9)
spinlock_t t_state_lock; spinlock_t t_state_lock;
struct kref cmd_kref;
struct completion t_transport_stop_comp; struct completion t_transport_stop_comp;
struct work_struct work; struct work_struct work;
...@@ -509,8 +504,10 @@ struct se_cmd { ...@@ -509,8 +504,10 @@ struct se_cmd {
struct scatterlist *t_bidi_data_sg; struct scatterlist *t_bidi_data_sg;
unsigned int t_bidi_data_nents; unsigned int t_bidi_data_nents;
/* Used for lun->lun_ref counting */
int lun_ref_active;
struct list_head state_list; struct list_head state_list;
bool state_active;
/* old task stop completion, consider merging with some of the above */ /* old task stop completion, consider merging with some of the above */
struct completion task_stop_comp; struct completion task_stop_comp;
...@@ -518,20 +515,17 @@ struct se_cmd { ...@@ -518,20 +515,17 @@ struct se_cmd {
/* backend private data */ /* backend private data */
void *priv; void *priv;
/* Used for lun->lun_ref counting */
int lun_ref_active;
/* DIF related members */ /* DIF related members */
enum target_prot_op prot_op; enum target_prot_op prot_op;
enum target_prot_type prot_type; enum target_prot_type prot_type;
u8 prot_checks; u8 prot_checks;
bool prot_pto;
u32 prot_length; u32 prot_length;
u32 reftag_seed; u32 reftag_seed;
struct scatterlist *t_prot_sg; struct scatterlist *t_prot_sg;
unsigned int t_prot_nents; unsigned int t_prot_nents;
sense_reason_t pi_err; sense_reason_t pi_err;
sector_t bad_sector; sector_t bad_sector;
bool prot_pto;
}; };
struct se_ua { struct se_ua {
...@@ -598,7 +592,6 @@ struct se_ml_stat_grps { ...@@ -598,7 +592,6 @@ struct se_ml_stat_grps {
}; };
struct se_lun_acl { struct se_lun_acl {
char initiatorname[TRANSPORT_IQN_LEN];
u64 mapped_lun; u64 mapped_lun;
struct se_node_acl *se_lun_nacl; struct se_node_acl *se_lun_nacl;
struct se_lun *se_lun; struct se_lun *se_lun;
...@@ -685,7 +678,6 @@ struct se_lun { ...@@ -685,7 +678,6 @@ struct se_lun {
#define SE_LUN_LINK_MAGIC 0xffff7771 #define SE_LUN_LINK_MAGIC 0xffff7771
u32 lun_link_magic; u32 lun_link_magic;
u32 lun_access; u32 lun_access;
u32 lun_flags;
u32 lun_index; u32 lun_index;
/* RELATIVE TARGET PORT IDENTIFER */ /* RELATIVE TARGET PORT IDENTIFER */
...@@ -751,7 +743,6 @@ struct se_device { ...@@ -751,7 +743,6 @@ struct se_device {
atomic_long_t write_bytes; atomic_long_t write_bytes;
/* Active commands on this virtual SE device */ /* Active commands on this virtual SE device */
atomic_t simple_cmds; atomic_t simple_cmds;
atomic_t dev_ordered_id;
atomic_t dev_ordered_sync; atomic_t dev_ordered_sync;
atomic_t dev_qf_count; atomic_t dev_qf_count;
u32 export_count; u32 export_count;
......
...@@ -5,6 +5,19 @@ struct target_core_fabric_ops { ...@@ -5,6 +5,19 @@ struct target_core_fabric_ops {
struct module *module; struct module *module;
const char *name; const char *name;
size_t node_acl_size; size_t node_acl_size;
/*
* Limits number of scatterlist entries per SCF_SCSI_DATA_CDB payload.
* Setting this value tells target-core to enforce this limit, and
* report as INQUIRY EVPD=b0 MAXIMUM TRANSFER LENGTH.
*
* target-core will currently reset se_cmd->data_length to this
* maximum size, and set UNDERFLOW residual count if length exceeds
* this limit.
*
* XXX: Not all initiator hosts honor this block-limit EVPD
* XXX: Currently assumes single PAGE_SIZE per scatterlist entry
*/
u32 max_data_sg_nents;
char *(*get_fabric_name)(void); char *(*get_fabric_name)(void);
char *(*tpg_get_wwn)(struct se_portal_group *); char *(*tpg_get_wwn)(struct se_portal_group *);
u16 (*tpg_get_tag)(struct se_portal_group *); u16 (*tpg_get_tag)(struct se_portal_group *);
...@@ -152,6 +165,7 @@ int transport_generic_handle_tmr(struct se_cmd *); ...@@ -152,6 +165,7 @@ int transport_generic_handle_tmr(struct se_cmd *);
void transport_generic_request_failure(struct se_cmd *, sense_reason_t); void transport_generic_request_failure(struct se_cmd *, sense_reason_t);
void __target_execute_cmd(struct se_cmd *); void __target_execute_cmd(struct se_cmd *);
int transport_lookup_tmr_lun(struct se_cmd *, u64); int transport_lookup_tmr_lun(struct se_cmd *, u64);
void core_allocate_nexus_loss_ua(struct se_node_acl *acl);
struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg, struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg,
unsigned char *); unsigned char *);
......
...@@ -42,10 +42,6 @@ ...@@ -42,10 +42,6 @@
#define TCMU_MAILBOX_VERSION 2 #define TCMU_MAILBOX_VERSION 2
#define ALIGN_SIZE 64 /* Should be enough for most CPUs */ #define ALIGN_SIZE 64 /* Should be enough for most CPUs */
/* See https://gcc.gnu.org/onlinedocs/cpp/Stringification.html */
#define xstr(s) str(s)
#define str(s) #s
struct tcmu_mailbox { struct tcmu_mailbox {
__u16 version; __u16 version;
__u16 flags; __u16 flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment