[PATCH] blktrace: use send() for last data on quit in sendfile() path
authorJens Axboe <axboe@suse.de>
Mon, 20 Feb 2006 08:56:56 +0000 (09:56 +0100)
committerJens Axboe <axboe@suse.de>
Mon, 20 Feb 2006 08:56:56 +0000 (09:56 +0100)
We need to do that, as we can only use full subbufs in the sendfile() path.

blktrace.c

index 9c4dd196fa34a0a806818c0840fef488451e7d49..c8f9ffb70e1f72418871e0e23f4afaea58e20205 100644 (file)
@@ -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;
 }