static void *
create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)
{
- size_t *sizes = calloc(nr_iov, sizeof(size_t));
+ size_t *sizes = g_new0(size_t, nr_iov);
size_t count = 0;
void *buf = NULL;
void *p;
}
fail:
- free(sizes);
+ g_free(sizes);
return buf;
}
static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total)
{
- BlockDriverAIOCB *acb;
int async_ret = NOT_DONE;
- acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
- aio_rw_done, &async_ret);
- if (!acb) {
- return -EIO;
- }
+ bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9,
+ aio_rw_done, &async_ret);
while (async_ret == NOT_DONE) {
qemu_aio_wait();
}
static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total)
{
- BlockDriverAIOCB *acb;
int async_ret = NOT_DONE;
- acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
- aio_rw_done, &async_ret);
- if (!acb) {
- return -EIO;
- }
-
+ bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9,
+ aio_rw_done, &async_ret);
while (async_ret == NOT_DONE) {
qemu_aio_wait();
}
}
if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) {
- printf("pattern verfication range exceeds end of read data\n");
+ printf("pattern verification range exceeds end of read data\n");
return 0;
}
}
if (Pflag) {
- void *cmp_buf = malloc(pattern_count);
+ void *cmp_buf = g_malloc(pattern_count);
memset(cmp_buf, pattern, pattern_count);
if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
printf("Pattern verification failed at offset %"
PRId64 ", %d bytes\n",
offset + pattern_offset, pattern_count);
}
- free(cmp_buf);
+ g_free(cmp_buf);
}
if (qflag) {
nr_iov = argc - optind;
buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);
+ if (buf == NULL) {
+ return 0;
+ }
gettimeofday(&t1, NULL);
cnt = do_aio_readv(&qiov, offset, &total);
}
if (Pflag) {
- void *cmp_buf = malloc(qiov.size);
+ void *cmp_buf = g_malloc(qiov.size);
memset(cmp_buf, pattern, qiov.size);
if (memcmp(buf, cmp_buf, qiov.size)) {
printf("Pattern verification failed at offset %"
PRId64 ", %zd bytes\n", offset, qiov.size);
}
- free(cmp_buf);
+ g_free(cmp_buf);
}
if (qflag) {
nr_iov = argc - optind;
buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern);
+ if (buf == NULL) {
+ return 0;
+ }
gettimeofday(&t1, NULL);
cnt = do_aio_writev(&qiov, offset, &total);
" in a batch of requests that may be merged by qemu\n"
"\n"
" Example:\n"
-" 'multiwrite 512 1k 1k ; 4k 1k' \n"
+" 'multiwrite 512 1k 1k ; 4k 1k'\n"
" writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
"\n"
" Writes into a segment of the currently open file, using a buffer\n"
}
}
- reqs = qemu_malloc(nr_reqs * sizeof(*reqs));
- buf = qemu_malloc(nr_reqs * sizeof(*buf));
- qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs));
+ reqs = g_malloc0(nr_reqs * sizeof(*reqs));
+ buf = g_malloc0(nr_reqs * sizeof(*buf));
+ qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
- for (i = 0; i < nr_reqs; i++) {
+ for (i = 0; i < nr_reqs && optind < argc; i++) {
int j;
/* Read the offset of the request */
offset = cvtnum(argv[optind]);
if (offset < 0) {
printf("non-numeric offset argument -- %s\n", argv[optind]);
- return 0;
+ goto out;
}
optind++;
if (offset & 0x1ff) {
printf("offset %lld is not sector aligned\n",
(long long)offset);
- return 0;
+ goto out;
}
if (i == 0) {
nr_iov = j - optind;
/* Build request */
+ buf[i] = create_iovec(&qiovs[i], &argv[optind], nr_iov, pattern);
+ if (buf[i] == NULL) {
+ goto out;
+ }
+
reqs[i].qiov = &qiovs[i];
- buf[i] = create_iovec(reqs[i].qiov, &argv[optind], nr_iov, pattern);
reqs[i].sector = offset >> 9;
reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
optind = j + 1;
- offset += reqs[i].qiov->size;
pattern++;
}
+ /* If there were empty requests at the end, ignore them */
+ nr_reqs = i;
+
gettimeofday(&t1, NULL);
cnt = do_aio_multiwrite(reqs, nr_reqs, &total);
gettimeofday(&t2, NULL);
out:
for (i = 0; i < nr_reqs; i++) {
qemu_io_free(buf[i]);
- qemu_iovec_destroy(&qiovs[i]);
+ if (reqs[i].qiov != NULL) {
+ qemu_iovec_destroy(&qiovs[i]);
+ }
}
- qemu_free(buf);
- qemu_free(reqs);
- qemu_free(qiovs);
+ g_free(buf);
+ g_free(reqs);
+ g_free(qiovs);
return 0;
}
ctx->qiov.size, 1, ctx->Cflag);
out:
qemu_io_free(ctx->buf);
- free(ctx);
+ g_free(ctx);
}
static void aio_read_done(void *opaque, int ret)
}
if (ctx->Pflag) {
- void *cmp_buf = malloc(ctx->qiov.size);
+ void *cmp_buf = g_malloc(ctx->qiov.size);
memset(cmp_buf, ctx->pattern, ctx->qiov.size);
if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
printf("Pattern verification failed at offset %"
PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
}
- free(cmp_buf);
+ g_free(cmp_buf);
}
if (ctx->qflag) {
ctx->qiov.size, 1, ctx->Cflag);
out:
qemu_io_free(ctx->buf);
- free(ctx);
+ g_free(ctx);
}
static void aio_read_help(void)
static int aio_read_f(int argc, char **argv)
{
int nr_iov, c;
- struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
- BlockDriverAIOCB *acb;
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
while ((c = getopt(argc, argv, "CP:qv")) != EOF) {
switch (c) {
ctx->Pflag = 1;
ctx->pattern = parse_pattern(optarg);
if (ctx->pattern < 0) {
- free(ctx);
+ g_free(ctx);
return 0;
}
break;
ctx->vflag = 1;
break;
default:
- free(ctx);
+ g_free(ctx);
return command_usage(&aio_read_cmd);
}
}
if (optind > argc - 2) {
- free(ctx);
+ g_free(ctx);
return command_usage(&aio_read_cmd);
}
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
- free(ctx);
+ g_free(ctx);
return 0;
}
optind++;
if (ctx->offset & 0x1ff) {
printf("offset %" PRId64 " is not sector aligned\n",
ctx->offset);
- free(ctx);
+ g_free(ctx);
return 0;
}
nr_iov = argc - optind;
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, 0xab);
-
- gettimeofday(&ctx->t1, NULL);
- acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
- ctx->qiov.size >> 9, aio_read_done, ctx);
- if (!acb) {
- free(ctx->buf);
- free(ctx);
- return -EIO;
+ if (ctx->buf == NULL) {
+ g_free(ctx);
+ return 0;
}
+ gettimeofday(&ctx->t1, NULL);
+ bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov,
+ ctx->qiov.size >> 9, aio_read_done, ctx);
return 0;
}
{
int nr_iov, c;
int pattern = 0xcd;
- struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));
- BlockDriverAIOCB *acb;
+ struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
while ((c = getopt(argc, argv, "CqP:")) != EOF) {
switch (c) {
case 'P':
pattern = parse_pattern(optarg);
if (pattern < 0) {
+ g_free(ctx);
return 0;
}
break;
default:
- free(ctx);
+ g_free(ctx);
return command_usage(&aio_write_cmd);
}
}
if (optind > argc - 2) {
- free(ctx);
+ g_free(ctx);
return command_usage(&aio_write_cmd);
}
ctx->offset = cvtnum(argv[optind]);
if (ctx->offset < 0) {
printf("non-numeric length argument -- %s\n", argv[optind]);
- free(ctx);
+ g_free(ctx);
return 0;
}
optind++;
if (ctx->offset & 0x1ff) {
printf("offset %" PRId64 " is not sector aligned\n",
ctx->offset);
- free(ctx);
+ g_free(ctx);
return 0;
}
nr_iov = argc - optind;
ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);
-
- gettimeofday(&ctx->t1, NULL);
- acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
- ctx->qiov.size >> 9, aio_write_done, ctx);
- if (!acb) {
- free(ctx->buf);
- free(ctx);
- return -EIO;
+ if (ctx->buf == NULL) {
+ g_free(ctx);
+ return 0;
}
+ gettimeofday(&ctx->t1, NULL);
+ bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,
+ ctx->qiov.size >> 9, aio_write_done, ctx);
return 0;
}
static int close_f(int argc, char **argv)
{
- bdrv_close(bs);
+ bdrv_delete(bs);
bs = NULL;
return 0;
}
if (bdrv_open(bs, name, flags, NULL) < 0) {
fprintf(stderr, "%s: can't open device %s\n", progname, name);
+ bdrv_delete(bs);
bs = NULL;
return 1;
}
command_loop();
/*
- * Make sure all outstanding requests get flushed the program exits.
+ * Make sure all outstanding requests complete before the program exits.
*/
- qemu_aio_flush();
+ bdrv_drain_all();
if (bs) {
- bdrv_close(bs);
+ bdrv_delete(bs);
}
return 0;
}