From: Jeff Garzik <jeff@garzik.org>
To: hail-devel@vger.kernel.org
Subject: [itd patch] use atcp
Date: Thu, 23 Sep 2010 17:42:06 -0400 [thread overview]
Message-ID: <20100923214206.GA24225@havoc.gtf.org> (raw)
This converts itd over to using [a local copy of] atcp.
Makefile.am | 1
iscsiutil.h | 52 +------------
target.c | 27 +++----
target.h | 2
util.c | 223 ++----------------------------------------------------------
5 files changed, 29 insertions(+), 276 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index d559165..9ef9e23 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,6 +7,7 @@ INCLUDES = @GLIB_CFLAGS@
sbin_PROGRAMS = itd
itd_SOURCES = \
+ atcp.c atcp.h \
elist.h scsi_cmd_codes.h iscsiutil.h iscsi.h parameters.h target.h \
main.c iscsi.c target.c util.c parameters.c
itd_LDADD = @GLIB_LIBS@ @CRYPTO_LIBS@ @EVENT_LIBS@
diff --git a/iscsiutil.h b/iscsiutil.h
index 5e5f5bf..568a16a 100644
--- a/iscsiutil.h
+++ b/iscsiutil.h
@@ -82,8 +82,8 @@
#endif
#include <string.h>
-#include <event.h>
#include "elist.h"
+#include "atcp.h"
/*
* Debugging Levels
@@ -138,11 +138,11 @@ extern void iscsi_print_buffer(uint8_t *, const size_t);
*/
struct target_session;
-struct tcp_write_state;
+struct atcp_wr_state;
extern const char *sopstr(uint8_t op);
extern int fsetflags(const char *prefix, int fd, int or_flags);
-extern int iscsi_writev(struct tcp_write_state *st,
+extern int iscsi_writev(struct atcp_wr_state *wst,
void *header, unsigned header_len,
const void *data, unsigned data_len);
@@ -241,53 +241,11 @@ typedef struct name { \
extern size_t strlcpy(char *, const char *, size_t);
#endif
-enum {
- TCP_MAX_WR_IOV = 512, /* arbitrary, pick better one */
- TCP_MAX_WR_CNT = 10000,/* arbitrary, pick better one */
-};
-
-struct tcp_write_state {
- int fd;
- struct list_head write_q;
- struct list_head write_compl_q;
- size_t write_cnt; /* water level */
- size_t write_cnt_max;
- bool writing;
- struct event write_ev;
-
- void *priv; /* useable by any app */
-
- /* stats */
- unsigned long opt_write;
-};
-
-struct tcp_write {
- const void *buf; /* write buffer pointer */
- int togo; /* write buffer remainder */
-
- int length; /* length for accounting */
-
- /* callback */
- bool (*cb)(struct tcp_write_state *, void *, bool);
- void *cb_data; /* data passed to cb */
-
- struct list_head node;
-};
-
-extern int tcp_writeq(struct tcp_write_state *st, const void *buf, unsigned int buflen,
- bool (*cb)(struct tcp_write_state *, void *, bool),
- void *cb_data);
-extern bool tcp_wr_cb_free(struct tcp_write_state *st, void *cb_data, bool done);
-extern void tcp_write_init(struct tcp_write_state *st, int fd);
-extern void tcp_write_exit(struct tcp_write_state *st);
-extern bool tcp_write_start(struct tcp_write_state *st);
-extern bool tcp_write_run_compl(struct tcp_write_state *st);
-
-extern void send_padding(struct tcp_write_state *st, unsigned int len_out);
+extern void send_padding(struct atcp_wr_state *wst, unsigned int len_out);
extern void *header_get(void);
extern void header_put(void *mem);
-extern bool hdr_cb_free(struct tcp_write_state *st, void *cb_data, bool done);
+extern bool hdr_cb_free(struct atcp_wr_state *, void *, bool);
extern void hdrs_free_all(void);
static inline int padding_bytes(unsigned int len_out)
diff --git a/target.c b/target.c
index 7ef7d72..c68f857 100644
--- a/target.c
+++ b/target.c
@@ -613,9 +613,9 @@ static int task_command_t(struct target_session *sess, const uint8_t *header)
goto err_out_hdr;
}
- tcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
+ atcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
hdr_cb_free, rsp_header);
- tcp_write_start(&sess->wst);
+ atcp_write_start(&sess->wst);
return 0;
@@ -839,18 +839,18 @@ static int text_command_t(struct target_session *sess, const uint8_t *header)
goto err_out_hdr;
}
- tcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
+ atcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
hdr_cb_free, rsp_header);
if (len_out) {
- tcp_writeq(&sess->wst, text_out, len_out,
- tcp_wr_cb_free, text_out);
+ atcp_writeq(&sess->wst, text_out, len_out,
+ atcp_cb_free, text_out);
text_out = NULL;
send_padding(&sess->wst, len_out);
}
- tcp_write_start(&sess->wst);
+ atcp_write_start(&sess->wst);
free(text_in);
free(text_out);
@@ -1228,9 +1228,9 @@ static int logout_command_t(struct target_session *sess, const uint8_t *header)
return -1;
}
- tcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
+ atcp_writeq(&sess->wst, rsp_header, ISCSI_HEADER_LEN,
hdr_cb_free, rsp_header);
- tcp_write_start(&sess->wst);
+ atcp_write_start(&sess->wst);
iscsi_trace(TRACE_ISCSI_DEBUG, __FILE__, __LINE__,
"sent logout response OK\n");
@@ -1494,9 +1494,9 @@ static int send_r2t(struct target_session *sess)
sess->xfer.r2t.tag, sess->xfer.r2t.transfer_tag,
sess->xfer.r2t.length, sess->xfer.r2t.offset);
- tcp_writeq(&sess->wst, header, ISCSI_HEADER_LEN,
+ atcp_writeq(&sess->wst, header, ISCSI_HEADER_LEN,
hdr_cb_free, header);
- tcp_write_start(&sess->wst);
+ atcp_write_start(&sess->wst);
sess->xfer.r2t_flag = 1;
sess->xfer.r2t.R2TSN += 1;
@@ -1761,7 +1761,7 @@ int target_sess_cleanup(struct target_session *sess)
event_del(&sess->ev);
- tcp_write_exit(&sess->wst);
+ atcp_wr_exit(&sess->wst);
/* Terminate connection */
if (sess->fd >= 0)
@@ -1965,7 +1965,7 @@ restart:
break;
}
- tcp_write_run_compl(&sess->wst);
+ atcp_write_run_compl(&sess->wst);
return;
err_out:
@@ -2013,7 +2013,8 @@ int target_accept(struct globals *gp, struct server_socket *sock)
sess->globals = gp;
- tcp_write_init(&sess->wst, sess->fd);
+ atcp_wr_init(&sess->wst, sess);
+ atcp_wr_set_fd(&sess->wst, sess->fd);
event_set(&sess->ev, sess->fd, EV_READ | EV_PERSIST,
target_tcp_evt, sess);
diff --git a/target.h b/target.h
index ddedb0a..0e9bc54 100644
--- a/target.h
+++ b/target.h
@@ -220,7 +220,7 @@ struct target_session {
struct sockaddr addr;
struct event ev;
- struct tcp_write_state wst;
+ struct atcp_wr_state wst;
struct session_xfer xfer;
diff --git a/util.c b/util.c
index c3e4455..eb41f84 100644
--- a/util.c
+++ b/util.c
@@ -307,7 +307,7 @@ void header_put(void *mem)
g_trash_stack_push(&free_headers, mem);
}
-bool hdr_cb_free(struct tcp_write_state *st, void *cb_data, bool done)
+bool hdr_cb_free(struct atcp_wr_state *wst, void *cb_data, bool done)
{
header_put(cb_data);
return false;
@@ -326,7 +326,7 @@ void hdrs_free_all(void)
}
}
-void send_padding(struct tcp_write_state *st, unsigned int len_out)
+void send_padding(struct atcp_wr_state *st, unsigned int len_out)
{
int pad_len;
static const char pad_buf[4] = { 0, 0, 0, 0 };
@@ -335,7 +335,7 @@ void send_padding(struct tcp_write_state *st, unsigned int len_out)
if (!pad_len)
return;
- tcp_writeq(st, pad_buf, pad_len, NULL, NULL);
+ atcp_writeq(st, pad_buf, pad_len, NULL, NULL);
}
/*
@@ -348,7 +348,7 @@ void send_padding(struct tcp_write_state *st, unsigned int len_out)
* data, else send as two separate messages.
*/
-int iscsi_writev(struct tcp_write_state *st,
+int iscsi_writev(struct atcp_wr_state *st,
void *header, unsigned header_len,
const void *data, unsigned data_len)
{
@@ -356,7 +356,7 @@ int iscsi_writev(struct tcp_write_state *st,
"NET: writing %u header bytes, %u data bytes\n",
header_len, data_len);
- tcp_writeq(st, header, header_len, hdr_cb_free, header);
+ atcp_writeq(st, header, header_len, hdr_cb_free, header);
if (data && data_len > 0) {
void *mem;
@@ -364,13 +364,13 @@ int iscsi_writev(struct tcp_write_state *st,
mem = g_memdup(data, data_len);
if (!mem)
return -1;
- tcp_writeq(st, mem, data_len,
- tcp_wr_cb_free, mem);
+ atcp_writeq(st, mem, data_len,
+ atcp_cb_free, mem);
}
send_padding(st, data_len);
- tcp_write_start(st);
+ atcp_write_start(st);
return header_len + data_len;
}
@@ -712,213 +712,6 @@ int fsetflags(const char *prefix, int fd, int or_flags)
return rc;
}
-static void tcp_write_complete(struct tcp_write_state *st, struct tcp_write *tmp)
-{
- list_del(&tmp->node);
- list_add_tail(&tmp->node, &st->write_compl_q);
-}
-
-bool tcp_wr_cb_free(struct tcp_write_state *st, void *cb_data, bool done)
-{
- free(cb_data);
- return false;
-}
-
-static bool tcp_write_free(struct tcp_write_state *st, struct tcp_write *tmp,
- bool done)
-{
- bool rcb = false;
-
- st->write_cnt -= tmp->length;
- list_del_init(&tmp->node);
- if (tmp->cb)
- rcb = tmp->cb(st, tmp->cb_data, done);
- free(tmp);
-
- return rcb;
-}
-
-static void tcp_write_free_all(struct tcp_write_state *st)
-{
- struct tcp_write *wr, *tmp;
-
- list_for_each_entry_safe(wr, tmp, &st->write_compl_q, node) {
- tcp_write_free(st, wr, true);
- }
- list_for_each_entry_safe(wr, tmp, &st->write_q, node) {
- tcp_write_free(st, wr, false);
- }
-}
-
-bool tcp_write_run_compl(struct tcp_write_state *st)
-{
- struct tcp_write *wr;
- bool do_loop;
-
- do_loop = false;
- while (!list_empty(&st->write_compl_q)) {
- wr = list_entry(st->write_compl_q.next, struct tcp_write,
- node);
- do_loop |= tcp_write_free(st, wr, true);
- }
- return do_loop;
-}
-
-static bool tcp_writable(struct tcp_write_state *st)
-{
- int n_iov;
- struct tcp_write *tmp;
- ssize_t rc;
- struct iovec iov[TCP_MAX_WR_IOV];
-
- /* accumulate pending writes into iovec */
- n_iov = 0;
- list_for_each_entry(tmp, &st->write_q, node) {
- if (n_iov == TCP_MAX_WR_IOV)
- break;
- /* bleh, struct iovec should declare iov_base const */
- iov[n_iov].iov_base = (void *) tmp->buf;
- iov[n_iov].iov_len = tmp->togo;
- n_iov++;
- }
-
- /* execute non-blocking write */
-do_write:
- rc = writev(st->fd, iov, n_iov);
- if (rc < 0) {
- if (errno == EINTR)
- goto do_write;
- if (errno != EAGAIN)
- goto err_out;
- return true;
- }
-
- /* iterate through write queue, issuing completions based on
- * amount of data written
- */
- while (rc > 0) {
- int sz;
-
- /* get pointer to first record on list */
- tmp = list_entry(st->write_q.next, struct tcp_write, node);
-
- /* mark data consumed by decreasing tmp->len */
- sz = (tmp->togo < rc) ? tmp->togo : rc;
- tmp->togo -= sz;
- tmp->buf += sz;
- rc -= sz;
-
- /* if tmp->len reaches zero, write is complete,
- * so schedule it for clean up (cannot call callback
- * right away or an endless recursion will result)
- */
- if (tmp->togo == 0)
- tcp_write_complete(st, tmp);
- }
-
- /* if we emptied the queue, clear write notification */
- if (list_empty(&st->write_q)) {
- st->writing = false;
- if (event_del(&st->write_ev) < 0)
- goto err_out;
- }
-
- return true;
-
-err_out:
- tcp_write_free_all(st);
- return false;
-}
-
-bool tcp_write_start(struct tcp_write_state *st)
-{
- if (list_empty(&st->write_q))
- return true; /* loop, not poll */
-
- /* if write-poll already active, nothing further to do */
- if (st->writing)
- return false; /* poll wait */
-
- /* attempt optimistic write, in hopes of avoiding poll,
- * or at least refill the write buffers so as to not
- * get -immediately- called again by the kernel
- */
- tcp_writable(st);
- if (list_empty(&st->write_q)) {
- st->opt_write++;
- return true; /* loop, not poll */
- }
-
- if (event_add(&st->write_ev, NULL) < 0)
- return true; /* loop, not poll */
-
- st->writing = true;
-
- return false; /* poll wait */
-}
-
-int tcp_writeq(struct tcp_write_state *st, const void *buf, unsigned int buflen,
- bool (*cb)(struct tcp_write_state *, void *, bool),
- void *cb_data)
-{
- struct tcp_write *wr;
-
- if (!buf || !buflen)
- return -EINVAL;
-
- wr = calloc(1, sizeof(struct tcp_write));
- if (!wr)
- return -ENOMEM;
-
- wr->buf = buf;
- wr->togo = buflen;
- wr->length = buflen;
- wr->cb = cb;
- wr->cb_data = cb_data;
- list_add_tail(&wr->node, &st->write_q);
- st->write_cnt += buflen;
- if (st->write_cnt > st->write_cnt_max)
- st->write_cnt_max = st->write_cnt;
-
- return 0;
-}
-
-size_t tcp_wqueued(struct tcp_write_state *st)
-{
- return st->write_cnt;
-}
-
-static void tcp_wr_evt(int fd, short events, void *userdata)
-{
- struct tcp_write_state *st = userdata;
-
- tcp_writable(st);
- tcp_write_run_compl(st);
-}
-
-void tcp_write_init(struct tcp_write_state *st, int fd)
-{
- memset(st, 0, sizeof(*st));
-
- st->fd = fd;
-
- INIT_LIST_HEAD(&st->write_q);
- INIT_LIST_HEAD(&st->write_compl_q);
-
- st->write_cnt_max = TCP_MAX_WR_CNT;
-
- event_set(&st->write_ev, fd, EV_WRITE | EV_PERSIST,
- tcp_wr_evt, st);
-}
-
-void tcp_write_exit(struct tcp_write_state *st)
-{
- if (st->writing)
- event_del(&st->write_ev);
-
- tcp_write_free_all(st);
-}
-
/*
* CRC32C chksum,
* as copied from Linux kernel's crypto/crc32c.c
reply other threads:[~2010-09-23 21:42 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100923214206.GA24225@havoc.gtf.org \
--to=jeff@garzik.org \
--cc=hail-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).