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

📄 conn.c

📁 iscsi企业级target.很好用
💻 C
字号:
/* * Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com> * * Released under the terms of the GNU GPL v2.0. */#include <linux/file.h>#include <linux/ip.h>#include <net/tcp.h>#include "iscsi.h"#include "iscsi_dbg.h"#include "digest.h"static void print_conn_state(char *p, size_t size, unsigned long state){	if (test_bit(CONN_ACTIVE, &state))		snprintf(p, size, "%s", "active");	else if (test_bit(CONN_CLOSING, &state))		snprintf(p, size, "%s", "closing");	else		snprintf(p, size, "%s", "unknown");}static void print_digest_state(char *p, size_t size, unsigned long flags){	if (DIGEST_NONE & flags)		snprintf(p, size, "%s", "none");	else if (DIGEST_CRC32C & flags)		snprintf(p, size, "%s", "crc32c");	else		snprintf(p, size, "%s", "unknown");}void conn_info_show(struct seq_file *seq, struct iscsi_session *session){	struct iscsi_conn *conn;	struct sock *sk;	char buf[64];	list_for_each_entry(conn, &session->conn_list, list) {		sk = conn->sock->sk;		switch (sk->sk_family) {		case AF_INET:			snprintf(buf, sizeof(buf),				 "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr));			break;		case AF_INET6:			snprintf(buf, sizeof(buf),				 "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]",				 NIP6(inet6_sk(sk)->daddr));			break;		default:			break;		}		seq_printf(seq, "\t\tcid:%u ip:%s ", conn->cid, buf);		print_conn_state(buf, sizeof(buf), conn->state);		seq_printf(seq, "state:%s ", buf);		print_digest_state(buf, sizeof(buf), conn->hdigest_type);		seq_printf(seq, "hd:%s ", buf);		print_digest_state(buf, sizeof(buf), conn->ddigest_type);		seq_printf(seq, "dd:%s\n", buf);	}}struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid){	struct iscsi_conn *conn;	list_for_each_entry(conn, &session->conn_list, list) {		if (conn->cid == cid)			return conn;	}	return NULL;}static void iet_state_change(struct sock *sk){	struct iscsi_conn *conn = sk->sk_user_data;	struct iscsi_target *target = conn->session->target;	if (sk->sk_state != TCP_ESTABLISHED)		conn_close(conn);	else		nthread_wakeup(target);	target->nthread_info.old_state_change(sk);}static void iet_data_ready(struct sock *sk, int len){	struct iscsi_conn *conn = sk->sk_user_data;	struct iscsi_target *target = conn->session->target;	nthread_wakeup(target);	target->nthread_info.old_data_ready(sk, len);}static void iet_socket_bind(struct iscsi_conn *conn){	int opt = 1;	mm_segment_t oldfs;	struct iscsi_session *session = conn->session;	struct iscsi_target *target = session->target;	dprintk(D_GENERIC, "%llu\n", (unsigned long long) session->sid);	conn->sock = SOCKET_I(conn->file->f_dentry->d_inode);	conn->sock->sk->sk_user_data = conn;	write_lock(&conn->sock->sk->sk_callback_lock);	target->nthread_info.old_state_change = conn->sock->sk->sk_state_change;	conn->sock->sk->sk_state_change = iet_state_change;	target->nthread_info.old_data_ready = conn->sock->sk->sk_data_ready;	conn->sock->sk->sk_data_ready = iet_data_ready;	write_unlock(&conn->sock->sk->sk_callback_lock);	oldfs = get_fs();	set_fs(get_ds());	conn->sock->ops->setsockopt(conn->sock, SOL_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt));	set_fs(oldfs);}int conn_free(struct iscsi_conn *conn){	dprintk(D_GENERIC, "%p %#Lx %u\n", conn->session,		(unsigned long long) conn->session->sid, conn->cid);	assert(atomic_read(&conn->nr_cmnds) == 0);	assert(list_empty(&conn->pdu_list));	assert(list_empty(&conn->write_list));	list_del(&conn->list);	list_del(&conn->poll_list);	digest_cleanup(conn);	kfree(conn);	return 0;}static int iet_conn_alloc(struct iscsi_session *session, struct conn_info *info){	struct iscsi_conn *conn;	dprintk(D_SETUP, "%#Lx:%u\n", (unsigned long long) session->sid, info->cid);	conn = kmalloc(sizeof(*conn), GFP_KERNEL);	if (!conn)		return -ENOMEM;	memset(conn, 0, sizeof(*conn));	conn->session = session;	conn->cid = info->cid;	conn->stat_sn = info->stat_sn;	conn->exp_stat_sn = info->exp_stat_sn;	conn->hdigest_type = info->header_digest;	conn->ddigest_type = info->data_digest;	if (digest_init(conn) < 0) {		kfree(conn);		return -ENOMEM;	}	spin_lock_init(&conn->list_lock);	atomic_set(&conn->nr_cmnds, 0);	atomic_set(&conn->nr_busy_cmnds, 0);	INIT_LIST_HEAD(&conn->pdu_list);	INIT_LIST_HEAD(&conn->write_list);	INIT_LIST_HEAD(&conn->poll_list);	list_add(&conn->list, &session->conn_list);	set_bit(CONN_ACTIVE, &conn->state);	conn->file = fget(info->fd);	iet_socket_bind(conn);	list_add(&conn->poll_list, &session->target->nthread_info.active_conns);	nthread_wakeup(conn->session->target);	return 0;}void conn_close(struct iscsi_conn *conn){	if (test_and_clear_bit(CONN_ACTIVE, &conn->state))		set_bit(CONN_CLOSING, &conn->state);	nthread_wakeup(conn->session->target);}int conn_add(struct iscsi_session *session, struct conn_info *info){	struct iscsi_conn *conn;	int err = -EEXIST;	if ((conn = conn_lookup(session, info->cid)))		return err;	return iet_conn_alloc(session, info);}int conn_del(struct iscsi_session *session, struct conn_info *info){	struct iscsi_conn *conn;	int err = -EEXIST;	if (!(conn = conn_lookup(session, info->cid)))		return err;	conn_close(conn);	return 0;}

⌨️ 快捷键说明

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