diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/iscsi.c | 3 | ||||
-rw-r--r-- | block/qcow2.c | 25 | ||||
-rw-r--r-- | block/qed.c | 4 | ||||
-rw-r--r-- | block/raw-posix.c | 39 | ||||
-rw-r--r-- | block/raw_bsd.c | 3 | ||||
-rw-r--r-- | block/stream.c | 2 | ||||
-rw-r--r-- | block/vmdk.c | 4 |
7 files changed, 50 insertions, 30 deletions
diff --git a/block/iscsi.c b/block/iscsi.c index f3e83e2332..a7bb6970ac 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -1450,7 +1450,7 @@ static void iscsi_close(BlockDriverState *bs) memset(iscsilun, 0, sizeof(IscsiLun)); } -static int iscsi_refresh_limits(BlockDriverState *bs) +static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp) { IscsiLun *iscsilun = bs->opaque; @@ -1475,7 +1475,6 @@ static int iscsi_refresh_limits(BlockDriverState *bs) } bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len, iscsilun); - return 0; } /* Since iscsi_open() ignores bdrv_flags, there is nothing to do here in diff --git a/block/qcow2.c b/block/qcow2.c index b0faa6917b..1e3ab6bd02 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -210,20 +210,31 @@ static void GCC_FMT_ATTR(3, 4) report_unsupported(BlockDriverState *bs, static void report_unsupported_feature(BlockDriverState *bs, Error **errp, Qcow2Feature *table, uint64_t mask) { + char *features = g_strdup(""); + char *old; + while (table && table->name[0] != '\0') { if (table->type == QCOW2_FEAT_TYPE_INCOMPATIBLE) { - if (mask & (1 << table->bit)) { - report_unsupported(bs, errp, "%.46s", table->name); - mask &= ~(1 << table->bit); + if (mask & (1ULL << table->bit)) { + old = features; + features = g_strdup_printf("%s%s%.46s", old, *old ? ", " : "", + table->name); + g_free(old); + mask &= ~(1ULL << table->bit); } } table++; } if (mask) { - report_unsupported(bs, errp, "Unknown incompatible feature: %" PRIx64, - mask); + old = features; + features = g_strdup_printf("%s%sUnknown incompatible feature: %" PRIx64, + old, *old ? ", " : "", mask); + g_free(old); } + + report_unsupported(bs, errp, "%s", features); + g_free(features); } /* @@ -855,13 +866,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags, return ret; } -static int qcow2_refresh_limits(BlockDriverState *bs) +static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQcowState *s = bs->opaque; bs->bl.write_zeroes_alignment = s->cluster_sectors; - - return 0; } static int qcow2_set_key(BlockDriverState *bs, const char *key) diff --git a/block/qed.c b/block/qed.c index cd4872b529..7944832181 100644 --- a/block/qed.c +++ b/block/qed.c @@ -528,13 +528,11 @@ out: return ret; } -static int bdrv_qed_refresh_limits(BlockDriverState *bs) +static void bdrv_qed_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQEDState *s = bs->opaque; bs->bl.write_zeroes_alignment = s->header.cluster_size >> BDRV_SECTOR_BITS; - - return 0; } /* We have nothing to do for QED reopen, stubs just return diff --git a/block/raw-posix.c b/block/raw-posix.c index 2bcc73dc37..8e9758e920 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -221,7 +221,7 @@ static int raw_normalize_devicepath(const char **filename) } #endif -static void raw_probe_alignment(BlockDriverState *bs) +static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) { BDRVRawState *s = bs->opaque; char *buf; @@ -240,24 +240,24 @@ static void raw_probe_alignment(BlockDriverState *bs) s->buf_align = 0; #ifdef BLKSSZGET - if (ioctl(s->fd, BLKSSZGET, §or_size) >= 0) { + if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef DKIOCGETBLOCKSIZE - if (ioctl(s->fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { + if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef DIOCGSECTORSIZE - if (ioctl(s->fd, DIOCGSECTORSIZE, §or_size) >= 0) { + if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { bs->request_alignment = sector_size; } #endif #ifdef CONFIG_XFS if (s->is_xfs) { struct dioattr da; - if (xfsctl(NULL, s->fd, XFS_IOC_DIOINFO, &da) >= 0) { + if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) { bs->request_alignment = da.d_miniosz; /* The kernel returns wrong information for d_mem */ /* s->buf_align = da.d_mem; */ @@ -270,7 +270,7 @@ static void raw_probe_alignment(BlockDriverState *bs) size_t align; buf = qemu_memalign(MAX_BLOCKSIZE, 2 * MAX_BLOCKSIZE); for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) { - if (pread(s->fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) { + if (pread(fd, buf + align, MAX_BLOCKSIZE, 0) >= 0) { s->buf_align = align; break; } @@ -282,13 +282,18 @@ static void raw_probe_alignment(BlockDriverState *bs) size_t align; buf = qemu_memalign(s->buf_align, MAX_BLOCKSIZE); for (align = 512; align <= MAX_BLOCKSIZE; align <<= 1) { - if (pread(s->fd, buf, align, 0) >= 0) { + if (pread(fd, buf, align, 0) >= 0) { bs->request_alignment = align; break; } } qemu_vfree(buf); } + + if (!s->buf_align || !bs->request_alignment) { + error_setg(errp, "Could not find working O_DIRECT alignment. " + "Try cache.direct=off."); + } } static void raw_parse_flags(int bdrv_flags, int *open_flags) @@ -505,6 +510,7 @@ static int raw_reopen_prepare(BDRVReopenState *state, BDRVRawState *s; BDRVRawReopenState *raw_s; int ret = 0; + Error *local_err = NULL; assert(state != NULL); assert(state->bs != NULL); @@ -577,6 +583,19 @@ static int raw_reopen_prepare(BDRVReopenState *state, ret = -1; } } + + /* Fail already reopen_prepare() if we can't get a working O_DIRECT + * alignment with the new fd. */ + if (raw_s->fd != -1) { + raw_probe_alignment(state->bs, raw_s->fd, &local_err); + if (local_err) { + qemu_close(raw_s->fd); + raw_s->fd = -1; + error_propagate(errp, local_err); + ret = -EINVAL; + } + } + return ret; } @@ -615,14 +634,12 @@ static void raw_reopen_abort(BDRVReopenState *state) state->opaque = NULL; } -static int raw_refresh_limits(BlockDriverState *bs) +static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVRawState *s = bs->opaque; - raw_probe_alignment(bs); + raw_probe_alignment(bs, s->fd, errp); bs->bl.opt_mem_alignment = s->buf_align; - - return 0; } static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) diff --git a/block/raw_bsd.c b/block/raw_bsd.c index 492f58de69..f82f4c25df 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -94,10 +94,9 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) return bdrv_get_info(bs->file, bdi); } -static int raw_refresh_limits(BlockDriverState *bs) +static void raw_refresh_limits(BlockDriverState *bs, Error **errp) { bs->bl = bs->file->bl; - return 0; } static int raw_truncate(BlockDriverState *bs, int64_t offset) diff --git a/block/stream.c b/block/stream.c index 34de8ba0d9..cdea3e8d0c 100644 --- a/block/stream.c +++ b/block/stream.c @@ -76,7 +76,7 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base, bdrv_unref(unused); } - bdrv_refresh_limits(top); + bdrv_refresh_limits(top, NULL); } static void coroutine_fn stream_run(void *opaque) diff --git a/block/vmdk.c b/block/vmdk.c index 27a78daa02..0517bbaf91 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -938,7 +938,7 @@ fail: } -static int vmdk_refresh_limits(BlockDriverState *bs) +static void vmdk_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVVmdkState *s = bs->opaque; int i; @@ -950,8 +950,6 @@ static int vmdk_refresh_limits(BlockDriverState *bs) s->extents[i].cluster_sectors); } } - - return 0; } static int get_whole_cluster(BlockDriverState *bs, |