You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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
...
This commit is contained in:
@@ -269,14 +269,14 @@ int iscsit_deaccess_np(struct iscsi_np *np, struct iscsi_portal_group *tpg,
|
||||
}
|
||||
|
||||
bool iscsit_check_np_match(
|
||||
struct __kernel_sockaddr_storage *sockaddr,
|
||||
struct sockaddr_storage *sockaddr,
|
||||
struct iscsi_np *np,
|
||||
int network_transport)
|
||||
{
|
||||
struct sockaddr_in *sock_in, *sock_in_e;
|
||||
struct sockaddr_in6 *sock_in6, *sock_in6_e;
|
||||
bool ip_match = false;
|
||||
u16 port;
|
||||
u16 port, port_e;
|
||||
|
||||
if (sockaddr->ss_family == AF_INET6) {
|
||||
sock_in6 = (struct sockaddr_in6 *)sockaddr;
|
||||
@@ -288,6 +288,7 @@ bool iscsit_check_np_match(
|
||||
ip_match = true;
|
||||
|
||||
port = ntohs(sock_in6->sin6_port);
|
||||
port_e = ntohs(sock_in6_e->sin6_port);
|
||||
} else {
|
||||
sock_in = (struct sockaddr_in *)sockaddr;
|
||||
sock_in_e = (struct sockaddr_in *)&np->np_sockaddr;
|
||||
@@ -296,9 +297,10 @@ bool iscsit_check_np_match(
|
||||
ip_match = true;
|
||||
|
||||
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))
|
||||
return true;
|
||||
|
||||
@@ -309,7 +311,7 @@ bool iscsit_check_np_match(
|
||||
* Called with mutex np_lock held
|
||||
*/
|
||||
static struct iscsi_np *iscsit_get_np(
|
||||
struct __kernel_sockaddr_storage *sockaddr,
|
||||
struct sockaddr_storage *sockaddr,
|
||||
int network_transport)
|
||||
{
|
||||
struct iscsi_np *np;
|
||||
@@ -340,12 +342,9 @@ static struct iscsi_np *iscsit_get_np(
|
||||
}
|
||||
|
||||
struct iscsi_np *iscsit_add_np(
|
||||
struct __kernel_sockaddr_storage *sockaddr,
|
||||
char *ip_str,
|
||||
struct sockaddr_storage *sockaddr,
|
||||
int network_transport)
|
||||
{
|
||||
struct sockaddr_in *sock_in;
|
||||
struct sockaddr_in6 *sock_in6;
|
||||
struct iscsi_np *np;
|
||||
int ret;
|
||||
|
||||
@@ -368,16 +367,6 @@ struct iscsi_np *iscsit_add_np(
|
||||
}
|
||||
|
||||
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;
|
||||
spin_lock_init(&np->np_thread_lock);
|
||||
init_completion(&np->np_restart_comp);
|
||||
@@ -411,8 +400,8 @@ struct iscsi_np *iscsit_add_np(
|
||||
list_add_tail(&np->np_list, &g_np_list);
|
||||
mutex_unlock(&np_lock);
|
||||
|
||||
pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n",
|
||||
np->np_ip, np->np_port, np->np_transport->name);
|
||||
pr_debug("CORE[0] - Added Network Portal: %pISpc on %s\n",
|
||||
&np->np_sockaddr, np->np_transport->name);
|
||||
|
||||
return np;
|
||||
}
|
||||
@@ -481,8 +470,8 @@ int iscsit_del_np(struct iscsi_np *np)
|
||||
list_del(&np->np_list);
|
||||
mutex_unlock(&np_lock);
|
||||
|
||||
pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n",
|
||||
np->np_ip, np->np_port, np->np_transport->name);
|
||||
pr_debug("CORE[0] - Removed Network Portal: %pISpc on %s\n",
|
||||
&np->np_sockaddr, np->np_transport->name);
|
||||
|
||||
iscsit_put_transport(np->np_transport);
|
||||
kfree(np);
|
||||
@@ -1209,7 +1198,6 @@ static u32 iscsit_do_crypto_hash_sg(
|
||||
u8 *pad_bytes)
|
||||
{
|
||||
u32 data_crc;
|
||||
u32 i;
|
||||
struct scatterlist *sg;
|
||||
unsigned int page_off;
|
||||
|
||||
@@ -1218,15 +1206,15 @@ static u32 iscsit_do_crypto_hash_sg(
|
||||
sg = cmd->first_data_sg;
|
||||
page_off = cmd->first_data_sg_off;
|
||||
|
||||
i = 0;
|
||||
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;
|
||||
page_off = 0;
|
||||
i++;
|
||||
/* iscsit_map_iovec has already checked for invalid sg pointers */
|
||||
sg = sg_next(sg);
|
||||
}
|
||||
|
||||
if (padding) {
|
||||
@@ -2556,7 +2544,7 @@ static int iscsit_send_conn_drop_async_message(
|
||||
cmd->stat_sn = conn->stat_sn++;
|
||||
hdr->statsn = cpu_to_be32(cmd->stat_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->param1 = cpu_to_be16(cmd->logout_cid);
|
||||
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,
|
||||
hdr->statsn = cpu_to_be32(0xFFFFFFFF);
|
||||
|
||||
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->offset = cpu_to_be32(datain->offset);
|
||||
|
||||
@@ -2839,7 +2827,7 @@ iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
|
||||
|
||||
iscsit_increment_maxcmdsn(cmd, conn->sess);
|
||||
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:"
|
||||
" 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,
|
||||
iscsit_increment_maxcmdsn(cmd, conn->sess);
|
||||
|
||||
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,"
|
||||
" StatSN: 0x%08x, Length %u\n", (nopout_response) ?
|
||||
@@ -3049,7 +3037,7 @@ static int iscsit_send_r2t(
|
||||
hdr->ttt = cpu_to_be32(r2t->targ_xfer_tag);
|
||||
hdr->statsn = cpu_to_be32(conn->stat_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->data_offset = cpu_to_be32(r2t->offset);
|
||||
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,
|
||||
|
||||
iscsit_increment_maxcmdsn(cmd, conn->sess);
|
||||
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,"
|
||||
" 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,
|
||||
|
||||
iscsit_increment_maxcmdsn(cmd, conn->sess);
|
||||
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,"
|
||||
" StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
|
||||
@@ -3399,6 +3387,7 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
|
||||
int target_name_printed;
|
||||
unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */
|
||||
unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL;
|
||||
bool active;
|
||||
|
||||
buffer_len = min(conn->conn_ops->MaxRecvDataSegmentLength,
|
||||
SENDTARGETS_BUF_LIMIT);
|
||||
@@ -3452,19 +3441,18 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
|
||||
}
|
||||
|
||||
spin_lock(&tpg->tpg_state_lock);
|
||||
if ((tpg->tpg_state == TPG_STATE_FREE) ||
|
||||
(tpg->tpg_state == TPG_STATE_INACTIVE)) {
|
||||
spin_unlock(&tpg->tpg_state_lock);
|
||||
continue;
|
||||
}
|
||||
active = (tpg->tpg_state == TPG_STATE_ACTIVE);
|
||||
spin_unlock(&tpg->tpg_state_lock);
|
||||
|
||||
if (!active && tpg->tpg_attrib.tpg_enabled_sendtargets)
|
||||
continue;
|
||||
|
||||
spin_lock(&tpg->tpg_np_lock);
|
||||
list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
|
||||
tpg_np_list) {
|
||||
struct iscsi_np *np = tpg_np->tpg_np;
|
||||
bool inaddr_any = iscsit_check_inaddr_any(np);
|
||||
char *fmt_str;
|
||||
struct sockaddr_storage *sockaddr;
|
||||
|
||||
if (np->np_network_transport != network_transport)
|
||||
continue;
|
||||
@@ -3492,15 +3480,15 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
if (np->np_sockaddr.ss_family == AF_INET6)
|
||||
fmt_str = "TargetAddress=[%s]:%hu,%hu";
|
||||
if (inaddr_any)
|
||||
sockaddr = &conn->local_sockaddr;
|
||||
else
|
||||
fmt_str = "TargetAddress=%s:%hu,%hu";
|
||||
sockaddr = &np->np_sockaddr;
|
||||
|
||||
len = sprintf(buf, fmt_str,
|
||||
inaddr_any ? conn->local_ip : np->np_ip,
|
||||
np->np_port,
|
||||
tpg->tpgt);
|
||||
len = sprintf(buf, "TargetAddress="
|
||||
"%pISpc,%hu",
|
||||
sockaddr,
|
||||
tpg->tpgt);
|
||||
len += 1;
|
||||
|
||||
if ((len + payload_len) > buffer_len) {
|
||||
@@ -3576,7 +3564,7 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
|
||||
*/
|
||||
cmd->maxcmdsn_inc = 0;
|
||||
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,"
|
||||
" 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,
|
||||
cmd->stat_sn = conn->stat_sn++;
|
||||
hdr->statsn = cpu_to_be32(cmd->stat_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);
|
||||
|
||||
@@ -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 int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *,
|
||||
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);
|
||||
extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *,
|
||||
char *, int);
|
||||
extern struct iscsi_np *iscsit_add_np(struct sockaddr_storage *,
|
||||
int);
|
||||
extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
|
||||
struct iscsi_portal_group *, bool);
|
||||
extern int iscsit_del_np(struct iscsi_np *);
|
||||
|
||||
@@ -99,7 +99,7 @@ static ssize_t lio_target_np_store_sctp(
|
||||
* Use existing np->np_sockaddr for SCTP network portal reference
|
||||
*/
|
||||
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))
|
||||
goto out;
|
||||
} else {
|
||||
@@ -177,7 +177,7 @@ static ssize_t lio_target_np_store_iser(
|
||||
}
|
||||
|
||||
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)) {
|
||||
rc = PTR_ERR(tpg_np_iser);
|
||||
goto out;
|
||||
@@ -220,7 +220,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
|
||||
struct iscsi_portal_group *tpg;
|
||||
struct iscsi_tpg_np *tpg_np;
|
||||
char *str, *str2, *ip_str, *port_str;
|
||||
struct __kernel_sockaddr_storage sockaddr;
|
||||
struct sockaddr_storage sockaddr;
|
||||
struct sockaddr_in *sock_in;
|
||||
struct sockaddr_in6 *sock_in6;
|
||||
unsigned long port;
|
||||
@@ -235,7 +235,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
|
||||
memset(buf, 0, MAX_PORTAL_LEN + 1);
|
||||
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, "[");
|
||||
if (str) {
|
||||
@@ -248,8 +248,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
str++; /* Skip over leading "[" */
|
||||
*str2 = '\0'; /* Terminate the IPv6 address */
|
||||
str2++; /* Skip over the "]" */
|
||||
*str2 = '\0'; /* Terminate the unbracketed IPv6 address */
|
||||
str2++; /* Skip over the \0 */
|
||||
port_str = strstr(str2, ":");
|
||||
if (!port_str) {
|
||||
pr_err("Unable to locate \":port\""
|
||||
@@ -267,7 +267,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
|
||||
sock_in6 = (struct sockaddr_in6 *)&sockaddr;
|
||||
sock_in6->sin6_family = AF_INET6;
|
||||
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);
|
||||
if (ret <= 0) {
|
||||
pr_err("in6_pton returned: %d\n", ret);
|
||||
@@ -316,7 +316,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg(
|
||||
* 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);
|
||||
if (IS_ERR(tpg_np)) {
|
||||
iscsit_put_tpg(tpg);
|
||||
@@ -344,8 +344,8 @@ static void lio_target_call_delnpfromtpg(
|
||||
|
||||
se_tpg = &tpg->tpg_se_tpg;
|
||||
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),
|
||||
tpg->tpgt, tpg_np->tpg_np->np_ip, tpg_np->tpg_np->np_port);
|
||||
" PORTAL: %pISpc\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item),
|
||||
tpg->tpgt, &tpg_np->tpg_np->np_sockaddr);
|
||||
|
||||
ret = iscsit_tpg_del_network_portal(tpg, tpg_np);
|
||||
if (ret < 0)
|
||||
@@ -656,6 +656,7 @@ static ssize_t lio_target_nacl_show_info(
|
||||
struct iscsi_conn *conn;
|
||||
struct se_session *se_sess;
|
||||
ssize_t rb = 0;
|
||||
u32 max_cmd_sn;
|
||||
|
||||
spin_lock_bh(&se_nacl->nacl_sess_lock);
|
||||
se_sess = se_nacl->nacl_sess;
|
||||
@@ -703,11 +704,12 @@ static ssize_t lio_target_nacl_show_info(
|
||||
" Values]-----------------------\n");
|
||||
rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN"
|
||||
" : 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"
|
||||
" 0x%08x 0x%08x\n",
|
||||
sess->cmdsn_window,
|
||||
(sess->max_cmd_sn - sess->exp_cmd_sn) + 1,
|
||||
sess->exp_cmd_sn, sess->max_cmd_sn,
|
||||
(max_cmd_sn - sess->exp_cmd_sn) + 1,
|
||||
sess->exp_cmd_sn, max_cmd_sn,
|
||||
sess->init_task_tag, sess->targ_xfer_tag);
|
||||
rb += sprintf(page+rb, "----------------------[iSCSI"
|
||||
" Connections]-------------------------\n");
|
||||
@@ -751,7 +753,7 @@ static ssize_t lio_target_nacl_show_info(
|
||||
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) ?
|
||||
"TCP" : "SCTP");
|
||||
rb += sprintf(page+rb, " StatSN: 0x%08x\n",
|
||||
@@ -1010,6 +1012,11 @@ TPG_ATTR(t10_pi, S_IRUGO | S_IWUSR);
|
||||
*/
|
||||
DEF_TPG_ATTRIB(fabric_prot_type);
|
||||
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[] = {
|
||||
&iscsi_tpg_attrib_authentication.attr,
|
||||
@@ -1024,6 +1031,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
|
||||
&iscsi_tpg_attrib_default_erl.attr,
|
||||
&iscsi_tpg_attrib_t10_pi.attr,
|
||||
&iscsi_tpg_attrib_fabric_prot_type.attr,
|
||||
&iscsi_tpg_attrib_tpg_enabled_sendtargets.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
@@ -47,19 +47,19 @@ void iscsit_determine_maxcmdsn(struct iscsi_session *sess)
|
||||
* core_set_queue_depth_for_node().
|
||||
*/
|
||||
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)
|
||||
{
|
||||
u32 max_cmd_sn;
|
||||
|
||||
if (cmd->immediate_cmd || cmd->maxcmdsn_inc)
|
||||
return;
|
||||
|
||||
cmd->maxcmdsn_inc = 1;
|
||||
|
||||
mutex_lock(&sess->cmdsn_mutex);
|
||||
sess->max_cmd_sn += 1;
|
||||
pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
|
||||
mutex_unlock(&sess->cmdsn_mutex);
|
||||
max_cmd_sn = atomic_inc_return(&sess->max_cmd_sn);
|
||||
pr_debug("Updated MaxCmdSN to 0x%08x\n", max_cmd_sn);
|
||||
}
|
||||
EXPORT_SYMBOL(iscsit_increment_maxcmdsn);
|
||||
|
||||
@@ -331,7 +331,7 @@ static int iscsi_login_zero_tsih_s1(
|
||||
* The FFP CmdSN window values will be allocated from the TPG's
|
||||
* 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);
|
||||
if (!sess->sess_ops) {
|
||||
@@ -729,9 +729,9 @@ void iscsi_post_login_handler(
|
||||
stop_timer = 1;
|
||||
}
|
||||
|
||||
pr_debug("iSCSI Login successful on CID: %hu from %s to"
|
||||
" %s:%hu,%hu\n", conn->cid, conn->login_ip,
|
||||
conn->local_ip, conn->local_port, tpg->tpgt);
|
||||
pr_debug("iSCSI Login successful on CID: %hu from %pISpc to"
|
||||
" %pISpc,%hu\n", conn->cid, &conn->login_sockaddr,
|
||||
&conn->local_sockaddr, tpg->tpgt);
|
||||
|
||||
list_add_tail(&conn->conn_list, &sess->sess_conn_list);
|
||||
atomic_inc(&sess->nconn);
|
||||
@@ -776,8 +776,8 @@ void iscsi_post_login_handler(
|
||||
pr_debug("Moving to TARG_SESS_STATE_LOGGED_IN.\n");
|
||||
sess->session_state = TARG_SESS_STATE_LOGGED_IN;
|
||||
|
||||
pr_debug("iSCSI Login successful on CID: %hu from %s to %s:%hu,%hu\n",
|
||||
conn->cid, conn->login_ip, conn->local_ip, conn->local_port,
|
||||
pr_debug("iSCSI Login successful on CID: %hu from %pISpc to %pISpc,%hu\n",
|
||||
conn->cid, &conn->login_sockaddr, &conn->local_sockaddr,
|
||||
tpg->tpgt);
|
||||
|
||||
spin_lock_bh(&sess->conn_lock);
|
||||
@@ -823,8 +823,8 @@ static void iscsi_handle_login_thread_timeout(unsigned long data)
|
||||
struct iscsi_np *np = (struct iscsi_np *) data;
|
||||
|
||||
spin_lock_bh(&np->np_thread_lock);
|
||||
pr_err("iSCSI Login timeout on Network Portal %s:%hu\n",
|
||||
np->np_ip, np->np_port);
|
||||
pr_err("iSCSI Login timeout on Network Portal %pISpc\n",
|
||||
&np->np_sockaddr);
|
||||
|
||||
if (np->np_login_timer_flags & ISCSI_TF_STOP) {
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
@@ -877,7 +877,7 @@ static void iscsi_stop_login_thread_timer(struct iscsi_np *np)
|
||||
|
||||
int iscsit_setup_np(
|
||||
struct iscsi_np *np,
|
||||
struct __kernel_sockaddr_storage *sockaddr)
|
||||
struct sockaddr_storage *sockaddr)
|
||||
{
|
||||
struct socket *sock = NULL;
|
||||
int backlog = ISCSIT_TCP_BACKLOG, ret, opt = 0, len;
|
||||
@@ -916,7 +916,7 @@ int iscsit_setup_np(
|
||||
* in iscsi_target_configfs.c code..
|
||||
*/
|
||||
memcpy(&np->np_sockaddr, sockaddr,
|
||||
sizeof(struct __kernel_sockaddr_storage));
|
||||
sizeof(struct sockaddr_storage));
|
||||
|
||||
if (sockaddr->ss_family == AF_INET6)
|
||||
len = sizeof(struct sockaddr_in6);
|
||||
@@ -975,7 +975,7 @@ fail:
|
||||
|
||||
int iscsi_target_setup_login_socket(
|
||||
struct iscsi_np *np,
|
||||
struct __kernel_sockaddr_storage *sockaddr)
|
||||
struct sockaddr_storage *sockaddr)
|
||||
{
|
||||
struct iscsit_transport *t;
|
||||
int rc;
|
||||
@@ -1015,44 +1015,42 @@ int iscsit_accept_np(struct iscsi_np *np, struct iscsi_conn *conn)
|
||||
rc = conn->sock->ops->getname(conn->sock,
|
||||
(struct sockaddr *)&sock_in6, &err, 1);
|
||||
if (!rc) {
|
||||
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr))
|
||||
snprintf(conn->login_ip, sizeof(conn->login_ip), "[%pI6c]",
|
||||
&sock_in6.sin6_addr.in6_u);
|
||||
else
|
||||
snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI4",
|
||||
&sock_in6.sin6_addr.s6_addr32[3]);
|
||||
conn->login_port = ntohs(sock_in6.sin6_port);
|
||||
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
|
||||
memcpy(&conn->login_sockaddr, &sock_in6, sizeof(sock_in6));
|
||||
} else {
|
||||
/* Pretend to be an ipv4 socket */
|
||||
sock_in.sin_family = AF_INET;
|
||||
sock_in.sin_port = 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,
|
||||
(struct sockaddr *)&sock_in6, &err, 0);
|
||||
if (!rc) {
|
||||
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr))
|
||||
snprintf(conn->local_ip, sizeof(conn->local_ip), "[%pI6c]",
|
||||
&sock_in6.sin6_addr.in6_u);
|
||||
else
|
||||
snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI4",
|
||||
&sock_in6.sin6_addr.s6_addr32[3]);
|
||||
conn->local_port = ntohs(sock_in6.sin6_port);
|
||||
if (!ipv6_addr_v4mapped(&sock_in6.sin6_addr)) {
|
||||
memcpy(&conn->local_sockaddr, &sock_in6, sizeof(sock_in6));
|
||||
} else {
|
||||
/* Pretend to be an ipv4 socket */
|
||||
sock_in.sin_family = AF_INET;
|
||||
sock_in.sin_port = 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 {
|
||||
memset(&sock_in, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
rc = conn->sock->ops->getname(conn->sock,
|
||||
(struct sockaddr *)&sock_in, &err, 1);
|
||||
if (!rc) {
|
||||
sprintf(conn->login_ip, "%pI4",
|
||||
&sock_in.sin_addr.s_addr);
|
||||
conn->login_port = ntohs(sock_in.sin_port);
|
||||
}
|
||||
if (!rc)
|
||||
memcpy(&conn->login_sockaddr, &sock_in, sizeof(sock_in));
|
||||
|
||||
rc = conn->sock->ops->getname(conn->sock,
|
||||
(struct sockaddr *)&sock_in, &err, 0);
|
||||
if (!rc) {
|
||||
sprintf(conn->local_ip, "%pI4",
|
||||
&sock_in.sin_addr.s_addr);
|
||||
conn->local_port = ntohs(sock_in.sin_port);
|
||||
}
|
||||
if (!rc)
|
||||
memcpy(&conn->local_sockaddr, &sock_in, sizeof(sock_in));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1302,8 +1300,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
|
||||
spin_lock_bh(&np->np_thread_lock);
|
||||
if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) {
|
||||
spin_unlock_bh(&np->np_thread_lock);
|
||||
pr_err("iSCSI Network Portal on %s:%hu currently not"
|
||||
" active.\n", np->np_ip, np->np_port);
|
||||
pr_err("iSCSI Network Portal on %pISpc currently not"
|
||||
" active.\n", &np->np_sockaddr);
|
||||
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
|
||||
ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE);
|
||||
goto new_sess_out;
|
||||
@@ -1312,9 +1310,9 @@ static int __iscsi_target_login_thread(struct iscsi_np *np)
|
||||
|
||||
conn->network_transport = np->np_network_transport;
|
||||
|
||||
pr_debug("Received iSCSI login request from %s on %s Network"
|
||||
" Portal %s:%hu\n", conn->login_ip, np->np_transport->name,
|
||||
conn->local_ip, conn->local_port);
|
||||
pr_debug("Received iSCSI login request from %pISpc on %s Network"
|
||||
" Portal %pISpc\n", &conn->login_sockaddr, np->np_transport->name,
|
||||
&conn->local_sockaddr);
|
||||
|
||||
pr_debug("Moving to TARG_CONN_STATE_IN_LOGIN.\n");
|
||||
conn->conn_state = TARG_CONN_STATE_IN_LOGIN;
|
||||
|
||||
@@ -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_login_post_auth_non_zero_tsih(struct iscsi_conn *, u16, u32);
|
||||
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 *,
|
||||
struct __kernel_sockaddr_storage *);
|
||||
struct sockaddr_storage *);
|
||||
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_put_login_tx(struct iscsi_conn *, struct iscsi_login *, u32);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
u32 padding = 0;
|
||||
struct iscsi_session *sess = conn->sess;
|
||||
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
|
||||
login_rsp->itt = login->init_task_tag;
|
||||
login_rsp->statsn = cpu_to_be32(conn->stat_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,"
|
||||
" 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
|
||||
goto err;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -430,7 +430,7 @@ static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr(
|
||||
int ret;
|
||||
|
||||
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);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -50,7 +50,7 @@ u8 iscsit_tmr_abort_task(
|
||||
pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
|
||||
" %hu.\n", hdr->rtt, conn->cid);
|
||||
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;
|
||||
}
|
||||
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)
|
||||
a->default_erl = TA_DEFAULT_ERL;
|
||||
a->t10_pi = TA_DEFAULT_T10_PI;
|
||||
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)
|
||||
@@ -430,7 +431,7 @@ struct iscsi_tpg_np *iscsit_tpg_locate_child_np(
|
||||
|
||||
static bool iscsit_tpg_check_network_portal(
|
||||
struct iscsi_tiqn *tiqn,
|
||||
struct __kernel_sockaddr_storage *sockaddr,
|
||||
struct sockaddr_storage *sockaddr,
|
||||
int network_transport)
|
||||
{
|
||||
struct iscsi_portal_group *tpg;
|
||||
@@ -459,8 +460,7 @@ static bool iscsit_tpg_check_network_portal(
|
||||
|
||||
struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
|
||||
struct iscsi_portal_group *tpg,
|
||||
struct __kernel_sockaddr_storage *sockaddr,
|
||||
char *ip_str,
|
||||
struct sockaddr_storage *sockaddr,
|
||||
struct iscsi_tpg_np *tpg_np_parent,
|
||||
int network_transport)
|
||||
{
|
||||
@@ -470,8 +470,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
|
||||
if (!tpg_np_parent) {
|
||||
if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr,
|
||||
network_transport)) {
|
||||
pr_err("Network Portal: %s already exists on a"
|
||||
" different TPG on %s\n", ip_str,
|
||||
pr_err("Network Portal: %pISc already exists on a"
|
||||
" different TPG on %s\n", sockaddr,
|
||||
tpg->tpg_tiqn->tiqn);
|
||||
return ERR_PTR(-EEXIST);
|
||||
}
|
||||
@@ -484,7 +484,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
np = iscsit_add_np(sockaddr, ip_str, network_transport);
|
||||
np = iscsit_add_np(sockaddr, network_transport);
|
||||
if (IS_ERR(np)) {
|
||||
kfree(tpg_np);
|
||||
return ERR_CAST(np);
|
||||
@@ -514,8 +514,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal(
|
||||
spin_unlock(&tpg_np_parent->tpg_np_parent_lock);
|
||||
}
|
||||
|
||||
pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n",
|
||||
tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
|
||||
pr_debug("CORE[%s] - Added Network Portal: %pISpc,%hu on %s\n",
|
||||
tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
|
||||
np->np_transport->name);
|
||||
|
||||
return tpg_np;
|
||||
@@ -528,8 +528,8 @@ static int iscsit_tpg_release_np(
|
||||
{
|
||||
iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true);
|
||||
|
||||
pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n",
|
||||
tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt,
|
||||
pr_debug("CORE[%s] - Removed Network Portal: %pISpc,%hu on %s\n",
|
||||
tpg->tpg_tiqn->tiqn, &np->np_sockaddr, tpg->tpgt,
|
||||
np->np_transport->name);
|
||||
|
||||
tpg_np->tpg_np = NULL;
|
||||
@@ -892,3 +892,21 @@ int iscsit_ta_fabric_prot_type(
|
||||
|
||||
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
|
||||
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_add_network_portal(struct iscsi_portal_group *,
|
||||
struct __kernel_sockaddr_storage *, char *, struct iscsi_tpg_np *,
|
||||
struct sockaddr_storage *, struct iscsi_tpg_np *,
|
||||
int);
|
||||
extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *,
|
||||
struct iscsi_tpg_np *);
|
||||
@@ -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_t10_pi(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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
u32 max_cmdsn;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
@@ -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
|
||||
* 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"
|
||||
" MaxCmdSN: 0x%08x, ignoring.\n", cmdsn,
|
||||
sess->max_cmd_sn);
|
||||
" MaxCmdSN: 0x%08x, ignoring.\n", cmdsn, max_cmdsn);
|
||||
ret = CMDSN_MAXCMDSN_OVERRUN;
|
||||
|
||||
} else if (cmdsn == sess->exp_cmd_sn) {
|
||||
@@ -1371,6 +1372,33 @@ int tx_data(
|
||||
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(
|
||||
struct iscsi_conn *conn,
|
||||
u8 status_class,
|
||||
@@ -1387,7 +1415,7 @@ void iscsit_collect_login_stats(
|
||||
ls = &tiqn->login_stats;
|
||||
|
||||
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)) {
|
||||
/* We already have the failure info for this login */
|
||||
spin_unlock(&ls->lock);
|
||||
@@ -1427,8 +1455,7 @@ void iscsit_collect_login_stats(
|
||||
|
||||
ls->last_intr_fail_ip_family = conn->login_family;
|
||||
|
||||
snprintf(ls->last_intr_fail_ip_addr, IPV6_ADDRESS_SPACE,
|
||||
"%s", conn->login_ip);
|
||||
ls->last_intr_fail_sockaddr = conn->login_sockaddr;
|
||||
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)
|
||||
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];
|
||||
}
|
||||
@@ -845,7 +845,7 @@ static int tcm_loop_make_nexus(
|
||||
transport_free_session(tl_nexus->se_sess);
|
||||
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,
|
||||
tl_nexus->se_sess, tl_nexus);
|
||||
tl_tpg->tl_nexus = tl_nexus;
|
||||
@@ -884,7 +884,7 @@ static int tcm_loop_drop_nexus(
|
||||
" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tpg->tl_hba),
|
||||
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);
|
||||
tpg->tl_nexus = NULL;
|
||||
@@ -1034,6 +1034,11 @@ static ssize_t tcm_loop_tpg_store_transport_status(
|
||||
}
|
||||
if (!strncmp(page, "offline", 7)) {
|
||||
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 -EINVAL;
|
||||
@@ -1077,7 +1082,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg(
|
||||
tl_tpg->tl_hba = tl_hba;
|
||||
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);
|
||||
if (ret < 0)
|
||||
@@ -1102,11 +1107,11 @@ static void tcm_loop_drop_naa_tpg(
|
||||
tl_hba = tl_tpg->tl_hba;
|
||||
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);
|
||||
/*
|
||||
* 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);
|
||||
|
||||
@@ -1199,8 +1204,9 @@ static void tcm_loop_drop_scsi_hba(
|
||||
struct tcm_loop_hba, tl_hba_wwn);
|
||||
|
||||
pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target"
|
||||
" SAS Address: %s at Linux/SCSI Host ID: %d\n",
|
||||
tl_hba->tl_wwn_address, tl_hba->sh->host_no);
|
||||
" %s Address: %s at Linux/SCSI Host ID: %d\n",
|
||||
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.
|
||||
* 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(
|
||||
|
||||
lacl->mapped_lun = mapped_lun;
|
||||
lacl->se_lun_nacl = nacl;
|
||||
snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s",
|
||||
nacl->initiatorname);
|
||||
|
||||
return lacl;
|
||||
}
|
||||
@@ -656,7 +654,7 @@ int core_dev_add_initiator_node_lun_acl(
|
||||
" InitiatorNode: %s\n", tpg->se_tpg_tfo->get_fabric_name(),
|
||||
tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun, lacl->mapped_lun,
|
||||
(lun_access & TRANSPORT_LUNFLAGS_READ_WRITE) ? "RW" : "RO",
|
||||
lacl->initiatorname);
|
||||
nacl->initiatorname);
|
||||
/*
|
||||
* Check to see if there are any existing persistent reservation APTPL
|
||||
* pre-registrations that need to be enabled for this LUN ACL..
|
||||
@@ -688,7 +686,7 @@ int core_dev_del_initiator_node_lun_acl(
|
||||
" InitiatorNode: %s Mapped LUN: %llu\n",
|
||||
tpg->se_tpg_tfo->get_fabric_name(),
|
||||
tpg->se_tpg_tfo->tpg_get_tag(tpg), lun->unpacked_lun,
|
||||
lacl->initiatorname, lacl->mapped_lun);
|
||||
nacl->initiatorname, lacl->mapped_lun);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -701,7 +699,7 @@ void core_dev_free_initiator_node_lun_acl(
|
||||
" Mapped LUN: %llu\n", tpg->se_tpg_tfo->get_fabric_name(),
|
||||
tpg->se_tpg_tfo->tpg_get_tag(tpg),
|
||||
tpg->se_tpg_tfo->get_fabric_name(),
|
||||
lacl->initiatorname, lacl->mapped_lun);
|
||||
lacl->se_lun_nacl->initiatorname, lacl->mapped_lun);
|
||||
|
||||
kfree(lacl);
|
||||
}
|
||||
@@ -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->se_hba = hba;
|
||||
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;
|
||||
|
||||
INIT_LIST_HEAD(&dev->dev_list);
|
||||
@@ -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->qf_cmd_lock);
|
||||
sema_init(&dev->caw_sem, 1);
|
||||
atomic_set(&dev->dev_ordered_id, 0);
|
||||
INIT_LIST_HEAD(&dev->t10_wwn.t10_vpd_list);
|
||||
spin_lock_init(&dev->t10_wwn.t10_vpd_lock);
|
||||
INIT_LIST_HEAD(&dev->t10_pr.registration_list);
|
||||
|
||||
@@ -203,7 +203,7 @@ static ssize_t target_fabric_mappedlun_store_write_protect(
|
||||
pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
|
||||
" Mapped LUN: %llu Write Protect bit to %s\n",
|
||||
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;
|
||||
|
||||
|
||||
@@ -184,3 +184,8 @@ core_delete_hba(struct se_hba *hba)
|
||||
kfree(hba);
|
||||
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)
|
||||
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)
|
||||
{
|
||||
u32 num_blocks;
|
||||
@@ -960,6 +992,9 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
|
||||
" than 1\n", sectors);
|
||||
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
|
||||
* zero is not an error..
|
||||
@@ -1069,6 +1104,10 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops)
|
||||
size = 0;
|
||||
cmd->execute_cmd = sbc_emulate_noop;
|
||||
break;
|
||||
case START_STOP:
|
||||
size = 0;
|
||||
cmd->execute_cmd = sbc_emulate_startstop;
|
||||
break;
|
||||
default:
|
||||
ret = spc_parse_cdb(cmd, &size);
|
||||
if (ret)
|
||||
@@ -1191,7 +1230,7 @@ void
|
||||
sbc_dif_generate(struct se_cmd *cmd)
|
||||
{
|
||||
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;
|
||||
sector_t sector = cmd->t_task_lba;
|
||||
void *daddr, *paddr;
|
||||
@@ -1203,7 +1242,7 @@ sbc_dif_generate(struct se_cmd *cmd)
|
||||
daddr = kmap_atomic(sg_page(dsg)) + dsg->offset;
|
||||
|
||||
for (j = 0; j < psg->length;
|
||||
j += sizeof(struct se_dif_v1_tuple)) {
|
||||
j += sizeof(*sdt)) {
|
||||
__u16 crc;
|
||||
unsigned int avail;
|
||||
|
||||
@@ -1256,7 +1295,7 @@ sbc_dif_generate(struct se_cmd *cmd)
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
__be16 csum;
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
sector_t sector = start;
|
||||
void *daddr, *paddr;
|
||||
@@ -1361,7 +1400,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
|
||||
|
||||
for (i = psg_off; i < psg->length &&
|
||||
sector < start + sectors;
|
||||
i += sizeof(struct se_dif_v1_tuple)) {
|
||||
i += sizeof(*sdt)) {
|
||||
__u16 crc;
|
||||
unsigned int avail;
|
||||
|
||||
|
||||
@@ -484,8 +484,8 @@ static sense_reason_t
|
||||
spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
|
||||
{
|
||||
struct se_device *dev = cmd->se_dev;
|
||||
int have_tp = 0;
|
||||
int opt, min;
|
||||
u32 mtl = 0;
|
||||
int have_tp = 0, opt, min;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -768,7 +775,12 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p)
|
||||
if (pc == 1)
|
||||
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
|
||||
*
|
||||
@@ -1151,6 +1163,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
|
||||
unsigned char *rbuf;
|
||||
u8 ua_asc = 0, ua_ascq = 0;
|
||||
unsigned char buf[SE_SENSE_BUF];
|
||||
bool desc_format = target_sense_desc_format(cmd->se_dev);
|
||||
|
||||
memset(buf, 0, SE_SENSE_BUF);
|
||||
|
||||
@@ -1164,32 +1177,11 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
|
||||
if (!rbuf)
|
||||
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||
|
||||
if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) {
|
||||
/*
|
||||
* CURRENT ERROR, UNIT ATTENTION
|
||||
*/
|
||||
buf[0] = 0x70;
|
||||
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;
|
||||
}
|
||||
if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))
|
||||
scsi_build_sense_buffer(desc_format, buf, UNIT_ATTENTION,
|
||||
ua_asc, ua_ascq);
|
||||
else
|
||||
scsi_build_sense_buffer(desc_format, buf, NO_SENSE, 0x0, 0x0);
|
||||
|
||||
memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
|
||||
transport_kunmap_data_sg(cmd);
|
||||
@@ -1418,9 +1410,6 @@ spc_parse_cdb(struct se_cmd *cmd, unsigned int *size)
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "target_core_internal.h"
|
||||
#include "target_core_alua.h"
|
||||
#include "target_core_pr.h"
|
||||
#include "target_core_ua.h"
|
||||
|
||||
extern struct se_device *g_lun0_dev;
|
||||
|
||||
@@ -83,6 +84,22 @@ struct se_node_acl *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():
|
||||
*
|
||||
*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user