⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iscsi_iser.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * verified against the global ib connections list */	ib_conn = iscsi_iser_ib_conn_lookup(transport_eph);	if (!ib_conn) {		iser_err("can't bind eph %llx\n",			 (unsigned long long)transport_eph);		return -EINVAL;	}	/* binds the iSER connection retrieved from the previously	 * connected ep_handle to the iSCSI layer connection. exchanges	 * connection pointers */	iser_err("binding iscsi conn %p to iser_conn %p\n",conn,ib_conn);	iser_conn = conn->dd_data;	ib_conn->iser_conn = iser_conn;	iser_conn->ib_conn  = ib_conn;	conn->recv_lock = &iser_conn->lock;	return 0;}static intiscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn){	struct iscsi_conn *conn = cls_conn->dd_data;	int err;	err = iser_conn_set_full_featured_mode(conn);	if (err)		return err;	return iscsi_conn_start(cls_conn);}static struct iscsi_transport iscsi_iser_transport;static struct iscsi_cls_session *iscsi_iser_session_create(struct iscsi_transport *iscsit,			 struct scsi_transport_template *scsit,			 uint16_t cmds_max, uint16_t qdepth,			 uint32_t initial_cmdsn, uint32_t *hostno){	struct iscsi_cls_session *cls_session;	struct iscsi_session *session;	int i;	uint32_t hn;	struct iscsi_cmd_task  *ctask;	struct iscsi_mgmt_task *mtask;	struct iscsi_iser_cmd_task *iser_ctask;	struct iser_desc *desc;	/*	 * we do not support setting can_queue cmd_per_lun from userspace yet	 * because we preallocate so many resources	 */	cls_session = iscsi_session_setup(iscsit, scsit,					  ISCSI_DEF_XMIT_CMDS_MAX,					  ISCSI_MAX_CMD_PER_LUN,					  sizeof(struct iscsi_iser_cmd_task),					  sizeof(struct iser_desc),					  initial_cmdsn, &hn);	if (!cls_session)	return NULL;	*hostno = hn;	session = class_to_transport_session(cls_session);	/* libiscsi setup itts, data and pool so just set desc fields */	for (i = 0; i < session->cmds_max; i++) {		ctask      = session->cmds[i];		iser_ctask = ctask->dd_data;		ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;	}	for (i = 0; i < session->mgmtpool_max; i++) {		mtask      = session->mgmt_cmds[i];		desc       = mtask->dd_data;		mtask->hdr = &desc->iscsi_header;		desc->data = mtask->data;	}	return cls_session;}static intiscsi_iser_set_param(struct iscsi_cls_conn *cls_conn,		     enum iscsi_param param, char *buf, int buflen){	int value;	switch (param) {	case ISCSI_PARAM_MAX_RECV_DLENGTH:		/* TBD */		break;	case ISCSI_PARAM_HDRDGST_EN:		sscanf(buf, "%d", &value);		if (value) {			printk(KERN_ERR "DataDigest wasn't negotiated to None");			return -EPROTO;		}		break;	case ISCSI_PARAM_DATADGST_EN:		sscanf(buf, "%d", &value);		if (value) {			printk(KERN_ERR "DataDigest wasn't negotiated to None");			return -EPROTO;		}		break;	case ISCSI_PARAM_IFMARKER_EN:		sscanf(buf, "%d", &value);		if (value) {			printk(KERN_ERR "IFMarker wasn't negotiated to No");			return -EPROTO;		}		break;	case ISCSI_PARAM_OFMARKER_EN:		sscanf(buf, "%d", &value);		if (value) {			printk(KERN_ERR "OFMarker wasn't negotiated to No");			return -EPROTO;		}		break;	default:		return iscsi_set_param(cls_conn, param, buf, buflen);	}	return 0;}static voidiscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats){	struct iscsi_conn *conn = cls_conn->dd_data;	stats->txdata_octets = conn->txdata_octets;	stats->rxdata_octets = conn->rxdata_octets;	stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;	stats->dataout_pdus = conn->dataout_pdus_cnt;	stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;	stats->datain_pdus = conn->datain_pdus_cnt; /* always 0 */	stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */	stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;	stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;	stats->custom_length = 3;	strcpy(stats->custom[0].desc, "qp_tx_queue_full");	stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */	strcpy(stats->custom[1].desc, "fmr_map_not_avail");	stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */;	strcpy(stats->custom[2].desc, "eh_abort_cnt");	stats->custom[2].value = conn->eh_abort_cnt;}static intiscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking,		      __u64 *ep_handle){	int err;	struct iser_conn *ib_conn;	err = iser_conn_init(&ib_conn);	if (err)		goto out;	err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking);	if (!err)		*ep_handle = (__u64)(unsigned long)ib_conn;out:	return err;}static intiscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms){	struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);	int rc;	if (!ib_conn)		return -EINVAL;	rc = wait_event_interruptible_timeout(ib_conn->wait,			     ib_conn->state == ISER_CONN_UP,			     msecs_to_jiffies(timeout_ms));	/* if conn establishment failed, return error code to iscsi */	if (!rc &&	    (ib_conn->state == ISER_CONN_TERMINATING ||	     ib_conn->state == ISER_CONN_DOWN))		rc = -1;	iser_err("ib conn %p rc = %d\n", ib_conn, rc);	if (rc > 0)		return 1; /* success, this is the equivalent of POLLOUT */	else if (!rc)		return 0; /* timeout */	else		return rc; /* signal */}static voidiscsi_iser_ep_disconnect(__u64 ep_handle){	struct iser_conn *ib_conn;	ib_conn = iscsi_iser_ib_conn_lookup(ep_handle);	if (!ib_conn)		return;	iser_err("ib conn %p state %d\n",ib_conn, ib_conn->state);	iser_conn_terminate(ib_conn);}static struct scsi_host_template iscsi_iser_sht = {	.module                 = THIS_MODULE,	.name                   = "iSCSI Initiator over iSER, v." DRV_VER,	.queuecommand           = iscsi_queuecommand,	.can_queue		= ISCSI_DEF_XMIT_CMDS_MAX - 1,	.sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,	.max_sectors		= 1024,	.cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,	.eh_abort_handler       = iscsi_eh_abort,	.eh_host_reset_handler	= iscsi_eh_host_reset,	.use_clustering         = DISABLE_CLUSTERING,	.proc_name              = "iscsi_iser",	.this_id                = -1,};static struct iscsi_transport iscsi_iser_transport = {	.owner                  = THIS_MODULE,	.name                   = "iser",	.caps                   = CAP_RECOVERY_L0 | CAP_MULTI_R2T,	.param_mask		= ISCSI_MAX_RECV_DLENGTH |				  ISCSI_MAX_XMIT_DLENGTH |				  ISCSI_HDRDGST_EN |				  ISCSI_DATADGST_EN |				  ISCSI_INITIAL_R2T_EN |				  ISCSI_MAX_R2T |				  ISCSI_IMM_DATA_EN |				  ISCSI_FIRST_BURST |				  ISCSI_MAX_BURST |				  ISCSI_PDU_INORDER_EN |				  ISCSI_DATASEQ_INORDER_EN |				  ISCSI_EXP_STATSN |				  ISCSI_PERSISTENT_PORT |				  ISCSI_PERSISTENT_ADDRESS |				  ISCSI_TARGET_NAME | ISCSI_TPGT |				  ISCSI_USERNAME | ISCSI_PASSWORD |				  ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,	.host_param_mask	= ISCSI_HOST_HWADDRESS |				  ISCSI_HOST_NETDEV_NAME |				  ISCSI_HOST_INITIATOR_NAME,	.host_template          = &iscsi_iser_sht,	.conndata_size		= sizeof(struct iscsi_conn),	.max_lun                = ISCSI_ISER_MAX_LUN,	.max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,	/* session management */	.create_session         = iscsi_iser_session_create,	.destroy_session        = iscsi_session_teardown,	/* connection management */	.create_conn            = iscsi_iser_conn_create,	.bind_conn              = iscsi_iser_conn_bind,	.destroy_conn           = iscsi_iser_conn_destroy,	.set_param              = iscsi_iser_set_param,	.get_conn_param		= iscsi_conn_get_param,	.get_session_param	= iscsi_session_get_param,	.start_conn             = iscsi_iser_conn_start,	.stop_conn              = iscsi_conn_stop,	/* iscsi host params */	.get_host_param		= iscsi_host_get_param,	.set_host_param		= iscsi_host_set_param,	/* IO */	.send_pdu		= iscsi_conn_send_pdu,	.get_stats		= iscsi_iser_conn_get_stats,	.init_cmd_task		= iscsi_iser_cmd_init,	.xmit_cmd_task		= iscsi_iser_ctask_xmit,	.xmit_mgmt_task		= iscsi_iser_mtask_xmit,	.cleanup_cmd_task	= iscsi_iser_cleanup_ctask,	/* recovery */	.session_recovery_timedout = iscsi_session_recovery_timedout,	.ep_connect             = iscsi_iser_ep_connect,	.ep_poll                = iscsi_iser_ep_poll,	.ep_disconnect          = iscsi_iser_ep_disconnect};static int __init iser_init(void){	int err;	iser_dbg("Starting iSER datamover...\n");	if (iscsi_max_lun < 1) {		printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun);		return -EINVAL;	}	iscsi_iser_transport.max_lun = iscsi_max_lun;	memset(&ig, 0, sizeof(struct iser_global));	ig.desc_cache = kmem_cache_create("iser_descriptors",					  sizeof (struct iser_desc),					  0, SLAB_HWCACHE_ALIGN,					  NULL);	if (ig.desc_cache == NULL)		return -ENOMEM;	/* device init is called only after the first addr resolution */	mutex_init(&ig.device_list_mutex);	INIT_LIST_HEAD(&ig.device_list);	mutex_init(&ig.connlist_mutex);	INIT_LIST_HEAD(&ig.connlist);	if (!iscsi_register_transport(&iscsi_iser_transport)) {		iser_err("iscsi_register_transport failed\n");		err = -EINVAL;		goto register_transport_failure;	}	return 0;register_transport_failure:	kmem_cache_destroy(ig.desc_cache);	return err;}static void __exit iser_exit(void){	iser_dbg("Removing iSER datamover...\n");	iscsi_unregister_transport(&iscsi_iser_transport);	kmem_cache_destroy(ig.desc_cache);}module_init(iser_init);module_exit(iser_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -