From f53a829bb9ef14be800556cbc02d8b20fc1050a7 Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Fri, 6 Feb 2015 16:06:16 -0500 Subject: nbd: Drop BDS backpointer Before this patch, the "opaque" pointer in an NBD BDS points to a BDRVNBDState, which contains an NbdClientSession object, which in turn contains a pointer to the BDS. This pointer may become invalid due to bdrv_swap(), so drop it, and instead pass the BDS directly to the nbd-client.c functions which then retrieve the NbdClientSession object from there. Signed-off-by: Max Reitz Reviewed-by: Paolo Bonzini Message-id: 1423256778-3340-2-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/nbd.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/block/nbd.h b/include/block/nbd.h index b75959556c..ca9a5ac5b3 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -99,7 +99,6 @@ void nbd_export_close_all(void); NBDClient *nbd_client_new(NBDExport *exp, int csock, void (*close)(NBDClient *)); -void nbd_client_close(NBDClient *client); void nbd_client_get(NBDClient *client); void nbd_client_put(NBDClient *client); -- cgit v1.2.3 From b0e5d90ebc3edb5cfc1d5d33dd3334482dee6d46 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 26 Jan 2015 17:26:42 +0100 Subject: dataplane: endianness-aware accesses The vring.c code currently assumes that guest and host endianness match, which is not true for a number of cases: - emulating targets with a different endianness than the host - bi-endian targets, where the correct endianness depends on the virtio device - upcoming support for the virtio-1 standard mandates little-endian accesses even for big-endian targets and hosts Make sure to use accessors that depend on the virtio device. Note that dataplane now needs to be built per-target. Cc: Stefan Hajnoczi Cc: Paolo Bonzini Cc: Fam Zheng Reviewed-by: David Gibson Tested-by: David Gibson Signed-off-by: Cornelia Huck Reviewed-by: Stefan Hajnoczi Message-id: 1422289602-17874-2-git-send-email-cornelia.huck@de.ibm.com Signed-off-by: Stefan Hajnoczi --- include/hw/virtio/dataplane/vring-accessors.h | 75 +++++++++++++++++++++++++++ include/hw/virtio/dataplane/vring.h | 14 +---- 2 files changed, 77 insertions(+), 12 deletions(-) create mode 100644 include/hw/virtio/dataplane/vring-accessors.h (limited to 'include') diff --git a/include/hw/virtio/dataplane/vring-accessors.h b/include/hw/virtio/dataplane/vring-accessors.h new file mode 100644 index 0000000000..b508b87900 --- /dev/null +++ b/include/hw/virtio/dataplane/vring-accessors.h @@ -0,0 +1,75 @@ +#ifndef VRING_ACCESSORS_H +#define VRING_ACCESSORS_H + +#include "hw/virtio/virtio_ring.h" +#include "hw/virtio/virtio.h" +#include "hw/virtio/virtio-access.h" + +static inline uint16_t vring_get_used_idx(VirtIODevice *vdev, Vring *vring) +{ + return virtio_tswap16(vdev, vring->vr.used->idx); +} + +static inline void vring_set_used_idx(VirtIODevice *vdev, Vring *vring, + uint16_t idx) +{ + vring->vr.used->idx = virtio_tswap16(vdev, idx); +} + +static inline uint16_t vring_get_avail_idx(VirtIODevice *vdev, Vring *vring) +{ + return virtio_tswap16(vdev, vring->vr.avail->idx); +} + +static inline uint16_t vring_get_avail_ring(VirtIODevice *vdev, Vring *vring, + int i) +{ + return virtio_tswap16(vdev, vring->vr.avail->ring[i]); +} + +static inline void vring_set_used_ring_id(VirtIODevice *vdev, Vring *vring, + int i, uint32_t id) +{ + vring->vr.used->ring[i].id = virtio_tswap32(vdev, id); +} + +static inline void vring_set_used_ring_len(VirtIODevice *vdev, Vring *vring, + int i, uint32_t len) +{ + vring->vr.used->ring[i].len = virtio_tswap32(vdev, len); +} + +static inline uint16_t vring_get_used_flags(VirtIODevice *vdev, Vring *vring) +{ + return virtio_tswap16(vdev, vring->vr.used->flags); +} + +static inline uint16_t vring_get_avail_flags(VirtIODevice *vdev, Vring *vring) +{ + return virtio_tswap16(vdev, vring->vr.avail->flags); +} + +static inline void vring_set_used_flags(VirtIODevice *vdev, Vring *vring, + uint16_t flags) +{ + vring->vr.used->flags |= virtio_tswap16(vdev, flags); +} + +static inline void vring_clear_used_flags(VirtIODevice *vdev, Vring *vring, + uint16_t flags) +{ + vring->vr.used->flags &= virtio_tswap16(vdev, ~flags); +} + +static inline unsigned int vring_get_num(Vring *vring) +{ + return vring->vr.num; +} + +/* Are there more descriptors available? */ +static inline bool vring_more_avail(VirtIODevice *vdev, Vring *vring) +{ + return vring_get_avail_idx(vdev, vring) != vring->last_avail_idx; +} + +#endif diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h index d3e086aefc..e42c0fc9cc 100644 --- a/include/hw/virtio/dataplane/vring.h +++ b/include/hw/virtio/dataplane/vring.h @@ -31,17 +31,6 @@ typedef struct { bool broken; /* was there a fatal error? */ } Vring; -static inline unsigned int vring_get_num(Vring *vring) -{ - return vring->vr.num; -} - -/* Are there more descriptors available? */ -static inline bool vring_more_avail(Vring *vring) -{ - return vring->vr.avail->idx != vring->last_avail_idx; -} - /* Fail future vring_pop() and vring_push() calls until reset */ static inline void vring_set_broken(Vring *vring) { @@ -54,6 +43,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring); bool vring_enable_notification(VirtIODevice *vdev, Vring *vring); bool vring_should_notify(VirtIODevice *vdev, Vring *vring); int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem); -void vring_push(Vring *vring, VirtQueueElement *elem, int len); +void vring_push(VirtIODevice *vdev, Vring *vring, VirtQueueElement *elem, + int len); #endif /* VRING_H */ -- cgit v1.2.3 From 1ef01253eb90d0c69129c817e85fa92f9d45602a Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Thu, 5 Feb 2015 13:58:10 -0500 Subject: block: Lift some BDS functions to the BlockBackend Create the blk_* counterparts for the following bdrv_* functions (which make sense to call on the BlockBackend level): - bdrv_co_write_zeroes() - bdrv_write_compressed() - bdrv_truncate() - bdrv_nb_sectors() - bdrv_discard() - bdrv_load_vmstate() - bdrv_save_vmstate() Signed-off-by: Max Reitz Reviewed-by: Eric Blake Message-id: 1423162705-32065-2-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/sysemu/block-backend.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index aab12b982c..4ef0407536 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -91,6 +91,7 @@ int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count); int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count); int64_t blk_getlength(BlockBackend *blk); void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr); +int64_t blk_nb_sectors(BlockBackend *blk); BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num, QEMUIOVector *iov, int nb_sectors, BlockCompletionFunc *cb, void *opaque); @@ -151,5 +152,14 @@ BlockAcctStats *blk_get_stats(BlockBackend *blk); void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk, BlockCompletionFunc *cb, void *opaque); +int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num, + int nb_sectors, BdrvRequestFlags flags); +int blk_write_compressed(BlockBackend *blk, int64_t sector_num, + const uint8_t *buf, int nb_sectors); +int blk_truncate(BlockBackend *blk, int64_t offset); +int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors); +int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, + int64_t pos, int size); +int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size); #endif -- cgit v1.2.3 From ca49a4fdb39d7b00b20e8500cba11aedc87755bd Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Thu, 5 Feb 2015 13:58:11 -0500 Subject: block: Add blk_new_open() blk_new_with_bs() creates a BlockBackend with an empty BlockDriverState attached to it. Empty BDSs are not nice, therefore add an alternative function which combines blk_new_with_bs() with bdrv_open(). Note: In contrast to bdrv_open() which takes a BlockDriver parameter, blk_new_open() does not take such a parameter. This is because bdrv_open() opens a BlockDriverState, therefore it is natural to be able to set the BlockDriver for that BDS. The fact that bdrv_open() can open more than a single BDS is merely some form of a byproduct. blk_new_open() on the other hand is intended to be used to create a whole tree of BlockDriverStates. Therefore, setting a single BlockDriver does not make much sense. Instead, the drivers to be used for each of the nodes must be configured through the "options" QDict; including the driver of the root BDS. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Kevin Wolf Message-id: 1423162705-32065-3-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/sysemu/block-backend.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 4ef0407536..2e8ebb2535 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -62,6 +62,9 @@ typedef struct BlockDevOps { BlockBackend *blk_new(const char *name, Error **errp); BlockBackend *blk_new_with_bs(const char *name, Error **errp); +BlockBackend *blk_new_open(const char *name, const char *filename, + const char *reference, QDict *options, int flags, + Error **errp); void blk_ref(BlockBackend *blk); void blk_unref(BlockBackend *blk); const char *blk_name(BlockBackend *blk); -- cgit v1.2.3 From b65a5e12a4136b20f9d06675d597b52d64ac903c Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Thu, 5 Feb 2015 13:58:12 -0500 Subject: block: Add Error parameter to bdrv_find_protocol() The argument given to bdrv_find_protocol() is just a file name, which makes it difficult for the caller to reconstruct what protocol bdrv_find_protocol() was hoping to find. This patch adds an Error parameter to that function to solve this issue. Suggested-by: Eric Blake Signed-off-by: Max Reitz Reviewed-by: Eric Blake Message-id: 1423162705-32065-4-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/block.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/block/block.h b/include/block/block.h index 321295e5f7..471d11dbbe 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -168,7 +168,8 @@ void bdrv_io_limits_disable(BlockDriverState *bs); void bdrv_init(void); void bdrv_init_with_whitelist(void); BlockDriver *bdrv_find_protocol(const char *filename, - bool allow_protocol_prefix); + bool allow_protocol_prefix, + Error **errp); BlockDriver *bdrv_find_format(const char *format_name); BlockDriver *bdrv_find_whitelisted_format(const char *format_name, bool readonly); -- cgit v1.2.3 From 4c7b7e9b94b4e81aa85de7c13e209017fc7f61dc Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Thu, 5 Feb 2015 13:58:22 -0500 Subject: qemu-io: Use BlockBackend qemu-io should behave like a guest, therefore it should use BlockBackend to access the block layer. There are a couple of places where that is infeasible: First, the bdrv_debug_* functions could theoretically be mirrored in the BlockBackend, but since these are functions internal to the block layer, they should not be visible externally (qemu-io as a test tool is exempt from this). Second, bdrv_get_info() and bdrv_get_specific_info() work on a single BDS alone, therefore they should stay BDS-specific. Third, bdrv_is_allocated() mainly works on a single BDS as well. Some data may be passed through from the BDS's file (if sectors which are apparently allocated in the file are not really allocated there but just zero). [Fixed conflicts around block_acct_start() usage from Fam Zheng's "qemu-io: Account IO by aio_read and aio_write" commit. Use BlockBackend and blk_get_stats() instead of BlockDriverState. --Stefan] Signed-off-by: Max Reitz Reviewed-by: Eric Blake Message-id: 1423162705-32065-14-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/qemu-io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/qemu-io.h b/include/qemu-io.h index 5d6006f73b..4d402b9b01 100644 --- a/include/qemu-io.h +++ b/include/qemu-io.h @@ -22,7 +22,7 @@ #define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */ -typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv); +typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv); typedef void (*helpfunc_t)(void); typedef struct cmdinfo { @@ -40,7 +40,7 @@ typedef struct cmdinfo { extern bool qemuio_misalign; -bool qemuio_command(BlockDriverState *bs, const char *cmd); +bool qemuio_command(BlockBackend *blk, const char *cmd); void qemuio_add_command(const cmdinfo_t *ci); int qemuio_command_usage(const cmdinfo_t *ci); -- cgit v1.2.3 From c0191e763b2f77cc5311d3aa6e487f3fe8a4c96f Mon Sep 17 00:00:00 2001 From: Max Reitz Date: Thu, 5 Feb 2015 13:58:24 -0500 Subject: block: Remove "growable" from BDS Now that request clamping is done in the BlockBackend, the "growable" field can be removed from the BlockDriverState. All BDSs are now treated as being "growable" (that is, they are allowed to grow; they are not necessarily actually able to). Signed-off-by: Max Reitz Reviewed-by: Eric Blake Message-id: 1423162705-32065-16-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi --- include/block/block_int.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/block/block_int.h b/include/block/block_int.h index 7ad19503df..b340e7e140 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -369,9 +369,6 @@ struct BlockDriverState { /* I/O Limits */ BlockLimits bl; - /* Whether the disk can expand beyond total_sectors */ - int growable; - /* Whether produces zeros when read beyond eof */ bool zero_beyond_eof; -- cgit v1.2.3