Updated for libhail's anet.  Not yet committed, waiting for more time to
pass.

 Makefile.am  |    2 
 configure.ac |    1 
 iscsiutil.h  |   52 +------------
 target.c     |   53 ++++++++++----
 target.h     |    3 
 util.c       |  223 ++---------------------------------------------------------
 6 files changed, 57 insertions(+), 277 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index d559165..d99ab0c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,7 +9,7 @@ sbin_PROGRAMS   = itd
 itd_SOURCES    = \
        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@
+itd_LDADD      = @GLIB_LIBS@ @CRYPTO_LIBS@ @EVENT_LIBS@ @HAIL_LIBS@
 
 EXTRA_DIST     = autogen.sh
 
diff --git a/configure.ac b/configure.ac
index 7cbbe3f..e2f6731 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,6 +71,7 @@ dnl autoconf output generation
 dnl --------------------------
 
 AM_PATH_GLIB_2_0(2.0.0)
+PKG_CHECK_MODULES(HAIL, libhail)
 
 AC_SUBST(CRYPTO_LIBS)
 AC_SUBST(EVENT_LIBS)
diff --git a/iscsiutil.h b/iscsiutil.h
index 5e5f5bf..2430c48 100644
--- a/iscsiutil.h
+++ b/iscsiutil.h
@@ -82,8 +82,8 @@
 #endif
 
 #include <string.h>
-#include <event.h>
 #include "elist.h"
+#include <anet.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..be6a88b 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:
@@ -1982,6 +1982,32 @@ static void target_tcp_evt(int fd, short events, void 
*userdata)
        target_read_evt(sess);
 }
 
+static int target_sess_le_wset(void *ev_info, int fd, atcp_ev_func cb, void 
*cb_data)
+{
+       struct event *ev = ev_info;
+
+       event_set(ev, fd, EV_WRITE | EV_PERSIST, cb, cb_data);
+       return 0;
+}
+
+static int target_sess_le_add(void *ev_info, const struct timeval *tv)
+{
+       struct event *ev = ev_info;
+       return event_add(ev, tv);
+}
+
+static int target_sess_le_del(void *ev_info)
+{
+       struct event *ev = ev_info;
+       return event_del(ev);
+}
+
+static const struct atcp_wr_ops libevent_wr_ops = {
+       .ev_wset        = target_sess_le_wset,
+       .ev_add         = target_sess_le_add,
+       .ev_del         = target_sess_le_del,
+};
+
 int target_accept(struct globals *gp, struct server_socket *sock)
 {
        struct target_session *sess;
@@ -2013,7 +2039,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, &libevent_wr_ops, &sess->write_ev, 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..e764730 100644
--- a/target.h
+++ b/target.h
@@ -219,8 +219,9 @@ struct target_session {
        int                     fd;
        struct sockaddr         addr;
        struct event            ev;
+       struct event            write_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
--
To unsubscribe from this list: send the line "unsubscribe hail-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to