Block patches for 2.9-rc2.

-----BEGIN PGP SIGNATURE-----
 
 iQFGBAABCAAwFiEEkb62CjDbPohX0Rgp9AfbAGHVz0AFAljZNCoSHG1yZWl0ekBy
 ZWRoYXQuY29tAAoJEPQH2wBh1c9Ac0kIAJ2NzP7LifDTzA2kVcm5sD0ufeOB7Cbf
 ucyiXvws28yLgVV0eeNEoWSWWRwX3ZwwuhHyE5ZIDCTjUhVNtCfp+Z9jfIMeLhwB
 t9bKJPUhGqjuAmwemQDwB1i3urlBikRVN/le/drC09B/ca3T6ylrEWPXD/3wmsFj
 W9AR/I94r7/srptOcV85YKMun4yDDeQX32BShpbA+FuZd7ER+xEVw66N1YUrTwAI
 I1LCTAfgLM5FcPLNLemUr7V6aQPIBDX1XljDglgvrC+zUgrUYwoc11afcDHSvmFQ
 w7nkMFMgTyz8PWevMNu2Ovxiqp0BO9bky0+E5K71cxlvunLP2EeZMWI=
 =++D6
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2017-03-27' into staging

Block patches for 2.9-rc2.

# gpg: Signature made Mon 27 Mar 2017 16:47:54 BST
# gpg:                using RSA key 0xF407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* remotes/maxreitz/tags/pull-block-2017-03-27:
  block/file-posix.c: Fix unused variable warning on OpenBSD
  file-posix: Make bdrv_flush() failure permanent without O_DIRECT
  nbd-client: fix handling of hungup connections
  qemu-img: print short help on getopt failure
  qemu-img: fix switch indentation in img_amend()
  qemu-img: show help for invalid global options

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2017-03-27 16:56:31 +01:00
commit 9366f53d50
4 changed files with 180 additions and 80 deletions

View File

@ -144,6 +144,7 @@ typedef struct BDRVRawState {
bool has_write_zeroes:1;
bool discard_zeroes:1;
bool use_linux_aio:1;
bool page_cache_inconsistent:1;
bool has_fallocate;
bool needs_alignment;
} BDRVRawState;
@ -219,28 +220,28 @@ static int probe_logical_blocksize(int fd, unsigned int *sector_size_p)
{
unsigned int sector_size;
bool success = false;
int i;
errno = ENOTSUP;
/* Try a few ioctls to get the right size */
static const unsigned long ioctl_list[] = {
#ifdef BLKSSZGET
if (ioctl(fd, BLKSSZGET, &sector_size) >= 0) {
*sector_size_p = sector_size;
success = true;
}
BLKSSZGET,
#endif
#ifdef DKIOCGETBLOCKSIZE
if (ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size) >= 0) {
*sector_size_p = sector_size;
success = true;
}
DKIOCGETBLOCKSIZE,
#endif
#ifdef DIOCGSECTORSIZE
if (ioctl(fd, DIOCGSECTORSIZE, &sector_size) >= 0) {
*sector_size_p = sector_size;
success = true;
}
DIOCGSECTORSIZE,
#endif
};
/* Try a few ioctls to get the right size */
for (i = 0; i < (int)ARRAY_SIZE(ioctl_list); i++) {
if (ioctl(fd, ioctl_list[i], &sector_size) >= 0) {
*sector_size_p = sector_size;
success = true;
}
}
return success ? 0 : -errno;
}
@ -824,10 +825,31 @@ static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb)
static ssize_t handle_aiocb_flush(RawPosixAIOData *aiocb)
{
BDRVRawState *s = aiocb->bs->opaque;
int ret;
if (s->page_cache_inconsistent) {
return -EIO;
}
ret = qemu_fdatasync(aiocb->aio_fildes);
if (ret == -1) {
/* There is no clear definition of the semantics of a failing fsync(),
* so we may have to assume the worst. The sad truth is that this
* assumption is correct for Linux. Some pages are now probably marked
* clean in the page cache even though they are inconsistent with the
* on-disk contents. The next fdatasync() call would succeed, but no
* further writeback attempt will be made. We can't get back to a state
* in which we know what is on disk (we would have to rewrite
* everything that was touched since the last fdatasync() at least), so
* make bdrv_flush() fail permanently. Given that the behaviour isn't
* really defined, I have little hope that other OSes are doing better.
*
* Obviously, this doesn't affect O_DIRECT, which bypasses the page
* cache. */
if ((s->open_flags & O_DIRECT) == 0) {
s->page_cache_inconsistent = true;
}
return -errno;
}
return 0;

View File

@ -33,17 +33,15 @@
#define HANDLE_TO_INDEX(bs, handle) ((handle) ^ ((uint64_t)(intptr_t)bs))
#define INDEX_TO_HANDLE(bs, index) ((index) ^ ((uint64_t)(intptr_t)bs))
static void nbd_recv_coroutines_enter_all(BlockDriverState *bs)
static void nbd_recv_coroutines_enter_all(NBDClientSession *s)
{
NBDClientSession *s = nbd_get_client_session(bs);
int i;
for (i = 0; i < MAX_NBD_REQUESTS; i++) {
if (s->recv_coroutine[i]) {
qemu_coroutine_enter(s->recv_coroutine[i]);
aio_co_wake(s->recv_coroutine[i]);
}
}
BDRV_POLL_WHILE(bs, s->read_reply_co);
}
static void nbd_teardown_connection(BlockDriverState *bs)
@ -58,7 +56,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
qio_channel_shutdown(client->ioc,
QIO_CHANNEL_SHUTDOWN_BOTH,
NULL);
nbd_recv_coroutines_enter_all(bs);
BDRV_POLL_WHILE(bs, client->read_reply_co);
nbd_client_detach_aio_context(bs);
object_unref(OBJECT(client->sioc));
@ -76,7 +74,7 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
for (;;) {
assert(s->reply.handle == 0);
ret = nbd_receive_reply(s->ioc, &s->reply);
if (ret < 0) {
if (ret <= 0) {
break;
}
@ -103,6 +101,8 @@ static coroutine_fn void nbd_read_reply_entry(void *opaque)
aio_co_wake(s->recv_coroutine[i]);
qemu_coroutine_yield();
}
nbd_recv_coroutines_enter_all(s);
s->read_reply_co = NULL;
}

View File

@ -812,6 +812,6 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply)
LOG("invalid magic (got 0x%" PRIx32 ")", magic);
return -EINVAL;
}
return 0;
return sizeof(buf);
}

View File

@ -88,6 +88,16 @@ static void QEMU_NORETURN GCC_FMT_ATTR(1, 2) error_exit(const char *fmt, ...)
exit(EXIT_FAILURE);
}
static void QEMU_NORETURN missing_argument(const char *option)
{
error_exit("missing argument for option '%s'", option);
}
static void QEMU_NORETURN unrecognized_option(const char *option)
{
error_exit("unrecognized option '%s'", option);
}
/* Please keep in synch with qemu-img.texi */
static void QEMU_NORETURN help(void)
{
@ -406,13 +416,18 @@ static int img_create(int argc, char **argv)
{"object", required_argument, 0, OPTION_OBJECT},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "F:b:f:he6o:q",
c = getopt_long(argc, argv, ":F:b:f:he6o:q",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -651,13 +666,18 @@ static int img_check(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:r:T:q",
c = getopt_long(argc, argv, ":hf:r:T:q",
long_options, &option_index);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -855,13 +875,18 @@ static int img_commit(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:ht:b:dpq",
c = getopt_long(argc, argv, ":f:ht:b:dpq",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -1190,13 +1215,18 @@ static int img_compare(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:F:T:pqs",
c = getopt_long(argc, argv, ":hf:F:T:pqs",
long_options, NULL);
if (c == -1) {
break;
}
switch (c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -1926,13 +1956,18 @@ static int img_convert(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:O:B:ce6o:s:l:S:pt:T:qnm:W",
c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:W",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -2502,13 +2537,18 @@ static int img_info(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
c = getopt_long(argc, argv, ":f:h",
long_options, &option_index);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -2713,13 +2753,18 @@ static int img_map(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
c = getopt_long(argc, argv, ":f:h",
long_options, &option_index);
if (c == -1) {
break;
}
switch (c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -2835,13 +2880,18 @@ static int img_snapshot(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "la:c:d:hq",
c = getopt_long(argc, argv, ":la:c:d:hq",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
return 0;
@ -2988,13 +3038,18 @@ static int img_rebase(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:F:b:upt:T:q",
c = getopt_long(argc, argv, ":hf:F:b:upt:T:q",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
return 0;
@ -3355,13 +3410,18 @@ static int img_resize(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:hq",
c = getopt_long(argc, argv, ":f:hq",
long_options, NULL);
if (c == -1) {
break;
}
switch(c) {
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -3493,54 +3553,59 @@ static int img_amend(int argc, char **argv)
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "ho:f:t:pq",
c = getopt_long(argc, argv, ":ho:f:t:pq",
long_options, NULL);
if (c == -1) {
break;
}
switch (c) {
case 'h':
case '?':
help();
break;
case 'o':
if (!is_valid_option_list(optarg)) {
error_report("Invalid option list: %s", optarg);
ret = -1;
goto out_no_progress;
}
if (!options) {
options = g_strdup(optarg);
} else {
char *old_options = options;
options = g_strdup_printf("%s,%s", options, optarg);
g_free(old_options);
}
break;
case 'f':
fmt = optarg;
break;
case 't':
cache = optarg;
break;
case 'p':
progress = true;
break;
case 'q':
quiet = true;
break;
case OPTION_OBJECT:
opts = qemu_opts_parse_noisily(&qemu_object_opts,
optarg, true);
if (!opts) {
ret = -1;
goto out_no_progress;
}
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
case 'o':
if (!is_valid_option_list(optarg)) {
error_report("Invalid option list: %s", optarg);
ret = -1;
goto out_no_progress;
}
if (!options) {
options = g_strdup(optarg);
} else {
char *old_options = options;
options = g_strdup_printf("%s,%s", options, optarg);
g_free(old_options);
}
break;
case 'f':
fmt = optarg;
break;
case 't':
cache = optarg;
break;
case 'p':
progress = true;
break;
case 'q':
quiet = true;
break;
case OPTION_OBJECT:
opts = qemu_opts_parse_noisily(&qemu_object_opts,
optarg, true);
if (!opts) {
ret = -1;
goto out_no_progress;
}
break;
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
}
}
@ -3759,14 +3824,19 @@ static int img_bench(int argc, char **argv)
{"no-drain", no_argument, 0, OPTION_NO_DRAIN},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hc:d:f:no:qs:S:t:w", long_options, NULL);
c = getopt_long(argc, argv, ":hc:d:f:no:qs:S:t:w", long_options, NULL);
if (c == -1) {
break;
}
switch (c) {
case 'h':
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
case 'c':
@ -4093,7 +4163,7 @@ static int img_dd(int argc, char **argv)
{ 0, 0, 0, 0 }
};
while ((c = getopt_long(argc, argv, "hf:O:", long_options, NULL))) {
while ((c = getopt_long(argc, argv, ":hf:O:", long_options, NULL))) {
if (c == EOF) {
break;
}
@ -4104,10 +4174,12 @@ static int img_dd(int argc, char **argv)
case 'f':
fmt = optarg;
break;
case ':':
missing_argument(argv[optind - 1]);
break;
case '?':
error_report("Try 'qemu-img --help' for more information.");
ret = -1;
goto out;
unrecognized_option(argv[optind - 1]);
break;
case 'h':
help();
break;
@ -4336,8 +4408,14 @@ int main(int argc, char **argv)
qemu_add_opts(&qemu_source_opts);
qemu_add_opts(&qemu_trace_opts);
while ((c = getopt_long(argc, argv, "+hVT:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "+:hVT:", long_options, NULL)) != -1) {
switch (c) {
case ':':
missing_argument(argv[optind - 1]);
return 0;
case '?':
unrecognized_option(argv[optind - 1]);
return 0;
case 'h':
help();
return 0;