mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches for 2.3 # gpg: Signature made Fri 06 Feb 2015 17:14:10 GMT using RSA key ID C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" * remotes/kevin/tags/for-upstream: (47 commits) block/raw-posix.c: Fix raw_getlength() on Mac OS X block devices block: Eliminate silly QERR_ macros used for encryption keys block: New bdrv_add_key(), convert monitor to use it blockdev: Eliminate silly QERR_BLOCK_JOB_NOT_ACTIVE macro blockdev: Give find_block_job() an Error ** parameter qcow2: Rewrite qcow2_alloc_bytes() block: Give always priority to unused entries in the qcow2 L2 cache nbd: fix max_discard/max_transfer_length block: introduce BDRV_REQUEST_MAX_SECTORS nbd: Improve error messages iotests: Fix 104 for NBD iotests: Fix 100 for nbd iotests: Fix 083 block: fix off-by-one error in qcow and qcow2 qemu-iotests: add 116 invalid QED input file tests qed: check for header size overflow block/dmg: improve zeroes handling block/dmg: support bzip2 block entry types block/dmg: factor out block type check block/dmg: use SectorNumber from BLKX header ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -2647,7 +2647,7 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
|
||||
{
|
||||
int64_t len;
|
||||
|
||||
if (size > INT_MAX) {
|
||||
if (size > BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2671,7 +2671,7 @@ static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
|
||||
static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors)
|
||||
{
|
||||
if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
|
||||
if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2758,7 +2758,7 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
|
||||
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
|
||||
};
|
||||
|
||||
if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
|
||||
if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -2826,13 +2826,10 @@ int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
nb_sectors = target_sectors - sector_num;
|
||||
nb_sectors = MIN(target_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);
|
||||
if (nb_sectors <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
|
||||
nb_sectors = INT_MAX / BDRV_SECTOR_SIZE;
|
||||
}
|
||||
ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n);
|
||||
if (ret < 0) {
|
||||
error_report("error getting block status at sector %" PRId64 ": %s",
|
||||
@@ -3167,7 +3164,7 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
if (nb_sectors < 0 || nb_sectors > (UINT_MAX >> BDRV_SECTOR_BITS)) {
|
||||
if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -3192,10 +3189,7 @@ int coroutine_fn bdrv_co_copy_on_readv(BlockDriverState *bs,
|
||||
BDRV_REQ_COPY_ON_READ);
|
||||
}
|
||||
|
||||
/* if no limit is specified in the BlockLimits use a default
|
||||
* of 32768 512-byte sectors (16 MiB) per request.
|
||||
*/
|
||||
#define MAX_WRITE_ZEROES_DEFAULT 32768
|
||||
#define MAX_WRITE_ZEROES_BOUNCE_BUFFER 32768
|
||||
|
||||
static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
|
||||
@@ -3205,8 +3199,8 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
||||
struct iovec iov = {0};
|
||||
int ret = 0;
|
||||
|
||||
int max_write_zeroes = bs->bl.max_write_zeroes ?
|
||||
bs->bl.max_write_zeroes : MAX_WRITE_ZEROES_DEFAULT;
|
||||
int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes,
|
||||
BDRV_REQUEST_MAX_SECTORS);
|
||||
|
||||
while (nb_sectors > 0 && !ret) {
|
||||
int num = nb_sectors;
|
||||
@@ -3242,7 +3236,7 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
||||
if (ret == -ENOTSUP) {
|
||||
/* Fall back to bounce buffer if write zeroes is unsupported */
|
||||
int max_xfer_len = MIN_NON_ZERO(bs->bl.max_transfer_length,
|
||||
MAX_WRITE_ZEROES_DEFAULT);
|
||||
MAX_WRITE_ZEROES_BOUNCE_BUFFER);
|
||||
num = MIN(num, max_xfer_len);
|
||||
iov.iov_len = num * BDRV_SECTOR_SIZE;
|
||||
if (iov.iov_base == NULL) {
|
||||
@@ -3461,7 +3455,7 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
|
||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags)
|
||||
{
|
||||
if (nb_sectors < 0 || nb_sectors > (INT_MAX >> BDRV_SECTOR_BITS)) {
|
||||
if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -3719,6 +3713,36 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide an encryption key for @bs.
|
||||
* If @key is non-null:
|
||||
* If @bs is not encrypted, fail.
|
||||
* Else if the key is invalid, fail.
|
||||
* Else set @bs's key to @key, replacing the existing key, if any.
|
||||
* If @key is null:
|
||||
* If @bs is encrypted and still lacks a key, fail.
|
||||
* Else do nothing.
|
||||
* On failure, store an error object through @errp if non-null.
|
||||
*/
|
||||
void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp)
|
||||
{
|
||||
if (key) {
|
||||
if (!bdrv_is_encrypted(bs)) {
|
||||
error_setg(errp, "Device '%s' is not encrypted",
|
||||
bdrv_get_device_name(bs));
|
||||
} else if (bdrv_set_key(bs, key) < 0) {
|
||||
error_set(errp, QERR_INVALID_PASSWORD);
|
||||
}
|
||||
} else {
|
||||
if (bdrv_key_required(bs)) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED,
|
||||
"'%s' (%s) is encrypted",
|
||||
bdrv_get_device_name(bs),
|
||||
bdrv_get_encrypted_filename(bs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *bdrv_get_format_name(BlockDriverState *bs)
|
||||
{
|
||||
return bs->drv ? bs->drv->format_name : NULL;
|
||||
@@ -4562,6 +4586,8 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
|
||||
}
|
||||
}
|
||||
|
||||
block_acct_merge_done(&bs->stats, BLOCK_ACCT_WRITE, num_reqs - outidx - 1);
|
||||
|
||||
return outidx + 1;
|
||||
}
|
||||
|
||||
@@ -5097,11 +5123,6 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque)
|
||||
rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
|
||||
}
|
||||
|
||||
/* if no limit is specified in the BlockLimits use a default
|
||||
* of 32768 512-byte sectors (16 MiB) per request.
|
||||
*/
|
||||
#define MAX_DISCARD_DEFAULT 32768
|
||||
|
||||
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors)
|
||||
{
|
||||
@@ -5126,7 +5147,7 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
|
||||
return 0;
|
||||
}
|
||||
|
||||
max_discard = bs->bl.max_discard ? bs->bl.max_discard : MAX_DISCARD_DEFAULT;
|
||||
max_discard = MIN_NON_ZERO(bs->bl.max_discard, BDRV_REQUEST_MAX_SECTORS);
|
||||
while (nb_sectors > 0) {
|
||||
int ret;
|
||||
int num = nb_sectors;
|
||||
|
||||
@@ -20,6 +20,7 @@ block-obj-$(CONFIG_GLUSTERFS) += gluster.o
|
||||
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
|
||||
block-obj-$(CONFIG_LIBSSH2) += ssh.o
|
||||
block-obj-y += accounting.o
|
||||
block-obj-y += write-threshold.o
|
||||
|
||||
common-obj-y += stream.o
|
||||
common-obj-y += commit.o
|
||||
@@ -36,5 +37,6 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
|
||||
ssh.o-cflags := $(LIBSSH2_CFLAGS)
|
||||
ssh.o-libs := $(LIBSSH2_LIBS)
|
||||
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
|
||||
dmg.o-libs := $(BZIP2_LIBS)
|
||||
qcow.o-libs := -lz
|
||||
linux-aio.o-libs := -laio
|
||||
|
||||
@@ -54,3 +54,10 @@ void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
|
||||
stats->wr_highest_sector = sector_num + nb_sectors - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void block_acct_merge_done(BlockAcctStats *stats, enum BlockAcctType type,
|
||||
int num_requests)
|
||||
{
|
||||
assert(type < BLOCK_MAX_IOTYPE);
|
||||
stats->merged[type] += num_requests;
|
||||
}
|
||||
|
||||
@@ -580,6 +580,11 @@ int blk_get_flags(BlockBackend *blk)
|
||||
return bdrv_get_flags(blk->bs);
|
||||
}
|
||||
|
||||
int blk_get_max_transfer_length(BlockBackend *blk)
|
||||
{
|
||||
return blk->bs->bl.max_transfer_length;
|
||||
}
|
||||
|
||||
void blk_set_guest_block_size(BlockBackend *blk, int align)
|
||||
{
|
||||
bdrv_set_guest_block_size(blk->bs, align);
|
||||
|
||||
+387
-119
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -373,7 +373,7 @@ void nbd_client_session_close(NbdClientSession *client)
|
||||
}
|
||||
|
||||
int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
|
||||
int sock, const char *export)
|
||||
int sock, const char *export, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -382,7 +382,7 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
|
||||
qemu_set_block(sock);
|
||||
ret = nbd_receive_negotiate(sock, export,
|
||||
&client->nbdflags, &client->size,
|
||||
&client->blocksize);
|
||||
&client->blocksize, errp);
|
||||
if (ret < 0) {
|
||||
logout("Failed to negotiate with the NBD server\n");
|
||||
closesocket(sock);
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ typedef struct NbdClientSession {
|
||||
} NbdClientSession;
|
||||
|
||||
int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
|
||||
int sock, const char *export_name);
|
||||
int sock, const char *export_name, Error **errp);
|
||||
void nbd_client_session_close(NbdClientSession *client);
|
||||
|
||||
int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
|
||||
|
||||
+10
-1
@@ -271,7 +271,7 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
/* NBD handshake */
|
||||
result = nbd_client_session_init(&s->client, bs, sock, export);
|
||||
result = nbd_client_session_init(&s->client, bs, sock, export, errp);
|
||||
g_free(export);
|
||||
return result;
|
||||
}
|
||||
@@ -301,6 +301,12 @@ static int nbd_co_flush(BlockDriverState *bs)
|
||||
return nbd_client_session_co_flush(&s->client);
|
||||
}
|
||||
|
||||
static void nbd_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
bs->bl.max_discard = UINT32_MAX >> BDRV_SECTOR_BITS;
|
||||
bs->bl.max_transfer_length = UINT32_MAX >> BDRV_SECTOR_BITS;
|
||||
}
|
||||
|
||||
static int nbd_co_discard(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors)
|
||||
{
|
||||
@@ -396,6 +402,7 @@ static BlockDriver bdrv_nbd = {
|
||||
.bdrv_close = nbd_close,
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
@@ -413,6 +420,7 @@ static BlockDriver bdrv_nbd_tcp = {
|
||||
.bdrv_close = nbd_close,
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
@@ -430,6 +438,7 @@ static BlockDriver bdrv_nbd_unix = {
|
||||
.bdrv_close = nbd_close,
|
||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||
.bdrv_co_discard = nbd_co_discard,
|
||||
.bdrv_refresh_limits = nbd_refresh_limits,
|
||||
.bdrv_getlength = nbd_getlength,
|
||||
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "block/qapi.h"
|
||||
#include "block/block_int.h"
|
||||
#include "block/write-threshold.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qapi-visit.h"
|
||||
#include "qapi/qmp-output-visitor.h"
|
||||
@@ -89,6 +90,8 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
|
||||
info->iops_size = cfg.op_size;
|
||||
}
|
||||
|
||||
info->write_threshold = bdrv_write_threshold_get(bs);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -335,6 +338,8 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
|
||||
s->stats->wr_bytes = bs->stats.nr_bytes[BLOCK_ACCT_WRITE];
|
||||
s->stats->rd_operations = bs->stats.nr_ops[BLOCK_ACCT_READ];
|
||||
s->stats->wr_operations = bs->stats.nr_ops[BLOCK_ACCT_WRITE];
|
||||
s->stats->rd_merged = bs->stats.merged[BLOCK_ACCT_READ];
|
||||
s->stats->wr_merged = bs->stats.merged[BLOCK_ACCT_WRITE];
|
||||
s->stats->wr_highest_offset =
|
||||
bs->stats.wr_highest_sector * BDRV_SECTOR_SIZE;
|
||||
s->stats->flush_operations = bs->stats.nr_ops[BLOCK_ACCT_FLUSH];
|
||||
|
||||
+1
-1
@@ -215,7 +215,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
/* read the backing file name */
|
||||
if (header.backing_file_offset != 0) {
|
||||
len = header.backing_file_size;
|
||||
if (len > 1023 || len > sizeof(bs->backing_file)) {
|
||||
if (len > 1023 || len >= sizeof(bs->backing_file)) {
|
||||
error_setg(errp, "Backing file name too long");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
|
||||
+3
-1
@@ -253,7 +253,9 @@ static int qcow2_cache_find_entry_to_replace(Qcow2Cache *c)
|
||||
|
||||
/* Give newer hits priority */
|
||||
/* TODO Check how to optimize the replacement strategy */
|
||||
c->entries[i].cache_hits /= 2;
|
||||
if (c->entries[i].cache_hits > 1) {
|
||||
c->entries[i].cache_hits /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (min_index == -1) {
|
||||
|
||||
+40
-40
@@ -759,54 +759,54 @@ int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
|
||||
int64_t qcow2_alloc_bytes(BlockDriverState *bs, int size)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int64_t offset, cluster_offset;
|
||||
int free_in_cluster;
|
||||
int64_t offset;
|
||||
size_t free_in_cluster;
|
||||
int ret;
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC_BYTES);
|
||||
assert(size > 0 && size <= s->cluster_size);
|
||||
if (s->free_byte_offset == 0) {
|
||||
offset = qcow2_alloc_clusters(bs, s->cluster_size);
|
||||
if (offset < 0) {
|
||||
return offset;
|
||||
assert(!s->free_byte_offset || offset_into_cluster(s, s->free_byte_offset));
|
||||
|
||||
offset = s->free_byte_offset;
|
||||
|
||||
if (offset) {
|
||||
int refcount = qcow2_get_refcount(bs, offset >> s->cluster_bits);
|
||||
if (refcount < 0) {
|
||||
return refcount;
|
||||
}
|
||||
s->free_byte_offset = offset;
|
||||
}
|
||||
redo:
|
||||
free_in_cluster = s->cluster_size -
|
||||
offset_into_cluster(s, s->free_byte_offset);
|
||||
if (size <= free_in_cluster) {
|
||||
/* enough space in current cluster */
|
||||
offset = s->free_byte_offset;
|
||||
s->free_byte_offset += size;
|
||||
free_in_cluster -= size;
|
||||
if (free_in_cluster == 0)
|
||||
s->free_byte_offset = 0;
|
||||
if (offset_into_cluster(s, offset) != 0)
|
||||
qcow2_update_cluster_refcount(bs, offset >> s->cluster_bits, 1,
|
||||
QCOW2_DISCARD_NEVER);
|
||||
} else {
|
||||
offset = qcow2_alloc_clusters(bs, s->cluster_size);
|
||||
if (offset < 0) {
|
||||
return offset;
|
||||
}
|
||||
cluster_offset = start_of_cluster(s, s->free_byte_offset);
|
||||
if ((cluster_offset + s->cluster_size) == offset) {
|
||||
/* we are lucky: contiguous data */
|
||||
offset = s->free_byte_offset;
|
||||
qcow2_update_cluster_refcount(bs, offset >> s->cluster_bits, 1,
|
||||
QCOW2_DISCARD_NEVER);
|
||||
s->free_byte_offset += size;
|
||||
} else {
|
||||
s->free_byte_offset = offset;
|
||||
goto redo;
|
||||
|
||||
if (refcount == 0xffff) {
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The cluster refcount was incremented, either by qcow2_alloc_clusters()
|
||||
* or explicitly by qcow2_update_cluster_refcount(). Refcount blocks must
|
||||
* be flushed before the caller's L2 table updates.
|
||||
*/
|
||||
free_in_cluster = s->cluster_size - offset_into_cluster(s, offset);
|
||||
if (!offset || free_in_cluster < size) {
|
||||
int64_t new_cluster = alloc_clusters_noref(bs, s->cluster_size);
|
||||
if (new_cluster < 0) {
|
||||
return new_cluster;
|
||||
}
|
||||
|
||||
if (!offset || ROUND_UP(offset, s->cluster_size) != new_cluster) {
|
||||
offset = new_cluster;
|
||||
}
|
||||
}
|
||||
|
||||
assert(offset);
|
||||
ret = update_refcount(bs, offset, size, 1, QCOW2_DISCARD_NEVER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The cluster refcount was incremented; refcount blocks must be flushed
|
||||
* before the caller's L2 table updates. */
|
||||
qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
|
||||
|
||||
s->free_byte_offset = offset + size;
|
||||
if (!offset_into_cluster(s, s->free_byte_offset)) {
|
||||
s->free_byte_offset = 0;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -869,7 +869,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
if (header.backing_file_offset != 0) {
|
||||
len = header.backing_file_size;
|
||||
if (len > MIN(1023, s->cluster_size - header.backing_file_offset) ||
|
||||
len > sizeof(bs->backing_file)) {
|
||||
len >= sizeof(bs->backing_file)) {
|
||||
error_setg(errp, "Backing file name too long");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
|
||||
@@ -440,6 +440,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
s->l2_mask = s->table_nelems - 1;
|
||||
s->l1_shift = s->l2_shift + ffs(s->table_nelems) - 1;
|
||||
|
||||
/* Header size calculation must not overflow uint32_t */
|
||||
if (s->header.header_size > UINT32_MAX / s->header.cluster_size) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((s->header.features & QED_F_BACKING_FILE)) {
|
||||
if ((uint64_t)s->header.backing_filename_offset +
|
||||
s->header.backing_filename_size >
|
||||
|
||||
@@ -133,7 +133,6 @@ typedef struct QEDAIOCB {
|
||||
int bh_ret; /* final return status for completion bh */
|
||||
QSIMPLEQ_ENTRY(QEDAIOCB) next; /* next request */
|
||||
int flags; /* QED_AIOCB_* bits ORed together */
|
||||
bool *finished; /* signal for cancel completion */
|
||||
uint64_t end_pos; /* request end on block device, in bytes */
|
||||
|
||||
/* User scatter-gather list */
|
||||
|
||||
+111
-35
@@ -60,7 +60,7 @@
|
||||
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
||||
#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE_ZERO_RANGE)
|
||||
#include <linux/falloc.h>
|
||||
#endif
|
||||
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
@@ -147,6 +147,7 @@ typedef struct BDRVRawState {
|
||||
bool has_discard:1;
|
||||
bool has_write_zeroes:1;
|
||||
bool discard_zeroes:1;
|
||||
bool has_fallocate;
|
||||
bool needs_alignment;
|
||||
} BDRVRawState;
|
||||
|
||||
@@ -452,6 +453,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
s->discard_zeroes = true;
|
||||
s->has_fallocate = true;
|
||||
}
|
||||
if (S_ISBLK(st.st_mode)) {
|
||||
#ifdef BLKDISCARDZEROES
|
||||
@@ -893,42 +895,110 @@ static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
|
||||
static int translate_err(int err)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
|
||||
err == -ENOTTY) {
|
||||
err = -ENOTSUP;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FALLOCATE
|
||||
static int do_fallocate(int fd, int mode, off_t offset, off_t len)
|
||||
{
|
||||
do {
|
||||
if (fallocate(fd, mode, offset, len) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
return translate_err(-errno);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
|
||||
{
|
||||
int ret = -ENOTSUP;
|
||||
BDRVRawState *s = aiocb->bs->opaque;
|
||||
|
||||
if (s->has_write_zeroes == 0) {
|
||||
if (!s->has_write_zeroes) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
|
||||
#ifdef BLKZEROOUT
|
||||
do {
|
||||
uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
|
||||
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
ret = -errno;
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CONFIG_XFS
|
||||
if (s->is_xfs) {
|
||||
return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
do {
|
||||
uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };
|
||||
if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
|
||||
ret == -ENOTTY) {
|
||||
ret = translate_err(-errno);
|
||||
#endif
|
||||
|
||||
if (ret == -ENOTSUP) {
|
||||
s->has_write_zeroes = false;
|
||||
ret = -ENOTSUP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
|
||||
{
|
||||
BDRVRawState *s = aiocb->bs->opaque;
|
||||
|
||||
if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
|
||||
return handle_aiocb_write_zeroes_block(aiocb);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XFS
|
||||
if (s->is_xfs) {
|
||||
return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
|
||||
if (s->has_write_zeroes) {
|
||||
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
|
||||
aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0 || ret != -ENOTSUP) {
|
||||
return ret;
|
||||
}
|
||||
s->has_write_zeroes = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
||||
if (s->has_discard && s->has_fallocate) {
|
||||
int ret = do_fallocate(s->fd,
|
||||
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||
aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0) {
|
||||
ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0 || ret != -ENOTSUP) {
|
||||
return ret;
|
||||
}
|
||||
s->has_fallocate = false;
|
||||
} else if (ret != -ENOTSUP) {
|
||||
return ret;
|
||||
} else {
|
||||
s->has_discard = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FALLOCATE
|
||||
if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) {
|
||||
int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
if (ret == 0 || ret != -ENOTSUP) {
|
||||
return ret;
|
||||
}
|
||||
s->has_fallocate = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
@@ -957,21 +1027,14 @@ static ssize_t handle_aiocb_discard(RawPosixAIOData *aiocb)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
||||
do {
|
||||
if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||
aiocb->aio_offset, aiocb->aio_nbytes) == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (errno == EINTR);
|
||||
|
||||
ret = -errno;
|
||||
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||
aiocb->aio_offset, aiocb->aio_nbytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||
|
||||
ret == -ENOTTY) {
|
||||
ret = translate_err(ret);
|
||||
if (ret == -ENOTSUP) {
|
||||
s->has_discard = false;
|
||||
ret = -ENOTSUP;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -1312,7 +1375,20 @@ again:
|
||||
if (size == 0)
|
||||
#endif
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
size = LLONG_MAX;
|
||||
{
|
||||
uint64_t sectors = 0;
|
||||
uint32_t sector_size = 0;
|
||||
|
||||
if (ioctl(fd, DKIOCGETBLOCKCOUNT, §ors) == 0
|
||||
&& ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) == 0) {
|
||||
size = sectors * sector_size;
|
||||
} else {
|
||||
size = lseek(fd, 0LL, SEEK_END);
|
||||
if (size < 0) {
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
size = lseek(fd, 0LL, SEEK_END);
|
||||
if (size < 0) {
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* QEMU System Emulator block write threshold notification
|
||||
*
|
||||
* Copyright Red Hat, Inc. 2014
|
||||
*
|
||||
* Authors:
|
||||
* Francesco Romani <fromani@redhat.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "block/block_int.h"
|
||||
#include "block/coroutine.h"
|
||||
#include "block/write-threshold.h"
|
||||
#include "qemu/notify.h"
|
||||
#include "qapi-event.h"
|
||||
#include "qmp-commands.h"
|
||||
|
||||
|
||||
uint64_t bdrv_write_threshold_get(const BlockDriverState *bs)
|
||||
{
|
||||
return bs->write_threshold_offset;
|
||||
}
|
||||
|
||||
bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
|
||||
{
|
||||
return bs->write_threshold_offset > 0;
|
||||
}
|
||||
|
||||
static void write_threshold_disable(BlockDriverState *bs)
|
||||
{
|
||||
if (bdrv_write_threshold_is_set(bs)) {
|
||||
notifier_with_return_remove(&bs->write_threshold_notifier);
|
||||
bs->write_threshold_offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
|
||||
const BdrvTrackedRequest *req)
|
||||
{
|
||||
if (bdrv_write_threshold_is_set(bs)) {
|
||||
if (req->offset > bs->write_threshold_offset) {
|
||||
return (req->offset - bs->write_threshold_offset) + req->bytes;
|
||||
}
|
||||
if ((req->offset + req->bytes) > bs->write_threshold_offset) {
|
||||
return (req->offset + req->bytes) - bs->write_threshold_offset;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int coroutine_fn before_write_notify(NotifierWithReturn *notifier,
|
||||
void *opaque)
|
||||
{
|
||||
BdrvTrackedRequest *req = opaque;
|
||||
BlockDriverState *bs = req->bs;
|
||||
uint64_t amount = 0;
|
||||
|
||||
amount = bdrv_write_threshold_exceeded(bs, req);
|
||||
if (amount > 0) {
|
||||
qapi_event_send_block_write_threshold(
|
||||
bs->node_name,
|
||||
amount,
|
||||
bs->write_threshold_offset,
|
||||
&error_abort);
|
||||
|
||||
/* autodisable to avoid flooding the monitor */
|
||||
write_threshold_disable(bs);
|
||||
}
|
||||
|
||||
return 0; /* should always let other notifiers run */
|
||||
}
|
||||
|
||||
static void write_threshold_register_notifier(BlockDriverState *bs)
|
||||
{
|
||||
bs->write_threshold_notifier.notify = before_write_notify;
|
||||
notifier_with_return_list_add(&bs->before_write_notifiers,
|
||||
&bs->write_threshold_notifier);
|
||||
}
|
||||
|
||||
static void write_threshold_update(BlockDriverState *bs,
|
||||
int64_t threshold_bytes)
|
||||
{
|
||||
bs->write_threshold_offset = threshold_bytes;
|
||||
}
|
||||
|
||||
void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
|
||||
{
|
||||
if (bdrv_write_threshold_is_set(bs)) {
|
||||
if (threshold_bytes > 0) {
|
||||
write_threshold_update(bs, threshold_bytes);
|
||||
} else {
|
||||
write_threshold_disable(bs);
|
||||
}
|
||||
} else {
|
||||
if (threshold_bytes > 0) {
|
||||
/* avoid multiple registration */
|
||||
write_threshold_register_notifier(bs);
|
||||
write_threshold_update(bs, threshold_bytes);
|
||||
}
|
||||
/* discard bogus disable request */
|
||||
}
|
||||
}
|
||||
|
||||
void qmp_block_set_write_threshold(const char *node_name,
|
||||
uint64_t threshold_bytes,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, node_name);
|
||||
return;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
bdrv_write_threshold_set(bs, threshold_bytes);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
+11
-33
@@ -1793,7 +1793,6 @@ void qmp_block_passwd(bool has_device, const char *device,
|
||||
Error *local_err = NULL;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
int err;
|
||||
|
||||
bs = bdrv_lookup_bs(has_device ? device : NULL,
|
||||
has_node_name ? node_name : NULL,
|
||||
@@ -1806,16 +1805,8 @@ void qmp_block_passwd(bool has_device, const char *device,
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
err = bdrv_set_key(bs, password);
|
||||
if (err == -EINVAL) {
|
||||
error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
|
||||
goto out;
|
||||
} else if (err < 0) {
|
||||
error_set(errp, QERR_INVALID_PASSWORD);
|
||||
goto out;
|
||||
}
|
||||
bdrv_add_key(bs, password, errp);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
@@ -1833,18 +1824,7 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
|
||||
return;
|
||||
}
|
||||
|
||||
if (bdrv_key_required(bs)) {
|
||||
if (password) {
|
||||
if (bdrv_set_key(bs, password) < 0) {
|
||||
error_set(errp, QERR_INVALID_PASSWORD);
|
||||
}
|
||||
} else {
|
||||
error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),
|
||||
bdrv_get_encrypted_filename(bs));
|
||||
}
|
||||
} else if (password) {
|
||||
error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
|
||||
}
|
||||
bdrv_add_key(bs, password, errp);
|
||||
}
|
||||
|
||||
void qmp_change_blockdev(const char *device, const char *filename,
|
||||
@@ -2653,7 +2633,8 @@ out:
|
||||
}
|
||||
|
||||
/* Get the block job for a given device name and acquire its AioContext */
|
||||
static BlockJob *find_block_job(const char *device, AioContext **aio_context)
|
||||
static BlockJob *find_block_job(const char *device, AioContext **aio_context,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
|
||||
@@ -2673,6 +2654,8 @@ static BlockJob *find_block_job(const char *device, AioContext **aio_context)
|
||||
return bs->job;
|
||||
|
||||
notfound:
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
|
||||
"No active block job on device '%s'", device);
|
||||
*aio_context = NULL;
|
||||
return NULL;
|
||||
}
|
||||
@@ -2680,10 +2663,9 @@ notfound:
|
||||
void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockJob *job = find_block_job(device, &aio_context);
|
||||
BlockJob *job = find_block_job(device, &aio_context, errp);
|
||||
|
||||
if (!job) {
|
||||
error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2695,10 +2677,9 @@ void qmp_block_job_cancel(const char *device,
|
||||
bool has_force, bool force, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockJob *job = find_block_job(device, &aio_context);
|
||||
BlockJob *job = find_block_job(device, &aio_context, errp);
|
||||
|
||||
if (!job) {
|
||||
error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2721,10 +2702,9 @@ out:
|
||||
void qmp_block_job_pause(const char *device, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockJob *job = find_block_job(device, &aio_context);
|
||||
BlockJob *job = find_block_job(device, &aio_context, errp);
|
||||
|
||||
if (!job) {
|
||||
error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2736,10 +2716,9 @@ void qmp_block_job_pause(const char *device, Error **errp)
|
||||
void qmp_block_job_resume(const char *device, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockJob *job = find_block_job(device, &aio_context);
|
||||
BlockJob *job = find_block_job(device, &aio_context, errp);
|
||||
|
||||
if (!job) {
|
||||
error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2751,10 +2730,9 @@ void qmp_block_job_resume(const char *device, Error **errp)
|
||||
void qmp_block_job_complete(const char *device, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockJob *job = find_block_job(device, &aio_context);
|
||||
BlockJob *job = find_block_job(device, &aio_context, errp);
|
||||
|
||||
if (!job) {
|
||||
error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -313,6 +313,7 @@ glx=""
|
||||
zlib="yes"
|
||||
lzo=""
|
||||
snappy=""
|
||||
bzip2=""
|
||||
guest_agent=""
|
||||
guest_agent_with_vss="no"
|
||||
vss_win32_sdk=""
|
||||
@@ -1060,6 +1061,10 @@ for opt do
|
||||
;;
|
||||
--enable-snappy) snappy="yes"
|
||||
;;
|
||||
--disable-bzip2) bzip2="no"
|
||||
;;
|
||||
--enable-bzip2) bzip2="yes"
|
||||
;;
|
||||
--enable-guest-agent) guest_agent="yes"
|
||||
;;
|
||||
--disable-guest-agent) guest_agent="no"
|
||||
@@ -1374,6 +1379,8 @@ Advanced options (experts only):
|
||||
--enable-usb-redir enable usb network redirection support
|
||||
--enable-lzo enable the support of lzo compression library
|
||||
--enable-snappy enable the support of snappy compression library
|
||||
--enable-bzip2 enable the support of bzip2 compression library (for
|
||||
reading bzip2-compressed dmg images)
|
||||
--disable-guest-agent disable building of the QEMU Guest Agent
|
||||
--enable-guest-agent enable building of the QEMU Guest Agent
|
||||
--with-vss-sdk=SDK-path enable Windows VSS support in QEMU Guest Agent
|
||||
@@ -1819,6 +1826,24 @@ EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# bzip2 check
|
||||
|
||||
if test "$bzip2" != "no" ; then
|
||||
cat > $TMPC << EOF
|
||||
#include <bzlib.h>
|
||||
int main(void) { BZ2_bzlibVersion(); return 0; }
|
||||
EOF
|
||||
if compile_prog "" "-lbz2" ; then
|
||||
bzip2="yes"
|
||||
else
|
||||
if test "$bzip2" = "yes"; then
|
||||
feature_not_found "libbzip2" "Install libbzip2 devel"
|
||||
fi
|
||||
bzip2="no"
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# libseccomp check
|
||||
|
||||
@@ -3335,6 +3360,22 @@ if compile_prog "" "" ; then
|
||||
fallocate_punch_hole=yes
|
||||
fi
|
||||
|
||||
# check that fallocate supports range zeroing inside the file
|
||||
fallocate_zero_range=no
|
||||
cat > $TMPC << EOF
|
||||
#include <fcntl.h>
|
||||
#include <linux/falloc.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
fallocate(0, FALLOC_FL_ZERO_RANGE, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
fallocate_zero_range=yes
|
||||
fi
|
||||
|
||||
# check for posix_fallocate
|
||||
posix_fallocate=no
|
||||
cat > $TMPC << EOF
|
||||
@@ -4369,6 +4410,7 @@ echo "vhdx $vhdx"
|
||||
echo "Quorum $quorum"
|
||||
echo "lzo support $lzo"
|
||||
echo "snappy support $snappy"
|
||||
echo "bzip2 support $bzip2"
|
||||
echo "NUMA host support $numa"
|
||||
|
||||
if test "$sdl_too_old" = "yes"; then
|
||||
@@ -4567,6 +4609,9 @@ fi
|
||||
if test "$fallocate_punch_hole" = "yes" ; then
|
||||
echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$fallocate_zero_range" = "yes" ; then
|
||||
echo "CONFIG_FALLOCATE_ZERO_RANGE=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$posix_fallocate" = "yes" ; then
|
||||
echo "CONFIG_POSIX_FALLOCATE=y" >> $config_host_mak
|
||||
fi
|
||||
@@ -4724,6 +4769,11 @@ if test "$snappy" = "yes" ; then
|
||||
echo "CONFIG_SNAPPY=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$bzip2" = "yes" ; then
|
||||
echo "CONFIG_BZIP2=y" >> $config_host_mak
|
||||
echo "BZIP2_LIBS=-lbz2" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$libiscsi" = "yes" ; then
|
||||
echo "CONFIG_LIBISCSI=m" >> $config_host_mak
|
||||
echo "LIBISCSI_CFLAGS=$libiscsi_cflags" >> $config_host_mak
|
||||
|
||||
@@ -474,6 +474,8 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
|
||||
" wr_total_time_ns=%" PRId64
|
||||
" rd_total_time_ns=%" PRId64
|
||||
" flush_total_time_ns=%" PRId64
|
||||
" rd_merged=%" PRId64
|
||||
" wr_merged=%" PRId64
|
||||
"\n",
|
||||
stats->value->stats->rd_bytes,
|
||||
stats->value->stats->wr_bytes,
|
||||
@@ -482,7 +484,9 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
|
||||
stats->value->stats->flush_operations,
|
||||
stats->value->stats->wr_total_time_ns,
|
||||
stats->value->stats->rd_total_time_ns,
|
||||
stats->value->stats->flush_total_time_ns);
|
||||
stats->value->stats->flush_total_time_ns,
|
||||
stats->value->stats->rd_merged,
|
||||
stats->value->stats->wr_merged);
|
||||
}
|
||||
|
||||
qapi_free_BlockStatsList(stats_list);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user