qemu-io: Allow unaligned access by default

There's no reason to require the user to specify a flag just so
they can pass in unaligned numbers.  Keep 'read -p' and 'write -p'
as no-ops so that I don't have to hunt down and update all users
of qemu-io, but otherwise make their behavior default as 'read' and
'write'.  Also fix 'write -z', 'readv', 'writev', 'writev',
'aio_read', 'aio_write', and 'aio_write -z'.  For now, 'read -b',
'write -b', and 'write -c' still require alignment (and 'multiwrite',
but that's slated to die soon).

qemu-iotest 23 is updated to match, as the only test that was
previously explicitly expecting an error on an unaligned request.

Signed-off-by: Eric Blake <eblake@redhat.com>
Message-id: 1462677405-4752-5-git-send-email-eblake@redhat.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index e038c03..ab14046 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1,7 +1,7 @@
 /*
  * Command line utility to exercise the QEMU I/O path.
  *
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009-2016 Red Hat, Inc.
  * Copyright (c) 2003-2005 Silicon Graphics, Inc.
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
@@ -395,12 +395,6 @@
             goto fail;
         }
 
-        if (len & 0x1ff) {
-            printf("length argument %" PRId64
-                   " is not sector aligned\n", len);
-            goto fail;
-        }
-
         sizes[i] = len;
         count += len;
     }
@@ -634,7 +628,7 @@
 " -b, -- read from the VM state rather than the virtual disk\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -l, -- length for pattern verification (only with -P)\n"
-" -p, -- allow unaligned access\n"
+" -p, -- ignored for backwards compatibility\n"
 " -P, -- use a pattern to verify read data\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
 " -s, -- start offset for pattern verification (only with -P)\n"
@@ -650,7 +644,7 @@
     .cfunc      = read_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
+    .args       = "[-abCqv] [-P pattern [-s off] [-l len]] off len",
     .oneline    = "reads a number of bytes at a specified offset",
     .help       = read_help,
 };
@@ -658,7 +652,7 @@
 static int read_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, pflag = false, qflag = false, vflag = false;
+    bool Cflag = false, qflag = false, vflag = false;
     bool Pflag = false, sflag = false, lflag = false, bflag = false;
     int c, cnt;
     char *buf;
@@ -686,7 +680,7 @@
             }
             break;
         case 'p':
-            pflag = true;
+            /* Ignored for backwards compatibility */
             break;
         case 'P':
             Pflag = true;
@@ -718,11 +712,6 @@
         return qemuio_command_usage(&read_cmd);
     }
 
-    if (bflag && pflag) {
-        printf("-b and -p cannot be specified at the same time\n");
-        return 0;
-    }
-
     offset = cvtnum(argv[optind]);
     if (offset < 0) {
         print_cvtnum_err(offset, argv[optind]);
@@ -753,7 +742,7 @@
         return 0;
     }
 
-    if (!pflag) {
+    if (bflag) {
         if (offset & 0x1ff) {
             printf("offset %" PRId64 " is not sector aligned\n",
                    offset);
@@ -836,7 +825,7 @@
     .cfunc      = readv_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .args       = "[-Cqv] [-P pattern] off len [len..]",
     .oneline    = "reads a number of bytes at a specified offset",
     .help       = readv_help,
 };
@@ -890,12 +879,6 @@
     }
     optind++;
 
-    if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               offset);
-        return 0;
-    }
-
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
     if (buf == NULL) {
@@ -952,7 +935,7 @@
 " filled with a set pattern (0xcdcdcdcd).\n"
 " -b, -- write to the VM state rather than the virtual disk\n"
 " -c, -- write compressed data with blk_write_compressed\n"
-" -p, -- allow unaligned access\n"
+" -p, -- ignored for backwards compatibility\n"
 " -P, -- use different pattern to fill file\n"
 " -C, -- report statistics in a machine parsable format\n"
 " -q, -- quiet mode, do not show I/O statistics\n"
@@ -968,7 +951,7 @@
     .cfunc      = write_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-bcCpqz] [-P pattern ] off len",
+    .args       = "[-bcCqz] [-P pattern] off len",
     .oneline    = "writes a number of bytes at a specified offset",
     .help       = write_help,
 };
@@ -976,7 +959,7 @@
 static int write_f(BlockBackend *blk, int argc, char **argv)
 {
     struct timeval t1, t2;
-    bool Cflag = false, pflag = false, qflag = false, bflag = false;
+    bool Cflag = false, qflag = false, bflag = false;
     bool Pflag = false, zflag = false, cflag = false;
     int c, cnt;
     char *buf = NULL;
@@ -998,7 +981,7 @@
             Cflag = true;
             break;
         case 'p':
-            pflag = true;
+            /* Ignored for backwards compatibility */
             break;
         case 'P':
             Pflag = true;
@@ -1022,8 +1005,8 @@
         return qemuio_command_usage(&write_cmd);
     }
 
-    if (bflag + pflag + zflag > 1) {
-        printf("-b, -p, or -z cannot be specified at the same time\n");
+    if (bflag && zflag) {
+        printf("-b and -z cannot be specified at the same time\n");
         return 0;
     }
 
@@ -1049,7 +1032,7 @@
         return 0;
     }
 
-    if (!pflag) {
+    if (bflag || cflag) {
         if (offset & 0x1ff) {
             printf("offset %" PRId64 " is not sector aligned\n",
                    offset);
@@ -1125,7 +1108,7 @@
     .cfunc      = writev_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cq] [-P pattern ] off len [len..]",
+    .args       = "[-Cq] [-P pattern] off len [len..]",
     .oneline    = "writes a number of bytes at a specified offset",
     .help       = writev_help,
 };
@@ -1173,12 +1156,6 @@
     }
     optind++;
 
-    if (offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               offset);
-        return 0;
-    }
-
     nr_iov = argc - optind;
     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
     if (buf == NULL) {
@@ -1484,7 +1461,7 @@
     .cfunc      = aio_read_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cqv] [-P pattern ] off len [len..]",
+    .args       = "[-Cqv] [-P pattern] off len [len..]",
     .oneline    = "asynchronously reads a number of bytes",
     .help       = aio_read_help,
 };
@@ -1533,14 +1510,6 @@
     }
     optind++;
 
-    if (ctx->offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               ctx->offset);
-        block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
-        g_free(ctx);
-        return 0;
-    }
-
     nr_iov = argc - optind;
     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
     if (ctx->buf == NULL) {
@@ -1584,7 +1553,7 @@
     .cfunc      = aio_write_f,
     .argmin     = 2,
     .argmax     = -1,
-    .args       = "[-Cqz] [-P pattern ] off len [len..]",
+    .args       = "[-Cqz] [-P pattern] off len [len..]",
     .oneline    = "asynchronously writes a number of bytes",
     .help       = aio_write_help,
 };
@@ -1645,14 +1614,6 @@
     }
     optind++;
 
-    if (ctx->offset & 0x1ff) {
-        printf("offset %" PRId64 " is not sector aligned\n",
-               ctx->offset);
-        block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
-        g_free(ctx);
-        return 0;
-    }
-
     if (ctx->zflag) {
         int64_t count = cvtnum(argv[optind]);
         if (count < 0) {