From f5ed765adadc5dca61efb5fc103fa5cd0310bcec Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 14 Mar 2012 16:28:07 +0100 Subject: [PATCH] server: convert iolog in place instead of copy allocating it Signed-off-by: Jens Axboe --- client.c | 28 +++++++++++++++++++++------- iolog.c | 8 +++++--- server.c | 39 ++++++++++++++++----------------------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/client.c b/client.c index c49e9a19..f7b050b0 100644 --- a/client.c +++ b/client.c @@ -963,6 +963,7 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) unsigned long total; z_stream stream; void *p; + int i; stream.zalloc = Z_NULL; stream.zfree = Z_NULL; @@ -974,17 +975,20 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) return NULL; /* - * Everything beyond the first entry is compressed. + * Get header first, it's not compressed */ nr_samples = le32_to_cpu(pdu->nr_samples); - total = sizeof(*pdu) + nr_samples * sizeof(struct io_sample); - ret = malloc(total); + total = nr_samples * sizeof(struct io_sample); + ret = malloc(total + sizeof(*pdu)); ret->nr_samples = nr_samples; - p = (void *) ret + sizeof(pdu->nr_samples); + ret->log_type = le32_to_cpu(pdu->log_type); + strcpy((char *) ret->name, (char *) pdu->name); + + p = (void *) ret + sizeof(*pdu); - stream.avail_in = cmd->pdu_len - sizeof(pdu->nr_samples); - stream.next_in = (void *) pdu + sizeof(pdu->nr_samples); + stream.avail_in = cmd->pdu_len - sizeof(*pdu); + stream.next_in = (void *) pdu + sizeof(*pdu); while (stream.avail_in) { unsigned int this_chunk = 65536; unsigned int this_len; @@ -998,6 +1002,8 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) err = inflate(&stream, Z_NO_FLUSH); if (err != Z_OK) { log_err("fio: inflate error %d\n", err); + free(ret); + ret = NULL; goto out; } @@ -1006,7 +1012,15 @@ static struct cmd_iolog_pdu *convert_iolog(struct fio_net_cmd *cmd) total -= this_len; } - ret->log_type = cpu_to_le32(ret->log_type); + for (i = 0; i < ret->nr_samples; i++) { + struct io_sample *s = &ret->samples[i]; + + s->time = le64_to_cpu(s->time); + s->val = le64_to_cpu(s->val); + s->ddir = le32_to_cpu(s->ddir); + s->bs = le32_to_cpu(s->bs); + } + out: inflateEnd(&stream); return ret; diff --git a/iolog.c b/iolog.c index 88adbf7f..7b212bb5 100644 --- a/iolog.c +++ b/iolog.c @@ -536,10 +536,12 @@ void finish_log_named(struct thread_data *td, struct io_log *log, snprintf(file_name, 200, "%s_%s.log", prefix, postfix); p = basename(file_name); - if (td->client_type == FIO_CLIENT_TYPE_GUI) + if (td->client_type == FIO_CLIENT_TYPE_GUI) { fio_send_iolog(td, log, p); - - __finish_log(log, p); + free(log->log); + free(log); + } else + __finish_log(log, p); } void finish_log(struct thread_data *td, struct io_log *log, const char *name) diff --git a/server.c b/server.c index 4e1f39be..b57c8b2c 100644 --- a/server.c +++ b/server.c @@ -853,27 +853,23 @@ void fio_server_send_du(void) int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) { - struct cmd_iolog_pdu *pdu; + struct cmd_iolog_pdu pdu; struct fio_net_cmd cmd; z_stream stream; void *out_pdu; - size_t p_size; int i; - p_size = sizeof(*pdu) + log->nr_samples * sizeof(struct io_sample); - pdu = malloc(p_size); - - pdu->nr_samples = __cpu_to_le32(log->nr_samples); - pdu->log_type = cpu_to_le32(log->log_type); - strcpy((char *) pdu->name, name); + pdu.nr_samples = __cpu_to_le32(log->nr_samples); + pdu.log_type = cpu_to_le32(log->log_type); + strcpy((char *) pdu.name, name); for (i = 0; i < log->nr_samples; i++) { - struct io_sample *s = &pdu->samples[i]; + struct io_sample *s = &log->log[i]; - s->time = cpu_to_le64(log->log[i].time); - s->val = cpu_to_le64(log->log[i].val); - s->ddir = cpu_to_le32(log->log[i].ddir); - s->bs = cpu_to_le32(log->log[i].bs); + s->time = cpu_to_le64(s->time); + s->val = cpu_to_le64(s->val); + s->ddir = cpu_to_le32(s->ddir); + s->bs = cpu_to_le32(s->bs); } /* @@ -889,29 +885,27 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) if (deflateInit(&stream, Z_DEFAULT_COMPRESSION) != Z_OK) { free(out_pdu); - free(pdu); return 1; } /* - * Don't compress the nr samples entry, we want to know on the - * client side how much data to allocate before starting inflate. + * Send header first, it's not compressed. */ - __fio_init_net_cmd(&cmd, FIO_NET_CMD_IOLOG, sizeof(pdu->nr_samples), 0); + __fio_init_net_cmd(&cmd, FIO_NET_CMD_IOLOG, sizeof(pdu), 0); cmd.flags = __cpu_to_le32(FIO_NET_CMD_F_MORE); - fio_net_cmd_crc_pdu(&cmd, pdu); + fio_net_cmd_crc_pdu(&cmd, &pdu); fio_send_data(server_fd, &cmd, sizeof(cmd)); - fio_send_data(server_fd, pdu, sizeof(pdu->nr_samples)); + fio_send_data(server_fd, &pdu, sizeof(pdu)); - stream.next_in = (void *) pdu + sizeof(pdu->nr_samples); - stream.avail_in = p_size - sizeof(pdu->nr_samples); + stream.next_in = (void *) log->log; + stream.avail_in = log->nr_samples * sizeof(struct io_sample); do { unsigned int this_len; stream.avail_out = FIO_SERVER_MAX_FRAGMENT_PDU; stream.next_out = out_pdu; - deflate(&stream, Z_FINISH); + assert(deflate(&stream, Z_FINISH) == Z_OK); this_len = FIO_SERVER_MAX_FRAGMENT_PDU - stream.avail_out; @@ -926,7 +920,6 @@ int fio_send_iolog(struct thread_data *td, struct io_log *log, const char *name) fio_send_data(server_fd, out_pdu, this_len); } while (stream.avail_in); - free(pdu); free(out_pdu); deflateEnd(&stream); return 0; -- 2.25.1