From 18eed2a721adb13ab374700d7ded3cfb26ed73c6 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 20 Feb 2006 09:56:56 +0100 Subject: [PATCH] [PATCH] blktrace: use send() for last data on quit in sendfile() path We need to do that, as we can only use full subbufs in the sendfile() path. --- blktrace.c | 58 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/blktrace.c b/blktrace.c index 9c4dd19..c8f9ffb 100644 --- a/blktrace.c +++ b/blktrace.c @@ -553,6 +553,26 @@ static int mmap_subbuf(struct thread_information *tip, unsigned int maxlen) return -1; } +/* + * Use the copy approach for pipes and network + */ +static int get_subbuf(struct thread_information *tip, unsigned int maxlen) +{ + struct tip_subbuf *ts = malloc(sizeof(*ts)); + int ret; + + ts->buf = malloc(buf_size); + ts->max_len = maxlen; + + ret = read_data(tip, ts->buf, ts->max_len); + if (ret > 0) { + ts->len = ret; + return subbuf_fifo_queue(tip, ts); + } + + return ret; +} + static int get_subbuf_sendfile(struct thread_information *tip, unsigned int maxlen) { @@ -561,6 +581,14 @@ static int get_subbuf_sendfile(struct thread_information *tip, unsigned int ready, this_size; int err; + wait_for_data(tip); + + /* + * hack to get last data out, we can't use sendfile for that + */ + if (is_done()) + return get_subbuf(tip, maxlen); + if (fstat(tip->fd, &sb) < 0) { perror("trace stat"); return 1; @@ -595,26 +623,6 @@ static int get_subbuf_sendfile(struct thread_information *tip, return 0; } -/* - * Use the copy approach for pipes and network - */ -static int get_subbuf(struct thread_information *tip, unsigned int maxlen) -{ - struct tip_subbuf *ts = malloc(sizeof(*ts)); - int ret; - - ts->buf = malloc(buf_size); - ts->max_len = maxlen; - - ret = read_data(tip, ts->buf, ts->max_len); - if (ret > 0) { - ts->len = ret; - return subbuf_fifo_queue(tip, ts); - } - - return ret; -} - static void close_thread(struct thread_information *tip) { if (tip->fd != -1) @@ -756,6 +764,7 @@ static int flush_subbuf_net(struct thread_information *tip, if (write_data_net(net_out_fd, ts->buf, ts->len)) return 1; + tip->data_read += ts->len; free(ts->buf); free(ts); return 0; @@ -767,6 +776,14 @@ static int flush_subbuf_sendfile(struct thread_information *tip, size_t padding; unsigned subbuf; unsigned len; + + /* + * currently we cannot use sendfile() on the last bytes read, as they + * may not be a full subbuffer. get_subbuf_sendfile() falls back to + * the read approach for those, so use send() to ship them out + */ + if (ts->buf) + return flush_subbuf_net(tip, ts); subbuf = (ts->offset / buf_size) % buf_nr; padding = get_subbuf_padding(tip, subbuf); @@ -779,6 +796,7 @@ static int flush_subbuf_sendfile(struct thread_information *tip, return 1; } + tip->data_read += ts->len; free(ts); return 0; } -- 2.25.1