[Stgt-devel] [PATCH 10/20] iser connection transport data

FUJITA Tomonori tomof
Wed Nov 14 15:33:27 CET 2007


From: Pete Wyckoff <pw at osc.edu>
Subject: [Stgt-devel] [PATCH 10/20] iser connection transport data
Date: Tue, 16 Oct 2007 11:20:44 -0400

> Add a private data field to iscsi_connection to hold state for the
> transport, and allocate room for it at connection allocation time.
> 
> Move the TCP socket fd from generic code into this private data region.
> 
> Also virtualize getsockname and getpeername as TCP and RDMA determine
> those IP addresses differently.
> 
> Signed-off-by: Pete Wyckoff <pw at osc.edu>
> ---
>  usr/iscsi/conn.c      |   21 +++++++-------
>  usr/iscsi/iscsi_tcp.c |   72 ++++++++++++++++++++++++++++++++++++------------
>  usr/iscsi/iscsid.c    |   58 +++++++++++++++++++-------------------
>  usr/iscsi/iscsid.h    |   14 +++++-----
>  usr/iscsi/session.c   |    2 +-
>  usr/iscsi/target.c    |   10 +++---
>  usr/iscsi/transport.h |   20 +++++++++----
>  7 files changed, 120 insertions(+), 77 deletions(-)

Merged, thanks.

Moving connection allocation to transport would work better for iSER?

This patch is against the lastest git tree
(09532079071d65ec62dae982324ab07a895e16f1).

=
From: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
Date: Wed, 14 Nov 2007 20:31:33 +0900
Subject: [PATCH] move connection allocation to transport

Signed-off-by: FUJITA Tomonori <fujita.tomonori at lab.ntt.co.jp>
---
 usr/iscsi/conn.c      |   31 +++++-------------
 usr/iscsi/iscsi_tcp.c |   80 +++++++++++++++++++++++++++++++-----------------
 usr/iscsi/iscsid.h    |    4 +-
 usr/iscsi/transport.h |    2 +
 4 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/usr/iscsi/conn.c b/usr/iscsi/conn.c
index 1e9dace..e131549 100644
--- a/usr/iscsi/conn.c
+++ b/usr/iscsi/conn.c
@@ -42,24 +42,16 @@ void conn_add_to_session(struct iscsi_connection *conn, struct iscsi_session *se
 	list_add(&conn->clist, &session->conn_list);
 }
 
-struct iscsi_connection *conn_alloc(unsigned int trans_len)
+int conn_init(struct iscsi_connection *conn)
 {
-	struct iscsi_connection *conn;
-
-	conn = zalloc(sizeof(*conn) + trans_len);
-	if (!conn)
-		return NULL;
-
 	conn->req_buffer = malloc(INCOMING_BUFSIZE);
-	if (!conn->req_buffer) {
-		free(conn);
-		return NULL;
-	}
+	if (!conn->req_buffer)
+		return -ENOMEM;
+
 	conn->rsp_buffer = malloc(INCOMING_BUFSIZE);
 	if (!conn->rsp_buffer) {
 		free(conn->req_buffer);
-		free(conn);
-		return NULL;
+		return -ENOMEM;
 	}
 
 	conn->refcount = 1;
@@ -69,22 +61,17 @@ struct iscsi_connection *conn_alloc(unsigned int trans_len)
 	INIT_LIST_HEAD(&conn->clist);
 	INIT_LIST_HEAD(&conn->tx_clist);
 
-	if (trans_len)
-		conn->trans_data = &conn[1];
-
-	return conn;
+	return 0;
 }
 
-static void conn_free(struct iscsi_connection *conn)
+void conn_exit(struct iscsi_connection *conn)
 {
 	struct iscsi_session *session = conn->session;
 
-	dprintf("freeing connection\n");
 	list_del(&conn->clist);
 	free(conn->req_buffer);
 	free(conn->rsp_buffer);
 	free(conn->initiator);
-	free(conn);
 
 	if (session)
 		session_put(session);
@@ -145,8 +132,8 @@ done:
 void conn_put(struct iscsi_connection *conn)
 {
 	conn->refcount--;
-	if (conn->refcount == 0)
-		conn_free(conn);
+	if (!conn->refcount)
+		conn->tp->ep_release(conn);
 }
 
 int conn_get(struct iscsi_connection *conn)
diff --git a/usr/iscsi/iscsi_tcp.c b/usr/iscsi/iscsi_tcp.c
index 31e7b29..b3f730d 100644
--- a/usr/iscsi/iscsi_tcp.c
+++ b/usr/iscsi/iscsi_tcp.c
@@ -42,10 +42,17 @@
 
 static void iscsi_tcp_event_handler(int fd, int events, void *data);
 
-struct tcp_conn_info {
+struct iscsi_tcp_connection {
 	int fd;
+
+	struct iscsi_connection iscsi_conn;
 };
 
+static inline struct iscsi_tcp_connection *TCP_CONN(struct iscsi_connection *conn)
+{
+	return container_of(conn, struct iscsi_tcp_connection, iscsi_conn);
+}
+
 static int set_keepalive(int fd)
 {
 	int ret, opt;
@@ -78,7 +85,7 @@ static void accept_connection(int afd, int events, void *data)
 	struct sockaddr_storage from;
 	socklen_t namesize;
 	struct iscsi_connection *conn;
-	struct tcp_conn_info *tci;
+	struct iscsi_tcp_connection *tcp_conn;
 	int fd, err;
 
 	dprintf("%d\n", afd);
@@ -94,24 +101,32 @@ static void accept_connection(int afd, int events, void *data)
 	if (err)
 		goto out;
 
-	conn = conn_alloc(sizeof(*tci));
-	if (!conn)
+	tcp_conn = zalloc(sizeof(*tcp_conn));
+	if (!tcp_conn)
 		goto out;
 
-	tci = conn->trans_data;
-	tci->fd = fd;
+	conn = &tcp_conn->iscsi_conn;
+
+	err = conn_init(conn);
+	if (err) {
+		free(tcp_conn);
+		goto out;
+	}
+
+	tcp_conn->fd = fd;
 	conn->tp = &iscsi_tcp;
 
 	conn_read_pdu(conn);
 	set_non_blocking(fd);
 
 	err = tgt_event_add(fd, EPOLLIN, iscsi_tcp_event_handler, conn);
-	if (err)
-		goto free_conn;
+	if (err) {
+		conn_exit(conn);
+		free(tcp_conn);
+		goto out;
+	}
 
 	return;
-free_conn:
-	free(conn);
 out:
 	close(fd);
 	return;
@@ -213,46 +228,54 @@ static int iscsi_tcp_init(void)
 static size_t iscsi_tcp_read(struct iscsi_connection *conn, void *buf,
 			     size_t nbytes)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
-	return read(tci->fd, buf, nbytes);
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
+	return read(tcp_conn->fd, buf, nbytes);
 }
 
 static size_t iscsi_tcp_write_begin(struct iscsi_connection *conn, void *buf,
 				    size_t nbytes)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 	int opt = 1;
 
-	setsockopt(tci->fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt));
-	return write(tci->fd, buf, nbytes);
+	setsockopt(tcp_conn->fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt));
+	return write(tcp_conn->fd, buf, nbytes);
 }
 
 static void iscsi_tcp_write_end(struct iscsi_connection *conn)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 	int opt = 0;
 
-	setsockopt(tci->fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt));
+	setsockopt(tcp_conn->fd, SOL_TCP, TCP_CORK, &opt, sizeof(opt));
 }
 
 static size_t iscsi_tcp_close(struct iscsi_connection *conn)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
+
+	tgt_event_del(tcp_conn->fd);
+	return close(tcp_conn->fd);
+}
+
+static void iscsi_tcp_release(struct iscsi_connection *conn)
+{
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 
-	tgt_event_del(tci->fd);
-	return close(tci->fd);
+	conn_exit(conn);
+	free(tcp_conn);
 }
 
 static int iscsi_tcp_show(struct iscsi_connection *conn, char *buf, int rest)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 	int err, total = 0;
 	socklen_t slen;
 	char dst[INET6_ADDRSTRLEN];
 	struct sockaddr_storage from;
 
 	slen = sizeof(from);
-	err = getpeername(tci->fd, (struct sockaddr *) &from, &slen);
+	err = getpeername(tcp_conn->fd, (struct sockaddr *) &from, &slen);
 	if (err < 0) {
 		eprintf("%m\n");
 		return 0;
@@ -272,10 +295,10 @@ static int iscsi_tcp_show(struct iscsi_connection *conn, char *buf, int rest)
 
 void iscsi_event_modify(struct iscsi_connection *conn, int events)
 {
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 	int ret;
-	struct tcp_conn_info *tci = conn->trans_data;
 
-	ret = tgt_event_modify(tci->fd, events);
+	ret = tgt_event_modify(tcp_conn->fd, events);
 	if (ret)
 		eprintf("tgt_event_modify failed\n");
 }
@@ -294,17 +317,17 @@ void iscsi_tcp_free_data_buf(struct iscsi_connection *conn, void *buf)
 int iscsi_tcp_getsockname(struct iscsi_connection *conn, struct sockaddr *sa,
 			  socklen_t *len)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 
-	return getsockname(tci->fd, sa, len);
+	return getsockname(tcp_conn->fd, sa, len);
 }
 
 int iscsi_tcp_getpeername(struct iscsi_connection *conn, struct sockaddr *sa,
 			  socklen_t *len)
 {
-	struct tcp_conn_info *tci = conn->trans_data;
+	struct iscsi_tcp_connection *tcp_conn = TCP_CONN(conn);
 
-	return getpeername(tci->fd, sa, len);
+	return getpeername(tcp_conn->fd, sa, len);
 }
 
 struct iscsi_transport iscsi_tcp = {
@@ -315,6 +338,7 @@ struct iscsi_transport iscsi_tcp = {
 	.ep_write_begin		= iscsi_tcp_write_begin,
 	.ep_write_end		= iscsi_tcp_write_end,
 	.ep_close		= iscsi_tcp_close,
+	.ep_release		= iscsi_tcp_release,
 	.ep_show		= iscsi_tcp_show,
 	.ep_event_modify	= iscsi_event_modify,
 	.alloc_data_buf		= iscsi_tcp_alloc_data_buf,
diff --git a/usr/iscsi/iscsid.h b/usr/iscsi/iscsid.h
index fe4c556..e5a7f2c 100644
--- a/usr/iscsi/iscsid.h
+++ b/usr/iscsi/iscsid.h
@@ -179,7 +179,6 @@ struct iscsi_connection {
 	} auth;
 
 	struct iscsi_transport *tp;
-	void *trans_data;   /* transport specific data */
 };
 
 #define STATE_FREE		0
@@ -245,7 +244,8 @@ extern struct list_head iscsi_targets_list;
 extern int cmnd_exec_auth_chap(struct iscsi_connection *conn);
 
 /* conn.c */
-extern struct iscsi_connection *conn_alloc(unsigned int trans_len);
+extern int conn_init(struct iscsi_connection *conn);
+extern void conn_exit(struct iscsi_connection *conn);
 extern void conn_close(struct iscsi_connection *conn);
 extern void conn_put(struct iscsi_connection *conn);
 extern int conn_get(struct iscsi_connection *conn);
diff --git a/usr/iscsi/transport.h b/usr/iscsi/transport.h
index 788fa41..f7239c7 100644
--- a/usr/iscsi/transport.h
+++ b/usr/iscsi/transport.h
@@ -16,6 +16,8 @@ struct iscsi_transport {
 				 size_t nbytes);
 	void (*ep_write_end)(struct iscsi_connection *conn);
 	size_t (*ep_close)(struct iscsi_connection *conn);
+	void (*ep_release)(struct iscsi_connection *conn);
+
 	int (*ep_show)(struct iscsi_connection *conn, char *buf, int rest);
 	void (*ep_event_modify)(struct iscsi_connection *conn, int events);
 	void *(*alloc_data_buf)(struct iscsi_connection *conn, size_t sz);
-- 
1.5.3.4




More information about the stgt mailing list