提交 bc756235 编写于 作者: M Michael S. Tsirkin

Merge branch 'for-next-merge' of...

Merge branch 'for-next-merge' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending into vhost-net-next
...@@ -59,5 +59,6 @@ source "drivers/infiniband/ulp/srp/Kconfig" ...@@ -59,5 +59,6 @@ source "drivers/infiniband/ulp/srp/Kconfig"
source "drivers/infiniband/ulp/srpt/Kconfig" source "drivers/infiniband/ulp/srpt/Kconfig"
source "drivers/infiniband/ulp/iser/Kconfig" source "drivers/infiniband/ulp/iser/Kconfig"
source "drivers/infiniband/ulp/isert/Kconfig"
endif # INFINIBAND endif # INFINIBAND
...@@ -13,3 +13,4 @@ obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/ ...@@ -13,3 +13,4 @@ obj-$(CONFIG_INFINIBAND_IPOIB) += ulp/ipoib/
obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/ obj-$(CONFIG_INFINIBAND_SRP) += ulp/srp/
obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/ obj-$(CONFIG_INFINIBAND_SRPT) += ulp/srpt/
obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/ obj-$(CONFIG_INFINIBAND_ISER) += ulp/iser/
obj-$(CONFIG_INFINIBAND_ISERT) += ulp/isert/
config INFINIBAND_ISERT
tristate "iSCSI Extentions for RDMA (iSER) target support"
depends on INET && INFINIBAND_ADDR_TRANS && TARGET_CORE && ISCSI_TARGET
---help---
Support for iSCSI Extentions for RDMA (iSER) Target on Infiniband fabrics.
ccflags-y := -Idrivers/target -Idrivers/target/iscsi
obj-$(CONFIG_INFINIBAND_ISERT) += ib_isert.o
此差异已折叠。
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <rdma/ib_verbs.h>
#include <rdma/rdma_cm.h>
#define ISERT_RDMA_LISTEN_BACKLOG 10
enum isert_desc_type {
ISCSI_TX_CONTROL,
ISCSI_TX_DATAIN
};
enum iser_ib_op_code {
ISER_IB_RECV,
ISER_IB_SEND,
ISER_IB_RDMA_WRITE,
ISER_IB_RDMA_READ,
};
enum iser_conn_state {
ISER_CONN_INIT,
ISER_CONN_UP,
ISER_CONN_TERMINATING,
ISER_CONN_DOWN,
};
struct iser_rx_desc {
struct iser_hdr iser_header;
struct iscsi_hdr iscsi_header;
char data[ISER_RECV_DATA_SEG_LEN];
u64 dma_addr;
struct ib_sge rx_sg;
char pad[ISER_RX_PAD_SIZE];
} __packed;
struct iser_tx_desc {
struct iser_hdr iser_header;
struct iscsi_hdr iscsi_header;
enum isert_desc_type type;
u64 dma_addr;
struct ib_sge tx_sg[2];
int num_sge;
struct isert_cmd *isert_cmd;
struct ib_send_wr send_wr;
} __packed;
struct isert_rdma_wr {
struct list_head wr_list;
struct isert_cmd *isert_cmd;
enum iser_ib_op_code iser_ib_op;
struct ib_sge *ib_sge;
int num_sge;
struct scatterlist *sge;
int send_wr_num;
struct ib_send_wr *send_wr;
};
struct isert_cmd {
uint32_t read_stag;
uint32_t write_stag;
uint64_t read_va;
uint64_t write_va;
u64 sense_buf_dma;
u32 sense_buf_len;
u32 read_va_off;
u32 write_va_off;
u32 rdma_wr_num;
struct isert_conn *conn;
struct iscsi_cmd iscsi_cmd;
struct ib_sge *ib_sge;
struct iser_tx_desc tx_desc;
struct isert_rdma_wr rdma_wr;
struct work_struct comp_work;
};
struct isert_device;
struct isert_conn {
enum iser_conn_state state;
bool logout_posted;
int post_recv_buf_count;
atomic_t post_send_buf_count;
u32 responder_resources;
u32 initiator_depth;
u32 max_sge;
char *login_buf;
char *login_req_buf;
char *login_rsp_buf;
u64 login_req_dma;
u64 login_rsp_dma;
unsigned int conn_rx_desc_head;
struct iser_rx_desc *conn_rx_descs;
struct ib_recv_wr conn_rx_wr[ISERT_MIN_POSTED_RX];
struct iscsi_conn *conn;
struct list_head conn_accept_node;
struct completion conn_login_comp;
struct iser_tx_desc conn_login_tx_desc;
struct rdma_cm_id *conn_cm_id;
struct ib_pd *conn_pd;
struct ib_mr *conn_mr;
struct ib_qp *conn_qp;
struct isert_device *conn_device;
struct work_struct conn_logout_work;
wait_queue_head_t conn_wait;
wait_queue_head_t conn_wait_comp_err;
struct kref conn_kref;
};
#define ISERT_MAX_CQ 64
struct isert_cq_desc {
struct isert_device *device;
int cq_index;
struct work_struct cq_rx_work;
struct work_struct cq_tx_work;
};
struct isert_device {
int cqs_used;
int refcount;
int cq_active_qps[ISERT_MAX_CQ];
struct ib_device *ib_device;
struct ib_pd *dev_pd;
struct ib_mr *dev_mr;
struct ib_cq *dev_rx_cq[ISERT_MAX_CQ];
struct ib_cq *dev_tx_cq[ISERT_MAX_CQ];
struct isert_cq_desc *cq_desc;
struct list_head dev_node;
};
struct isert_np {
wait_queue_head_t np_accept_wq;
struct rdma_cm_id *np_cm_id;
struct mutex np_accept_mutex;
struct list_head np_accept_list;
struct completion np_login_comp;
};
/* From iscsi_iser.h */
struct iser_hdr {
u8 flags;
u8 rsvd[3];
__be32 write_stag; /* write rkey */
__be64 write_va;
__be32 read_stag; /* read rkey */
__be64 read_va;
} __packed;
/*Constant PDU lengths calculations */
#define ISER_HEADERS_LEN (sizeof(struct iser_hdr) + sizeof(struct iscsi_hdr))
#define ISER_RECV_DATA_SEG_LEN 8192
#define ISER_RX_PAYLOAD_SIZE (ISER_HEADERS_LEN + ISER_RECV_DATA_SEG_LEN)
#define ISER_RX_LOGIN_SIZE (ISER_HEADERS_LEN + ISCSI_DEF_MAX_RECV_SEG_LEN)
/* QP settings */
/* Maximal bounds on received asynchronous PDUs */
#define ISERT_MAX_TX_MISC_PDUS 4 /* NOOP_IN(2) , ASYNC_EVENT(2) */
#define ISERT_MAX_RX_MISC_PDUS 6 /* NOOP_OUT(2), TEXT(1), *
* SCSI_TMFUNC(2), LOGOUT(1) */
#define ISCSI_DEF_XMIT_CMDS_MAX 128 /* from libiscsi.h, must be power of 2 */
#define ISERT_QP_MAX_RECV_DTOS (ISCSI_DEF_XMIT_CMDS_MAX)
#define ISERT_MIN_POSTED_RX (ISCSI_DEF_XMIT_CMDS_MAX >> 2)
#define ISERT_INFLIGHT_DATAOUTS 8
#define ISERT_QP_MAX_REQ_DTOS (ISCSI_DEF_XMIT_CMDS_MAX * \
(1 + ISERT_INFLIGHT_DATAOUTS) + \
ISERT_MAX_TX_MISC_PDUS + \
ISERT_MAX_RX_MISC_PDUS)
#define ISER_RX_PAD_SIZE (ISER_RECV_DATA_SEG_LEN + 4096 - \
(ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge)))
#define ISER_VER 0x10
#define ISER_WSV 0x08
#define ISER_RSV 0x04
#define ISCSI_CTRL 0x10
#define ISER_HELLO 0x20
#define ISER_HELLORPLY 0x30
...@@ -2585,25 +2585,6 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, ...@@ -2585,25 +2585,6 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
ha->tgt.tgt_ops->free_cmd(cmd); ha->tgt.tgt_ops->free_cmd(cmd);
} }
/* ha->hardware_lock supposed to be held on entry */
/* called via callback from qla2xxx */
void qlt_ctio_completion(struct scsi_qla_host *vha, uint32_t handle)
{
struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = ha->tgt.qla_tgt;
if (likely(tgt == NULL)) {
ql_dbg(ql_dbg_tgt, vha, 0xe021,
"CTIO, but target mode not enabled"
" (ha %d %p handle %#x)", vha->vp_idx, ha, handle);
return;
}
tgt->irq_cmd_count++;
qlt_do_ctio_completion(vha, handle, CTIO_SUCCESS, NULL);
tgt->irq_cmd_count--;
}
static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha, static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha,
uint8_t task_codes) uint8_t task_codes)
{ {
......
...@@ -980,7 +980,6 @@ extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); ...@@ -980,7 +980,6 @@ extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
extern void qlt_ctio_completion(struct scsi_qla_host *, uint32_t);
extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *); extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *);
extern void qlt_enable_vha(struct scsi_qla_host *); extern void qlt_enable_vha(struct scsi_qla_host *);
extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *);
......
...@@ -15,6 +15,7 @@ iscsi_target_mod-y += iscsi_target_parameters.o \ ...@@ -15,6 +15,7 @@ iscsi_target_mod-y += iscsi_target_parameters.o \
iscsi_target_util.o \ iscsi_target_util.o \
iscsi_target.o \ iscsi_target.o \
iscsi_target_configfs.o \ iscsi_target_configfs.o \
iscsi_target_stat.o iscsi_target_stat.o \
iscsi_target_transport.o
obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o obj-$(CONFIG_ISCSI_TARGET) += iscsi_target_mod.o
此差异已折叠。
...@@ -16,11 +16,12 @@ extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, ...@@ -16,11 +16,12 @@ extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
struct iscsi_portal_group *); struct iscsi_portal_group *);
extern int iscsit_del_np(struct iscsi_np *); extern int iscsit_del_np(struct iscsi_np *);
extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *); extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *);
extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *); extern int iscsit_logout_removeconnforrecovery(struct iscsi_cmd *, struct iscsi_conn *);
extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8); extern int iscsit_send_async_msg(struct iscsi_conn *, u16, u8, u8);
extern int iscsit_build_r2ts_for_cmd(struct iscsi_cmd *, struct iscsi_conn *, bool recovery); extern int iscsit_build_r2ts_for_cmd(struct iscsi_conn *, struct iscsi_cmd *, bool recovery);
extern void iscsit_thread_get_cpumask(struct iscsi_conn *); extern void iscsit_thread_get_cpumask(struct iscsi_conn *);
extern int iscsi_target_tx_thread(void *); extern int iscsi_target_tx_thread(void *);
extern int iscsi_target_rx_thread(void *); extern int iscsi_target_rx_thread(void *);
......
...@@ -49,32 +49,6 @@ static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len) ...@@ -49,32 +49,6 @@ static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len)
} }
} }
static void chap_set_random(char *data, int length)
{
long r;
unsigned n;
while (length > 0) {
get_random_bytes(&r, sizeof(long));
r = r ^ (r >> 8);
r = r ^ (r >> 4);
n = r & 0x7;
get_random_bytes(&r, sizeof(long));
r = r ^ (r >> 8);
r = r ^ (r >> 5);
n = (n << 3) | (r & 0x7);
get_random_bytes(&r, sizeof(long));
r = r ^ (r >> 8);
r = r ^ (r >> 5);
n = (n << 2) | (r & 0x3);
*data++ = n;
length--;
}
}
static void chap_gen_challenge( static void chap_gen_challenge(
struct iscsi_conn *conn, struct iscsi_conn *conn,
int caller, int caller,
...@@ -86,7 +60,7 @@ static void chap_gen_challenge( ...@@ -86,7 +60,7 @@ static void chap_gen_challenge(
memset(challenge_asciihex, 0, CHAP_CHALLENGE_LENGTH * 2 + 1); memset(challenge_asciihex, 0, CHAP_CHALLENGE_LENGTH * 2 + 1);
chap_set_random(chap->challenge, CHAP_CHALLENGE_LENGTH); get_random_bytes(chap->challenge, CHAP_CHALLENGE_LENGTH);
chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge, chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge,
CHAP_CHALLENGE_LENGTH); CHAP_CHALLENGE_LENGTH);
/* /*
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <target/target_core_fabric_configfs.h> #include <target/target_core_fabric_configfs.h>
#include <target/target_core_configfs.h> #include <target/target_core_configfs.h>
#include <target/configfs_macros.h> #include <target/configfs_macros.h>
#include <target/iscsi/iscsi_transport.h>
#include "iscsi_target_core.h" #include "iscsi_target_core.h"
#include "iscsi_target_parameters.h" #include "iscsi_target_parameters.h"
...@@ -124,8 +125,87 @@ static ssize_t lio_target_np_store_sctp( ...@@ -124,8 +125,87 @@ static ssize_t lio_target_np_store_sctp(
TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR); TF_NP_BASE_ATTR(lio_target, sctp, S_IRUGO | S_IWUSR);
static ssize_t lio_target_np_show_iser(
struct se_tpg_np *se_tpg_np,
char *page)
{
struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
struct iscsi_tpg_np, se_tpg_np);
struct iscsi_tpg_np *tpg_np_iser;
ssize_t rb;
tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND);
if (tpg_np_iser)
rb = sprintf(page, "1\n");
else
rb = sprintf(page, "0\n");
return rb;
}
static ssize_t lio_target_np_store_iser(
struct se_tpg_np *se_tpg_np,
const char *page,
size_t count)
{
struct iscsi_np *np;
struct iscsi_portal_group *tpg;
struct iscsi_tpg_np *tpg_np = container_of(se_tpg_np,
struct iscsi_tpg_np, se_tpg_np);
struct iscsi_tpg_np *tpg_np_iser = NULL;
char *endptr;
u32 op;
int rc;
op = simple_strtoul(page, &endptr, 0);
if ((op != 1) && (op != 0)) {
pr_err("Illegal value for tpg_enable: %u\n", op);
return -EINVAL;
}
np = tpg_np->tpg_np;
if (!np) {
pr_err("Unable to locate struct iscsi_np from"
" struct iscsi_tpg_np\n");
return -EINVAL;
}
tpg = tpg_np->tpg;
if (iscsit_get_tpg(tpg) < 0)
return -EINVAL;
if (op) {
int rc = request_module("ib_isert");
if (rc != 0)
pr_warn("Unable to request_module for ib_isert\n");
tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr,
np->np_ip, tpg_np, ISCSI_INFINIBAND);
if (!tpg_np_iser || IS_ERR(tpg_np_iser))
goto out;
} else {
tpg_np_iser = iscsit_tpg_locate_child_np(tpg_np, ISCSI_INFINIBAND);
if (!tpg_np_iser)
goto out;
rc = iscsit_tpg_del_network_portal(tpg, tpg_np_iser);
if (rc < 0)
goto out;
}
printk("lio_target_np_store_iser() done, op: %d\n", op);
iscsit_put_tpg(tpg);
return count;
out:
iscsit_put_tpg(tpg);
return -EINVAL;
}
TF_NP_BASE_ATTR(lio_target, iser, S_IRUGO | S_IWUSR);
static struct configfs_attribute *lio_target_portal_attrs[] = { static struct configfs_attribute *lio_target_portal_attrs[] = {
&lio_target_np_sctp.attr, &lio_target_np_sctp.attr,
&lio_target_np_iser.attr,
NULL, NULL,
}; };
...@@ -1536,16 +1616,18 @@ static int lio_queue_data_in(struct se_cmd *se_cmd) ...@@ -1536,16 +1616,18 @@ static int lio_queue_data_in(struct se_cmd *se_cmd)
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
cmd->i_state = ISTATE_SEND_DATAIN; cmd->i_state = ISTATE_SEND_DATAIN;
iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); cmd->conn->conn_transport->iscsit_queue_data_in(cmd->conn, cmd);
return 0; return 0;
} }
static int lio_write_pending(struct se_cmd *se_cmd) static int lio_write_pending(struct se_cmd *se_cmd)
{ {
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
struct iscsi_conn *conn = cmd->conn;
if (!cmd->immediate_data && !cmd->unsolicited_data) if (!cmd->immediate_data && !cmd->unsolicited_data)
return iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); return conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
return 0; return 0;
} }
...@@ -1567,7 +1649,8 @@ static int lio_queue_status(struct se_cmd *se_cmd) ...@@ -1567,7 +1649,8 @@ static int lio_queue_status(struct se_cmd *se_cmd)
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
cmd->i_state = ISTATE_SEND_STATUS; cmd->i_state = ISTATE_SEND_STATUS;
iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); cmd->conn->conn_transport->iscsit_queue_status(cmd->conn, cmd);
return 0; return 0;
} }
...@@ -1696,11 +1779,17 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl) ...@@ -1696,11 +1779,17 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
iscsit_set_default_node_attribues(acl); iscsit_set_default_node_attribues(acl);
} }
static int lio_check_stop_free(struct se_cmd *se_cmd)
{
return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
}
static void lio_release_cmd(struct se_cmd *se_cmd) static void lio_release_cmd(struct se_cmd *se_cmd)
{ {
struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
iscsit_release_cmd(cmd); pr_debug("Entering lio_release_cmd for se_cmd: %p\n", se_cmd);
cmd->release_cmd(cmd);
} }
/* End functions for target_core_fabric_ops */ /* End functions for target_core_fabric_ops */
...@@ -1740,6 +1829,7 @@ int iscsi_target_register_configfs(void) ...@@ -1740,6 +1829,7 @@ int iscsi_target_register_configfs(void)
fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl; fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl;
fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl; fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl;
fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index; fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index;
fabric->tf_ops.check_stop_free = &lio_check_stop_free,
fabric->tf_ops.release_cmd = &lio_release_cmd; fabric->tf_ops.release_cmd = &lio_release_cmd;
fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session;
fabric->tf_ops.close_session = &lio_tpg_close_session; fabric->tf_ops.close_session = &lio_tpg_close_session;
......
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
#define ISCSI_IOV_DATA_BUFFER 5 #define ISCSI_IOV_DATA_BUFFER 5
enum tpg_np_network_transport_table { enum iscsit_transport_type {
ISCSI_TCP = 0, ISCSI_TCP = 0,
ISCSI_SCTP_TCP = 1, ISCSI_SCTP_TCP = 1,
ISCSI_SCTP_UDP = 2, ISCSI_SCTP_UDP = 2,
...@@ -244,6 +244,11 @@ struct iscsi_conn_ops { ...@@ -244,6 +244,11 @@ struct iscsi_conn_ops {
u8 IFMarker; /* [0,1] == [No,Yes] */ u8 IFMarker; /* [0,1] == [No,Yes] */
u32 OFMarkInt; /* [1..65535] */ u32 OFMarkInt; /* [1..65535] */
u32 IFMarkInt; /* [1..65535] */ u32 IFMarkInt; /* [1..65535] */
/*
* iSER specific connection parameters
*/
u32 InitiatorRecvDataSegmentLength; /* [512..2**24-1] */
u32 TargetRecvDataSegmentLength; /* [512..2**24-1] */
}; };
struct iscsi_sess_ops { struct iscsi_sess_ops {
...@@ -265,6 +270,10 @@ struct iscsi_sess_ops { ...@@ -265,6 +270,10 @@ struct iscsi_sess_ops {
u8 DataSequenceInOrder; /* [0,1] == [No,Yes] */ u8 DataSequenceInOrder; /* [0,1] == [No,Yes] */
u8 ErrorRecoveryLevel; /* [0..2] */ u8 ErrorRecoveryLevel; /* [0..2] */
u8 SessionType; /* [0,1] == [Normal,Discovery]*/ u8 SessionType; /* [0,1] == [Normal,Discovery]*/
/*
* iSER specific session parameters
*/
u8 RDMAExtensions; /* [0,1] == [No,Yes] */
}; };
struct iscsi_queue_req { struct iscsi_queue_req {
...@@ -284,6 +293,7 @@ struct iscsi_data_count { ...@@ -284,6 +293,7 @@ struct iscsi_data_count {
}; };
struct iscsi_param_list { struct iscsi_param_list {
bool iser;
struct list_head param_list; struct list_head param_list;
struct list_head extra_response_list; struct list_head extra_response_list;
}; };
...@@ -475,6 +485,7 @@ struct iscsi_cmd { ...@@ -475,6 +485,7 @@ struct iscsi_cmd {
u32 first_data_sg_off; u32 first_data_sg_off;
u32 kmapped_nents; u32 kmapped_nents;
sense_reason_t sense_reason; sense_reason_t sense_reason;
void (*release_cmd)(struct iscsi_cmd *);
} ____cacheline_aligned; } ____cacheline_aligned;
struct iscsi_tmr_req { struct iscsi_tmr_req {
...@@ -503,6 +514,7 @@ struct iscsi_conn { ...@@ -503,6 +514,7 @@ struct iscsi_conn {
u16 login_port; u16 login_port;
u16 local_port; u16 local_port;
int net_size; int net_size;
int login_family;
u32 auth_id; u32 auth_id;
u32 conn_flags; u32 conn_flags;
/* Used for iscsi_tx_login_rsp() */ /* Used for iscsi_tx_login_rsp() */
...@@ -562,9 +574,12 @@ struct iscsi_conn { ...@@ -562,9 +574,12 @@ struct iscsi_conn {
struct list_head immed_queue_list; struct list_head immed_queue_list;
struct list_head response_queue_list; struct list_head response_queue_list;
struct iscsi_conn_ops *conn_ops; struct iscsi_conn_ops *conn_ops;
struct iscsi_login *conn_login;
struct iscsit_transport *conn_transport;
struct iscsi_param_list *param_list; struct iscsi_param_list *param_list;
/* Used for per connection auth state machine */ /* Used for per connection auth state machine */
void *auth_protocol; void *auth_protocol;
void *context;
struct iscsi_login_thread_s *login_thread; struct iscsi_login_thread_s *login_thread;
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
/* Pointer to parent session */ /* Pointer to parent session */
...@@ -663,6 +678,8 @@ struct iscsi_login { ...@@ -663,6 +678,8 @@ struct iscsi_login {
u8 first_request; u8 first_request;
u8 version_min; u8 version_min;
u8 version_max; u8 version_max;
u8 login_complete;
u8 login_failed;
char isid[6]; char isid[6];
u32 cmd_sn; u32 cmd_sn;
itt_t init_task_tag; itt_t init_task_tag;
...@@ -670,10 +687,11 @@ struct iscsi_login { ...@@ -670,10 +687,11 @@ struct iscsi_login {
u32 rsp_length; u32 rsp_length;
u16 cid; u16 cid;
u16 tsih; u16 tsih;
char *req; char req[ISCSI_HDR_LEN];
char *rsp; char rsp[ISCSI_HDR_LEN];
char *req_buf; char *req_buf;
char *rsp_buf; char *rsp_buf;
struct iscsi_conn *conn;
} ____cacheline_aligned; } ____cacheline_aligned;
struct iscsi_node_attrib { struct iscsi_node_attrib {
...@@ -754,6 +772,8 @@ struct iscsi_np { ...@@ -754,6 +772,8 @@ struct iscsi_np {
struct task_struct *np_thread; struct task_struct *np_thread;
struct timer_list np_login_timer; struct timer_list np_login_timer;
struct iscsi_portal_group *np_login_tpg; struct iscsi_portal_group *np_login_tpg;
void *np_context;
struct iscsit_transport *np_transport;
struct list_head np_list; struct list_head np_list;
} ____cacheline_aligned; } ____cacheline_aligned;
......
...@@ -60,8 +60,13 @@ void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess ...@@ -60,8 +60,13 @@ void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess
cmd->maxcmdsn_inc = 1; cmd->maxcmdsn_inc = 1;
mutex_lock(&sess->cmdsn_mutex); if (!mutex_trylock(&sess->cmdsn_mutex)) {
sess->max_cmd_sn += 1;
pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
return;
}
sess->max_cmd_sn += 1; sess->max_cmd_sn += 1;
pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn); pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
mutex_unlock(&sess->cmdsn_mutex); mutex_unlock(&sess->cmdsn_mutex);
} }
EXPORT_SYMBOL(iscsit_increment_maxcmdsn);
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <scsi/iscsi_proto.h> #include <scsi/iscsi_proto.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#include <target/target_core_fabric.h> #include <target/target_core_fabric.h>
#include <target/iscsi/iscsi_transport.h>
#include "iscsi_target_core.h" #include "iscsi_target_core.h"
#include "iscsi_target_seq_pdu_list.h" #include "iscsi_target_seq_pdu_list.h"
...@@ -53,6 +54,9 @@ int iscsit_dump_data_payload( ...@@ -53,6 +54,9 @@ int iscsit_dump_data_payload(
u32 length, padding, offset = 0, size; u32 length, padding, offset = 0, size;
struct kvec iov; struct kvec iov;
if (conn->sess->sess_ops->RDMAExtensions)
return 0;
length = (buf_len > OFFLOAD_BUF_SIZE) ? OFFLOAD_BUF_SIZE : buf_len; length = (buf_len > OFFLOAD_BUF_SIZE) ? OFFLOAD_BUF_SIZE : buf_len;
buf = kzalloc(length, GFP_ATOMIC); buf = kzalloc(length, GFP_ATOMIC);
...@@ -919,6 +923,7 @@ int iscsit_execute_ooo_cmdsns(struct iscsi_session *sess) ...@@ -919,6 +923,7 @@ int iscsit_execute_ooo_cmdsns(struct iscsi_session *sess)
int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
{ {
struct se_cmd *se_cmd = &cmd->se_cmd; struct se_cmd *se_cmd = &cmd->se_cmd;
struct iscsi_conn *conn = cmd->conn;
int lr = 0; int lr = 0;
spin_lock_bh(&cmd->istate_lock); spin_lock_bh(&cmd->istate_lock);
...@@ -981,7 +986,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) ...@@ -981,7 +986,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
return 0; return 0;
iscsit_set_dataout_sequence_values(cmd); iscsit_set_dataout_sequence_values(cmd);
iscsit_build_r2ts_for_cmd(cmd, cmd->conn, false); conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
} }
return 0; return 0;
} }
...@@ -999,10 +1004,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) ...@@ -999,10 +1004,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
if (transport_check_aborted_status(se_cmd, 1) != 0) if (transport_check_aborted_status(se_cmd, 1) != 0)
return 0; return 0;
iscsit_set_dataout_sequence_values(cmd); iscsit_set_unsoliticed_dataout(cmd);
spin_lock_bh(&cmd->dataout_timeout_lock);
iscsit_start_dataout_timer(cmd, cmd->conn);
spin_unlock_bh(&cmd->dataout_timeout_lock);
} }
return transport_handle_cdb_direct(&cmd->se_cmd); return transport_handle_cdb_direct(&cmd->se_cmd);
...@@ -1290,3 +1292,4 @@ void iscsit_stop_dataout_timer(struct iscsi_cmd *cmd) ...@@ -1290,3 +1292,4 @@ void iscsit_stop_dataout_timer(struct iscsi_cmd *cmd)
cmd->init_task_tag); cmd->init_task_tag);
spin_unlock_bh(&cmd->dataout_timeout_lock); spin_unlock_bh(&cmd->dataout_timeout_lock);
} }
EXPORT_SYMBOL(iscsit_stop_dataout_timer);
...@@ -4,8 +4,14 @@ ...@@ -4,8 +4,14 @@
extern int iscsi_login_setup_crypto(struct iscsi_conn *); 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 *,
struct __kernel_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 __kernel_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);
extern void iscsit_free_conn(struct iscsi_np *, struct iscsi_conn *);
extern int iscsi_target_login_thread(void *); extern int iscsi_target_login_thread(void *);
extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *); extern int iscsi_login_disable_FIM_keys(struct iscsi_param_list *, struct iscsi_conn *);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <scsi/iscsi_proto.h> #include <scsi/iscsi_proto.h>
#include <target/target_core_base.h> #include <target/target_core_base.h>
#include <target/target_core_fabric.h> #include <target/target_core_fabric.h>
#include <target/iscsi/iscsi_transport.h>
#include "iscsi_target_core.h" #include "iscsi_target_core.h"
#include "iscsi_target_parameters.h" #include "iscsi_target_parameters.h"
...@@ -169,7 +170,7 @@ static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn) ...@@ -169,7 +170,7 @@ static void iscsi_remove_failed_auth_entry(struct iscsi_conn *conn)
kfree(conn->auth_protocol); kfree(conn->auth_protocol);
} }
static int iscsi_target_check_login_request( int iscsi_target_check_login_request(
struct iscsi_conn *conn, struct iscsi_conn *conn,
struct iscsi_login *login) struct iscsi_login *login)
{ {
...@@ -200,8 +201,8 @@ static int iscsi_target_check_login_request( ...@@ -200,8 +201,8 @@ static int iscsi_target_check_login_request(
return -1; return -1;
} }
req_csg = (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2; req_csg = ISCSI_LOGIN_CURRENT_STAGE(login_req->flags);
req_nsg = (login_req->flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK); req_nsg = ISCSI_LOGIN_NEXT_STAGE(login_req->flags);
if (req_csg != login->current_stage) { if (req_csg != login->current_stage) {
pr_err("Initiator unexpectedly changed login stage" pr_err("Initiator unexpectedly changed login stage"
...@@ -352,11 +353,8 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log ...@@ -352,11 +353,8 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
padding = ((-login->rsp_length) & 3); padding = ((-login->rsp_length) & 3);
if (iscsi_login_tx_data( if (conn->conn_transport->iscsit_put_login_tx(conn, login,
conn, login->rsp_length + padding) < 0)
login->rsp,
login->rsp_buf,
login->rsp_length + padding) < 0)
return -1; return -1;
login->rsp_length = 0; login->rsp_length = 0;
...@@ -368,72 +366,12 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log ...@@ -368,72 +366,12 @@ static int iscsi_target_do_tx_login_io(struct iscsi_conn *conn, struct iscsi_log
return 0; return 0;
} }
static int iscsi_target_do_rx_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
{
u32 padding = 0, payload_length;
struct iscsi_login_req *login_req;
if (iscsi_login_rx_data(conn, login->req, ISCSI_HDR_LEN) < 0)
return -1;
login_req = (struct iscsi_login_req *) login->req;
payload_length = ntoh24(login_req->dlength);
pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
" CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
login_req->flags, login_req->itt, login_req->cmdsn,
login_req->exp_statsn, login_req->cid, payload_length);
if (iscsi_target_check_login_request(conn, login) < 0)
return -1;
padding = ((-payload_length) & 3);
memset(login->req_buf, 0, MAX_KEY_VALUE_PAIRS);
if (iscsi_login_rx_data(
conn,
login->req_buf,
payload_length + padding) < 0)
return -1;
return 0;
}
static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login) static int iscsi_target_do_login_io(struct iscsi_conn *conn, struct iscsi_login *login)
{ {
if (iscsi_target_do_tx_login_io(conn, login) < 0) if (iscsi_target_do_tx_login_io(conn, login) < 0)
return -1; return -1;
if (iscsi_target_do_rx_login_io(conn, login) < 0) if (conn->conn_transport->iscsit_get_login_rx(conn, login) < 0)
return -1;
return 0;
}
static int iscsi_target_get_initial_payload(
struct iscsi_conn *conn,
struct iscsi_login *login)
{
u32 padding = 0, payload_length;
struct iscsi_login_req *login_req;
login_req = (struct iscsi_login_req *) login->req;
payload_length = ntoh24(login_req->dlength);
pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
" CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
login_req->flags, login_req->itt, login_req->cmdsn,
login_req->exp_statsn, payload_length);
if (iscsi_target_check_login_request(conn, login) < 0)
return -1;
padding = ((-payload_length) & 3);
if (iscsi_login_rx_data(
conn,
login->req_buf,
payload_length + padding) < 0)
return -1; return -1;
return 0; return 0;
...@@ -681,9 +619,9 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo ...@@ -681,9 +619,9 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo
return -1; return -1;
} }
switch ((login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2) { switch (ISCSI_LOGIN_CURRENT_STAGE(login_req->flags)) {
case 0: case 0:
login_rsp->flags |= (0 & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK); login_rsp->flags &= ~ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK;
if (iscsi_target_handle_csg_zero(conn, login) < 0) if (iscsi_target_handle_csg_zero(conn, login) < 0)
return -1; return -1;
break; break;
...@@ -693,6 +631,7 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo ...@@ -693,6 +631,7 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo
return -1; return -1;
if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) { if (login_rsp->flags & ISCSI_FLAG_LOGIN_TRANSIT) {
login->tsih = conn->sess->tsih; login->tsih = conn->sess->tsih;
login->login_complete = 1;
if (iscsi_target_do_tx_login_io(conn, if (iscsi_target_do_tx_login_io(conn,
login) < 0) login) < 0)
return -1; return -1;
...@@ -702,8 +641,7 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo ...@@ -702,8 +641,7 @@ static int iscsi_target_do_login(struct iscsi_conn *conn, struct iscsi_login *lo
default: default:
pr_err("Illegal CSG: %d received from" pr_err("Illegal CSG: %d received from"
" Initiator, protocol error.\n", " Initiator, protocol error.\n",
(login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) ISCSI_LOGIN_CURRENT_STAGE(login_req->flags));
>> 2);
break; break;
} }
...@@ -737,7 +675,7 @@ static void iscsi_initiatorname_tolower( ...@@ -737,7 +675,7 @@ static void iscsi_initiatorname_tolower(
/* /*
* Processes the first Login Request.. * Processes the first Login Request..
*/ */
static int iscsi_target_locate_portal( int iscsi_target_locate_portal(
struct iscsi_np *np, struct iscsi_np *np,
struct iscsi_conn *conn, struct iscsi_conn *conn,
struct iscsi_login *login) struct iscsi_login *login)
...@@ -753,22 +691,6 @@ static int iscsi_target_locate_portal( ...@@ -753,22 +691,6 @@ static int iscsi_target_locate_portal(
login_req = (struct iscsi_login_req *) login->req; login_req = (struct iscsi_login_req *) login->req;
payload_length = ntoh24(login_req->dlength); payload_length = ntoh24(login_req->dlength);
login->first_request = 1;
login->leading_connection = (!login_req->tsih) ? 1 : 0;
login->current_stage =
(login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2;
login->version_min = login_req->min_version;
login->version_max = login_req->max_version;
memcpy(login->isid, login_req->isid, 6);
login->cmd_sn = be32_to_cpu(login_req->cmdsn);
login->init_task_tag = login_req->itt;
login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn);
login->cid = be16_to_cpu(login_req->cid);
login->tsih = be16_to_cpu(login_req->tsih);
if (iscsi_target_get_initial_payload(conn, login) < 0)
return -1;
tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL); tmpbuf = kzalloc(payload_length + 1, GFP_KERNEL);
if (!tmpbuf) { if (!tmpbuf) {
pr_err("Unable to allocate memory for tmpbuf.\n"); pr_err("Unable to allocate memory for tmpbuf.\n");
...@@ -800,6 +722,8 @@ static int iscsi_target_locate_portal( ...@@ -800,6 +722,8 @@ static int iscsi_target_locate_portal(
start += strlen(key) + strlen(value) + 2; start += strlen(key) + strlen(value) + 2;
} }
printk("i_buf: %s, s_buf: %s, t_buf: %s\n", i_buf, s_buf, t_buf);
/* /*
* See 5.3. Login Phase. * See 5.3. Login Phase.
*/ */
...@@ -958,100 +882,30 @@ static int iscsi_target_locate_portal( ...@@ -958,100 +882,30 @@ static int iscsi_target_locate_portal(
return ret; return ret;
} }
struct iscsi_login *iscsi_target_init_negotiation(
struct iscsi_np *np,
struct iscsi_conn *conn,
char *login_pdu)
{
struct iscsi_login *login;
login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL);
if (!login) {
pr_err("Unable to allocate memory for struct iscsi_login.\n");
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
return NULL;
}
login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL);
if (!login->req) {
pr_err("Unable to allocate memory for Login Request.\n");
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
goto out;
}
login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
if (!login->req_buf) {
pr_err("Unable to allocate memory for response buffer.\n");
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
goto out;
}
/*
* SessionType: Discovery
*
* Locates Default Portal
*
* SessionType: Normal
*
* Locates Target Portal from NP -> Target IQN
*/
if (iscsi_target_locate_portal(np, conn, login) < 0) {
goto out;
}
return login;
out:
kfree(login->req);
kfree(login->req_buf);
kfree(login);
return NULL;
}
int iscsi_target_start_negotiation( int iscsi_target_start_negotiation(
struct iscsi_login *login, struct iscsi_login *login,
struct iscsi_conn *conn) struct iscsi_conn *conn)
{ {
int ret = -1; int ret;
login->rsp = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL);
if (!login->rsp) {
pr_err("Unable to allocate memory for"
" Login Response.\n");
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
ret = -1;
goto out;
}
login->rsp_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL);
if (!login->rsp_buf) {
pr_err("Unable to allocate memory for"
" request buffer.\n");
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
ISCSI_LOGIN_STATUS_NO_RESOURCES);
ret = -1;
goto out;
}
ret = iscsi_target_do_login(conn, login); ret = iscsi_target_do_login(conn, login);
out:
if (ret != 0) if (ret != 0)
iscsi_remove_failed_auth_entry(conn); iscsi_remove_failed_auth_entry(conn);
iscsi_target_nego_release(login, conn); iscsi_target_nego_release(conn);
return ret; return ret;
} }
void iscsi_target_nego_release( void iscsi_target_nego_release(struct iscsi_conn *conn)
struct iscsi_login *login,
struct iscsi_conn *conn)
{ {
kfree(login->req); struct iscsi_login *login = conn->conn_login;
kfree(login->rsp);
if (!login)
return;
kfree(login->req_buf); kfree(login->req_buf);
kfree(login->rsp_buf); kfree(login->rsp_buf);
kfree(login); kfree(login);
conn->conn_login = NULL;
} }
此差异已折叠。
...@@ -8,6 +8,7 @@ extern struct iscsi_r2t *iscsit_get_r2t_for_eos(struct iscsi_cmd *, u32, u32); ...@@ -8,6 +8,7 @@ extern struct iscsi_r2t *iscsit_get_r2t_for_eos(struct iscsi_cmd *, u32, u32);
extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *); extern struct iscsi_r2t *iscsit_get_r2t_from_list(struct iscsi_cmd *);
extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *); extern void iscsit_free_r2t(struct iscsi_r2t *, struct iscsi_cmd *);
extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *); extern void iscsit_free_r2ts_from_list(struct iscsi_cmd *);
extern struct iscsi_cmd *iscsit_alloc_cmd(struct iscsi_conn *, gfp_t);
extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t); extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32); extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *); extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册