Similarly to the previous patches, split block-backend.h
in block-backend-io.h and block-backend-global-state.h
In addition, remove "block/block.h" include as it seems
it is not necessary anymore, together with "qemu/iov.h"
block-backend-common.h contains the structures shared between
the two headers, and the functions that can't be categorized as
I/O or global state.
Assertions are added in the next patch.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/block-backend.c | 9 +-
include/sysemu/block-backend-common.h | 74 ++++++
include/sysemu/block-backend-global-state.h | 122 +++++++++
include/sysemu/block-backend-io.h | 139 ++++++++++
include/sysemu/block-backend.h | 269 +-------------------
5 files changed, 344 insertions(+), 269 deletions(-)
create mode 100644 include/sysemu/block-backend-common.h
create mode 100644 include/sysemu/block-backend-global-state.h
create mode 100644 include/sysemu/block-backend-io.h
diff --git a/block/block-backend.c b/block/block-backend.c
index 39cd99df2b..0afc03fd66 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -79,6 +79,7 @@ struct BlockBackend {
bool allow_aio_context_change;
bool allow_write_beyond_eof;
+ /* Protected by BQL lock */
NotifierList remove_bs_notifiers, insert_bs_notifiers;
QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
@@ -111,12 +112,14 @@ static const AIOCBInfo block_backend_aiocb_info = {
static void drive_info_del(DriveInfo *dinfo);
static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
-/* All BlockBackends */
+/* All BlockBackends. Protected by BQL lock. */
static QTAILQ_HEAD(, BlockBackend) block_backends =
QTAILQ_HEAD_INITIALIZER(block_backends);
-/* All BlockBackends referenced by the monitor and which are iterated through by
- * blk_next() */
+/*
+ * All BlockBackends referenced by the monitor and which are iterated through by
+ * blk_next(). Protected by BQL lock.
+ */
static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h
new file mode 100644
index 0000000000..52ff6a4d26
--- /dev/null
+++ b/include/sysemu/block-backend-common.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_COMMON_H
+#define BLOCK_BACKEND_COMMON_H
+
+#include "block/throttle-groups.h"
+
+/* Callbacks for block device models */
+typedef struct BlockDevOps {
+ /*
+ * Runs when virtual media changed (monitor commands eject, change)
+ * Argument load is true on load and false on eject.
+ * Beware: doesn't run when a host device's physical media
+ * changes. Sure would be useful if it did.
+ * Device models with removable media must implement this callback.
+ */
+ void (*change_media_cb)(void *opaque, bool load, Error **errp);
+ /*
+ * Runs when an eject request is issued from the monitor, the tray
+ * is closed, and the medium is locked.
+ * Device models that do not implement is_medium_locked will not need
+ * this callback. Device models that can lock the medium or tray might
+ * want to implement the callback and unlock the tray when "force" is
+ * true, even if they do not support eject requests.
+ */
+ void (*eject_request_cb)(void *opaque, bool force);
+ /*
+ * Is the virtual tray open?
+ * Device models implement this only when the device has a tray.
+ */
+ bool (*is_tray_open)(void *opaque);
+ /*
+ * Is the virtual medium locked into the device?
+ * Device models implement this only when device has such a lock.
+ */
+ bool (*is_medium_locked)(void *opaque);
+ /*
+ * Runs when the size changed (e.g. monitor command block_resize)
+ */
+ void (*resize_cb)(void *opaque);
+ /*
+ * Runs when the backend receives a drain request.
+ */
+ void (*drained_begin)(void *opaque);
+ /*
+ * Runs when the backend's last drain request ends.
+ */
+ void (*drained_end)(void *opaque);
+ /*
+ * Is the device still busy?
+ */
+ bool (*drained_poll)(void *opaque);
+} BlockDevOps;
+
+/*
+ * This struct is embedded in (the private) BlockBackend struct and contains
+ * fields that must be public. This is in particular for QLIST_ENTRY() and
+ * friends so that BlockBackends can be kept in lists outside block-backend.c
+ */
+typedef struct BlockBackendPublic {
+ ThrottleGroupMember throttle_group_member;
+} BlockBackendPublic;
+
+#endif /* BLOCK_BACKEND_COMMON_H */
diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
new file mode 100644
index 0000000000..4001b1c02a
--- /dev/null
+++ b/include/sysemu/block-backend-global-state.h
@@ -0,0 +1,122 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_GS_H
+#define BLOCK_BACKEND_GS_H
+
+#include "block-backend-common.h"
+
+/*
+ * Global state (GS) API. These functions run under the BQL lock.
+ *
+ * See include/block/block-global-state.h for more information about
+ * the GS API.
+ */
+
+BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
+BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
+ uint64_t shared_perm, Error **errp);
+BlockBackend *blk_new_open(const char *filename, const char *reference,
+ QDict *options, int flags, Error **errp);
+int blk_get_refcnt(BlockBackend *blk);
+void blk_ref(BlockBackend *blk);
+void blk_unref(BlockBackend *blk);
+void blk_remove_all_bs(void);
+const char *blk_name(const BlockBackend *blk);
+BlockBackend *blk_by_name(const char *name);
+BlockBackend *blk_next(BlockBackend *blk);
+BlockBackend *blk_all_next(BlockBackend *blk);
+bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
+void monitor_remove_blk(BlockBackend *blk);
+
+BlockBackendPublic *blk_get_public(BlockBackend *blk);
+BlockBackend *blk_by_public(BlockBackendPublic *public);
+
+void blk_remove_bs(BlockBackend *blk);
+int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
+bool bdrv_has_blk(BlockDriverState *bs);
+bool bdrv_is_root_node(BlockDriverState *bs);
+int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
+ Error **errp);
+void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
+
+void blk_iostatus_enable(BlockBackend *blk);
+bool blk_iostatus_is_enabled(const BlockBackend *blk);
+BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
+void blk_iostatus_disable(BlockBackend *blk);
+void blk_iostatus_reset(BlockBackend *blk);
+void blk_iostatus_set_err(BlockBackend *blk, int error);
+int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
+void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
+DeviceState *blk_get_attached_dev(BlockBackend *blk);
+char *blk_get_attached_dev_id(BlockBackend *blk);
+BlockBackend *blk_by_dev(void *dev);
+BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
+void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
+
+int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
+int64_t blk_nb_sectors(BlockBackend *blk);
+int blk_commit_all(void);
+void blk_drain(BlockBackend *blk);
+void blk_drain_all(void);
+void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
+ BlockdevOnError on_write_error);
+bool blk_supports_write_perm(BlockBackend *blk);
+bool blk_is_sg(BlockBackend *blk);
+bool blk_enable_write_cache(BlockBackend *blk);
+void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
+void blk_lock_medium(BlockBackend *blk, bool locked);
+void blk_eject(BlockBackend *blk, bool eject_flag);
+int blk_get_flags(BlockBackend *blk);
+void blk_set_guest_block_size(BlockBackend *blk, int align);
+bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
+void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
+void blk_op_block_all(BlockBackend *blk, Error *reason);
+void blk_op_unblock_all(BlockBackend *blk, Error *reason);
+int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
+ Error **errp);
+void blk_add_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *new_context, void *opaque),
+ void (*detach_aio_context)(void *opaque), void *opaque);
+void blk_remove_aio_context_notifier(BlockBackend *blk,
+ void (*attached_aio_context)(AioContext *,
+ void *),
+ void (*detach_aio_context)(void *),
+ void *opaque);
+void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
+void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
+BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
+void blk_update_root_state(BlockBackend *blk);
+bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
+int blk_get_open_flags_from_root_state(BlockBackend *blk);
+
+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);
+int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
+int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
+BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
+ BlockCompletionFunc *cb,
+ void *opaque, int ret);
+
+void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
+void blk_io_limits_disable(BlockBackend *blk);
+void blk_io_limits_enable(BlockBackend *blk, const char *group);
+void blk_io_limits_update_group(BlockBackend *blk, const char *group);
+void blk_set_force_allow_inactivate(BlockBackend *blk);
+
+void blk_register_buf(BlockBackend *blk, void *host, size_t size);
+void blk_unregister_buf(BlockBackend *blk, void *host);
+
+const BdrvChild *blk_root(BlockBackend *blk);
+
+#endif /* BLOCK_BACKEND_GS_H */
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
new file mode 100644
index 0000000000..ab0463cb69
--- /dev/null
+++ b/include/sysemu/block-backend-io.h
@@ -0,0 +1,139 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014-2016 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_IO_H
+#define BLOCK_BACKEND_IO_H
+
+#include "block-backend-common.h"
+
+/*
+ * I/O API functions. These functions are thread-safe.
+ *
+ * See include/block/block-io.h for more information about
+ * the I/O API.
+ */
+
+BlockDriverState *blk_bs(BlockBackend *blk);
+
+int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
+
+void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
+void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
+void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
+
+int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes);
+int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
+ int64_t bytes,
+ QEMUIOVector *qiov, size_t qiov_offset,
+ BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
+ int64_t bytes, QEMUIOVector *qiov,
+ BdrvRequestFlags flags);
+
+static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
+ int64_t bytes, void *buf,
+ BdrvRequestFlags flags)
+{
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
+
+ assert(bytes <= SIZE_MAX);
+
+ return blk_co_preadv(blk, offset, bytes, &qiov, flags);
+}
+
+static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
+ int64_t bytes, void *buf,
+ BdrvRequestFlags flags)
+{
+ QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
+
+ assert(bytes <= SIZE_MAX);
+
+ return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
+}
+
+BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+
+BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
+ QEMUIOVector *qiov, BdrvRequestFlags flags,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_flush(BlockBackend *blk,
+ BlockCompletionFunc *cb, void *opaque);
+BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
+ BlockCompletionFunc *cb, void *opaque);
+void blk_aio_cancel(BlockAIOCB *acb);
+void blk_aio_cancel_async(BlockAIOCB *acb);
+int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
+BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
+ BlockCompletionFunc *cb, void *opaque);
+int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
+ int64_t bytes);
+int coroutine_fn blk_co_flush(BlockBackend *blk);
+int blk_flush(BlockBackend *blk);
+void blk_inc_in_flight(BlockBackend *blk);
+void blk_dec_in_flight(BlockBackend *blk);
+bool blk_is_inserted(BlockBackend *blk);
+bool blk_is_available(BlockBackend *blk);
+int64_t blk_getlength(BlockBackend *blk);
+void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
+void *blk_try_blockalign(BlockBackend *blk, size_t size);
+void *blk_blockalign(BlockBackend *blk, size_t size);
+bool blk_is_writable(BlockBackend *blk);
+BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
+BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
+ int error);
+void blk_error_action(BlockBackend *blk, BlockErrorAction action,
+ bool is_read, int error);
+int blk_get_max_iov(BlockBackend *blk);
+int blk_get_max_hw_iov(BlockBackend *blk);
+
+void blk_invalidate_cache(BlockBackend *blk, Error **errp);
+
+void blk_io_plug(BlockBackend *blk);
+void blk_io_unplug(BlockBackend *blk);
+AioContext *blk_get_aio_context(BlockBackend *blk);
+BlockAcctStats *blk_get_stats(BlockBackend *blk);
+void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
+ BlockCompletionFunc *cb, void *opaque);
+int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
+ int64_t bytes);
+int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
+int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes, BdrvRequestFlags flags);
+int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
+ int64_t bytes, BdrvRequestFlags flags);
+int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
+ PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
+
+uint32_t blk_get_request_alignment(BlockBackend *blk);
+uint32_t blk_get_max_transfer(BlockBackend *blk);
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
+
+int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
+ BlockBackend *blk_out, int64_t off_out,
+ int64_t bytes, BdrvRequestFlags read_flags,
+ BdrvRequestFlags write_flags);
+
+
+int blk_make_empty(BlockBackend *blk, Error **errp);
+
+#endif /* BLOCK_BACKEND_IO_H */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index e5e1524f06..038be9fc40 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -13,272 +13,9 @@
#ifndef BLOCK_BACKEND_H
#define BLOCK_BACKEND_H
-#include "qemu/iov.h"
-#include "block/throttle-groups.h"
+#include "block-backend-global-state.h"
+#include "block-backend-io.h"
-/*
- * TODO Have to include block/block.h for a bunch of block layer
- * types. Unfortunately, this pulls in the whole BlockDriverState
- * API, which we don't want used by many BlockBackend users. Some of
- * the types belong here, and the rest should be split into a common
- * header and one for the BlockDriverState API.
- */
-#include "block/block.h"
-
-/* Callbacks for block device models */
-typedef struct BlockDevOps {
- /*
- * Runs when virtual media changed (monitor commands eject, change)
- * Argument load is true on load and false on eject.
- * Beware: doesn't run when a host device's physical media
- * changes. Sure would be useful if it did.
- * Device models with removable media must implement this callback.
- */
- void (*change_media_cb)(void *opaque, bool load, Error **errp);
- /*
- * Runs when an eject request is issued from the monitor, the tray
- * is closed, and the medium is locked.
- * Device models that do not implement is_medium_locked will not need
- * this callback. Device models that can lock the medium or tray might
- * want to implement the callback and unlock the tray when "force" is
- * true, even if they do not support eject requests.
- */
- void (*eject_request_cb)(void *opaque, bool force);
- /*
- * Is the virtual tray open?
- * Device models implement this only when the device has a tray.
- */
- bool (*is_tray_open)(void *opaque);
- /*
- * Is the virtual medium locked into the device?
- * Device models implement this only when device has such a lock.
- */
- bool (*is_medium_locked)(void *opaque);
- /*
- * Runs when the size changed (e.g. monitor command block_resize)
- */
- void (*resize_cb)(void *opaque);
- /*
- * Runs when the backend receives a drain request.
- */
- void (*drained_begin)(void *opaque);
- /*
- * Runs when the backend's last drain request ends.
- */
- void (*drained_end)(void *opaque);
- /*
- * Is the device still busy?
- */
- bool (*drained_poll)(void *opaque);
-} BlockDevOps;
-
-/* This struct is embedded in (the private) BlockBackend struct and contains
- * fields that must be public. This is in particular for QLIST_ENTRY() and
- * friends so that BlockBackends can be kept in lists outside block-backend.c
- * */
-typedef struct BlockBackendPublic {
- ThrottleGroupMember throttle_group_member;
-} BlockBackendPublic;
-
-BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
-BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
- uint64_t shared_perm, Error **errp);
-BlockBackend *blk_new_open(const char *filename, const char *reference,
- QDict *options, int flags, Error **errp);
-int blk_get_refcnt(BlockBackend *blk);
-void blk_ref(BlockBackend *blk);
-void blk_unref(BlockBackend *blk);
-void blk_remove_all_bs(void);
-const char *blk_name(const BlockBackend *blk);
-BlockBackend *blk_by_name(const char *name);
-BlockBackend *blk_next(BlockBackend *blk);
-BlockBackend *blk_all_next(BlockBackend *blk);
-bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
-void monitor_remove_blk(BlockBackend *blk);
-
-BlockBackendPublic *blk_get_public(BlockBackend *blk);
-BlockBackend *blk_by_public(BlockBackendPublic *public);
-
-BlockDriverState *blk_bs(BlockBackend *blk);
-void blk_remove_bs(BlockBackend *blk);
-int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
-int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
-bool bdrv_has_blk(BlockDriverState *bs);
-bool bdrv_is_root_node(BlockDriverState *bs);
-int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
- Error **errp);
-void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
-
-void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
-void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
-void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
-void blk_iostatus_enable(BlockBackend *blk);
-bool blk_iostatus_is_enabled(const BlockBackend *blk);
-BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
-void blk_iostatus_disable(BlockBackend *blk);
-void blk_iostatus_reset(BlockBackend *blk);
-void blk_iostatus_set_err(BlockBackend *blk, int error);
-int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
-void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
-DeviceState *blk_get_attached_dev(BlockBackend *blk);
-char *blk_get_attached_dev_id(BlockBackend *blk);
-BlockBackend *blk_by_dev(void *dev);
-BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
-void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
-int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
- int64_t bytes,
- QEMUIOVector *qiov, size_t qiov_offset,
- BdrvRequestFlags flags);
-int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
- int64_t bytes, QEMUIOVector *qiov,
- BdrvRequestFlags flags);
-
-static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
- int64_t bytes, void *buf,
- BdrvRequestFlags flags)
-{
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
-
- assert(bytes <= SIZE_MAX);
-
- return blk_co_preadv(blk, offset, bytes, &qiov, flags);
-}
-
-static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
- int64_t bytes, void *buf,
- BdrvRequestFlags flags)
-{
- QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
-
- assert(bytes <= SIZE_MAX);
-
- return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
-}
-
-int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes, BdrvRequestFlags flags);
-BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
-int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes);
-int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
- BdrvRequestFlags flags);
-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_preadv(BlockBackend *blk, int64_t offset,
- QEMUIOVector *qiov, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
- QEMUIOVector *qiov, BdrvRequestFlags flags,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_flush(BlockBackend *blk,
- BlockCompletionFunc *cb, void *opaque);
-BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
- BlockCompletionFunc *cb, void *opaque);
-void blk_aio_cancel(BlockAIOCB *acb);
-void blk_aio_cancel_async(BlockAIOCB *acb);
-int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
-BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
- BlockCompletionFunc *cb, void *opaque);
-int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
- int64_t bytes);
-int coroutine_fn blk_co_flush(BlockBackend *blk);
-int blk_flush(BlockBackend *blk);
-int blk_commit_all(void);
-void blk_inc_in_flight(BlockBackend *blk);
-void blk_dec_in_flight(BlockBackend *blk);
-void blk_drain(BlockBackend *blk);
-void blk_drain_all(void);
-void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
- BlockdevOnError on_write_error);
-BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
-BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
- int error);
-void blk_error_action(BlockBackend *blk, BlockErrorAction action,
- bool is_read, int error);
-bool blk_supports_write_perm(BlockBackend *blk);
-bool blk_is_writable(BlockBackend *blk);
-bool blk_is_sg(BlockBackend *blk);
-bool blk_enable_write_cache(BlockBackend *blk);
-void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
-void blk_invalidate_cache(BlockBackend *blk, Error **errp);
-bool blk_is_inserted(BlockBackend *blk);
-bool blk_is_available(BlockBackend *blk);
-void blk_lock_medium(BlockBackend *blk, bool locked);
-void blk_eject(BlockBackend *blk, bool eject_flag);
-int blk_get_flags(BlockBackend *blk);
-uint32_t blk_get_request_alignment(BlockBackend *blk);
-uint32_t blk_get_max_transfer(BlockBackend *blk);
-uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
-int blk_get_max_iov(BlockBackend *blk);
-int blk_get_max_hw_iov(BlockBackend *blk);
-void blk_set_guest_block_size(BlockBackend *blk, int align);
-void *blk_try_blockalign(BlockBackend *blk, size_t size);
-void *blk_blockalign(BlockBackend *blk, size_t size);
-bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
-void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
-void blk_op_block_all(BlockBackend *blk, Error *reason);
-void blk_op_unblock_all(BlockBackend *blk, Error *reason);
-AioContext *blk_get_aio_context(BlockBackend *blk);
-int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
- Error **errp);
-void blk_add_aio_context_notifier(BlockBackend *blk,
- void (*attached_aio_context)(AioContext *new_context, void *opaque),
- void (*detach_aio_context)(void *opaque), void *opaque);
-void blk_remove_aio_context_notifier(BlockBackend *blk,
- void (*attached_aio_context)(AioContext *,
- void *),
- void (*detach_aio_context)(void *),
- void *opaque);
-void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
-void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
-void blk_io_plug(BlockBackend *blk);
-void blk_io_unplug(BlockBackend *blk);
-BlockAcctStats *blk_get_stats(BlockBackend *blk);
-BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
-void blk_update_root_state(BlockBackend *blk);
-bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
-int blk_get_open_flags_from_root_state(BlockBackend *blk);
-
-void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
- BlockCompletionFunc *cb, void *opaque);
-int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
- int64_t bytes, BdrvRequestFlags flags);
-int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
- int64_t bytes);
-int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
- PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
-int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
-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);
-int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
-int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
-BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
- BlockCompletionFunc *cb,
- void *opaque, int ret);
-
-void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
-void blk_io_limits_disable(BlockBackend *blk);
-void blk_io_limits_enable(BlockBackend *blk, const char *group);
-void blk_io_limits_update_group(BlockBackend *blk, const char *group);
-void blk_set_force_allow_inactivate(BlockBackend *blk);
-
-void blk_register_buf(BlockBackend *blk, void *host, size_t size);
-void blk_unregister_buf(BlockBackend *blk, void *host);
-
-int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
- BlockBackend *blk_out, int64_t off_out,
- int64_t bytes, BdrvRequestFlags read_flags,
- BdrvRequestFlags write_flags);
-
-const BdrvChild *blk_root(BlockBackend *blk);
-
-int blk_make_empty(BlockBackend *blk, Error **errp);
+/* DO NOT ADD ANYTHING IN HERE. USE ONE OF THE HEADERS INCLUDED ABOVE */
#endif
--
2.27.0
On 25.10.21 12:17, Emanuele Giuseppe Esposito wrote:
> Similarly to the previous patches, split block-backend.h
> in block-backend-io.h and block-backend-global-state.h
>
> In addition, remove "block/block.h" include as it seems
> it is not necessary anymore, together with "qemu/iov.h"
>
> block-backend-common.h contains the structures shared between
> the two headers, and the functions that can't be categorized as
> I/O or global state.
>
> Assertions are added in the next patch.
>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> block/block-backend.c | 9 +-
> include/sysemu/block-backend-common.h | 74 ++++++
> include/sysemu/block-backend-global-state.h | 122 +++++++++
> include/sysemu/block-backend-io.h | 139 ++++++++++
> include/sysemu/block-backend.h | 269 +-------------------
> 5 files changed, 344 insertions(+), 269 deletions(-)
> create mode 100644 include/sysemu/block-backend-common.h
> create mode 100644 include/sysemu/block-backend-global-state.h
> create mode 100644 include/sysemu/block-backend-io.h
>
> diff --git a/block/block-backend.c b/block/block-backend.c
> index 39cd99df2b..0afc03fd66 100644
> --- a/block/block-backend.c
> +++ b/block/block-backend.c
> @@ -79,6 +79,7 @@ struct BlockBackend {
> bool allow_aio_context_change;
> bool allow_write_beyond_eof;
>
> + /* Protected by BQL lock */
> NotifierList remove_bs_notifiers, insert_bs_notifiers;
> QLIST_HEAD(, BlockBackendAioNotifier) aio_notifiers;
>
> @@ -111,12 +112,14 @@ static const AIOCBInfo block_backend_aiocb_info = {
> static void drive_info_del(DriveInfo *dinfo);
> static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
>
> -/* All BlockBackends */
> +/* All BlockBackends. Protected by BQL lock. */
> static QTAILQ_HEAD(, BlockBackend) block_backends =
> QTAILQ_HEAD_INITIALIZER(block_backends);
>
> -/* All BlockBackends referenced by the monitor and which are iterated through by
> - * blk_next() */
> +/*
> + * All BlockBackends referenced by the monitor and which are iterated through by
> + * blk_next(). Protected by BQL lock.
> + */
> static QTAILQ_HEAD(, BlockBackend) monitor_block_backends =
> QTAILQ_HEAD_INITIALIZER(monitor_block_backends);
>
> diff --git a/include/sysemu/block-backend-common.h b/include/sysemu/block-backend-common.h
> new file mode 100644
> index 0000000000..52ff6a4d26
> --- /dev/null
> +++ b/include/sysemu/block-backend-common.h
> @@ -0,0 +1,74 @@
> +/*
> + * QEMU Block backends
> + *
> + * Copyright (C) 2014-2016 Red Hat, Inc.
> + *
> + * Authors:
> + * Markus Armbruster <armbru@redhat.com>,
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1
> + * or later. See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#ifndef BLOCK_BACKEND_COMMON_H
> +#define BLOCK_BACKEND_COMMON_H
> +
> +#include "block/throttle-groups.h"
> +
> +/* Callbacks for block device models */
> +typedef struct BlockDevOps {
> + /*
> + * Runs when virtual media changed (monitor commands eject, change)
> + * Argument load is true on load and false on eject.
> + * Beware: doesn't run when a host device's physical media
> + * changes. Sure would be useful if it did.
> + * Device models with removable media must implement this callback.
> + */
> + void (*change_media_cb)(void *opaque, bool load, Error **errp);
> + /*
> + * Runs when an eject request is issued from the monitor, the tray
> + * is closed, and the medium is locked.
> + * Device models that do not implement is_medium_locked will not need
> + * this callback. Device models that can lock the medium or tray might
> + * want to implement the callback and unlock the tray when "force" is
> + * true, even if they do not support eject requests.
> + */
> + void (*eject_request_cb)(void *opaque, bool force);
> + /*
> + * Is the virtual tray open?
> + * Device models implement this only when the device has a tray.
> + */
> + bool (*is_tray_open)(void *opaque);
> + /*
> + * Is the virtual medium locked into the device?
> + * Device models implement this only when device has such a lock.
> + */
> + bool (*is_medium_locked)(void *opaque);
> + /*
> + * Runs when the size changed (e.g. monitor command block_resize)
> + */
> + void (*resize_cb)(void *opaque);
> + /*
> + * Runs when the backend receives a drain request.
> + */
> + void (*drained_begin)(void *opaque);
> + /*
> + * Runs when the backend's last drain request ends.
> + */
> + void (*drained_end)(void *opaque);
> + /*
> + * Is the device still busy?
> + */
> + bool (*drained_poll)(void *opaque);
> +} BlockDevOps;
> +
> +/*
> + * This struct is embedded in (the private) BlockBackend struct and contains
> + * fields that must be public. This is in particular for QLIST_ENTRY() and
> + * friends so that BlockBackends can be kept in lists outside block-backend.c
> + */
> +typedef struct BlockBackendPublic {
> + ThrottleGroupMember throttle_group_member;
> +} BlockBackendPublic;
> +
> +#endif /* BLOCK_BACKEND_COMMON_H */
> diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
> new file mode 100644
> index 0000000000..4001b1c02a
> --- /dev/null
> +++ b/include/sysemu/block-backend-global-state.h
> @@ -0,0 +1,122 @@
> +/*
> + * QEMU Block backends
> + *
> + * Copyright (C) 2014-2016 Red Hat, Inc.
> + *
> + * Authors:
> + * Markus Armbruster <armbru@redhat.com>,
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1
> + * or later. See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#ifndef BLOCK_BACKEND_GS_H
> +#define BLOCK_BACKEND_GS_H
> +
> +#include "block-backend-common.h"
> +
> +/*
> + * Global state (GS) API. These functions run under the BQL lock.
> + *
> + * See include/block/block-global-state.h for more information about
> + * the GS API.
> + */
> +
> +BlockBackend *blk_new(AioContext *ctx, uint64_t perm, uint64_t shared_perm);
> +BlockBackend *blk_new_with_bs(BlockDriverState *bs, uint64_t perm,
> + uint64_t shared_perm, Error **errp);
> +BlockBackend *blk_new_open(const char *filename, const char *reference,
> + QDict *options, int flags, Error **errp);
> +int blk_get_refcnt(BlockBackend *blk);
> +void blk_ref(BlockBackend *blk);
> +void blk_unref(BlockBackend *blk);
> +void blk_remove_all_bs(void);
> +const char *blk_name(const BlockBackend *blk);
This is called by send_qmp_error_event(), which in turn is called by
blk_error_action(). Are those strictly main loop functions?
> +BlockBackend *blk_by_name(const char *name);
> +BlockBackend *blk_next(BlockBackend *blk);
> +BlockBackend *blk_all_next(BlockBackend *blk);
> +bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
> +void monitor_remove_blk(BlockBackend *blk);
> +
> +BlockBackendPublic *blk_get_public(BlockBackend *blk);
> +BlockBackend *blk_by_public(BlockBackendPublic *public);
> +
> +void blk_remove_bs(BlockBackend *blk);
> +int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
> +bool bdrv_has_blk(BlockDriverState *bs);
> +bool bdrv_is_root_node(BlockDriverState *bs);
> +int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
> + Error **errp);
> +void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
These functions are called from fuse_do_truncate(), which I believe runs
in the context of the export’s BlockBackend. I’m not saying that’s
necessarily correct, but as of the next patch, this happens:
$ touch /tmp/fuse-export
$ storage-daemon/qemu-storage-daemon \
--object iothread,id=iothr0 \
--blockdev file,node-name=node0,filename=/tmp/fuse-export \
--export
fuse,id=exp0,node-name=node0,mountpoint=/tmp/fuse-export,iothread=iothr0,writable=true
\
&
[1] 27395
$ truncate /tmp/fuse-export -s 1M
qemu-storage-daemon: ../block/block-backend.c:935: blk_get_perm:
Assertion `qemu_in_main_thread()' failed.
truncate: failed to truncate '/tmp/fuse-export' at 1048576 bytes:
Software caused connection abort
truncate: failed to close '/tmp/fuse-export': Transport endpoint is not
connected
[1] + 27395 IOT instruction (core dumped)
storage-daemon/qemu-storage-daemon --object iothread,id=iothr0 --blockdev
> +
> +void blk_iostatus_enable(BlockBackend *blk);
> +bool blk_iostatus_is_enabled(const BlockBackend *blk);
> +BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
> +void blk_iostatus_disable(BlockBackend *blk);
> +void blk_iostatus_reset(BlockBackend *blk);
> +void blk_iostatus_set_err(BlockBackend *blk, int error);
> +int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
> +void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
> +DeviceState *blk_get_attached_dev(BlockBackend *blk);
> +char *blk_get_attached_dev_id(BlockBackend *blk);
> +BlockBackend *blk_by_dev(void *dev);
> +BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
> +void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
> +
> +int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
> +int64_t blk_nb_sectors(BlockBackend *blk);
I’d have considered this an I/O function, and blk_getlength() is
classified as such. Why not this?
> +int blk_commit_all(void);
> +void blk_drain(BlockBackend *blk);
I’m again wondering a bit why this is a GS function, when
bdrv_drained_begin() is an I/O function. However, less than in the case
of bdrv_drain(), given that there is no blk_drained_begin() that’s
classified as I/O.
> +void blk_drain_all(void);
> +void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
> + BlockdevOnError on_write_error);
> +bool blk_supports_write_perm(BlockBackend *blk);
> +bool blk_is_sg(BlockBackend *blk);
> +bool blk_enable_write_cache(BlockBackend *blk);
> +void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
> +void blk_lock_medium(BlockBackend *blk, bool locked);
> +void blk_eject(BlockBackend *blk, bool eject_flag);
> +int blk_get_flags(BlockBackend *blk);
> +void blk_set_guest_block_size(BlockBackend *blk, int align);
> +bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
> +void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
> +void blk_op_block_all(BlockBackend *blk, Error *reason);
> +void blk_op_unblock_all(BlockBackend *blk, Error *reason);
> +int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
> + Error **errp);
> +void blk_add_aio_context_notifier(BlockBackend *blk,
> + void (*attached_aio_context)(AioContext *new_context, void *opaque),
> + void (*detach_aio_context)(void *opaque), void *opaque);
> +void blk_remove_aio_context_notifier(BlockBackend *blk,
> + void (*attached_aio_context)(AioContext *,
> + void *),
> + void (*detach_aio_context)(void *),
> + void *opaque);
> +void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
> +void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
> +BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
> +void blk_update_root_state(BlockBackend *blk);
> +bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
> +int blk_get_open_flags_from_root_state(BlockBackend *blk);
> +
> +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);
> +int blk_probe_blocksizes(BlockBackend *blk, BlockSizes *bsz);
> +int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
> +BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
> + BlockCompletionFunc *cb,
> + void *opaque, int ret);
This sounds more like an I/O function to me.
> +
> +void blk_set_io_limits(BlockBackend *blk, ThrottleConfig *cfg);
> +void blk_io_limits_disable(BlockBackend *blk);
> +void blk_io_limits_enable(BlockBackend *blk, const char *group);
> +void blk_io_limits_update_group(BlockBackend *blk, const char *group);
> +void blk_set_force_allow_inactivate(BlockBackend *blk);
> +
> +void blk_register_buf(BlockBackend *blk, void *host, size_t size);
> +void blk_unregister_buf(BlockBackend *blk, void *host);
> +
> +const BdrvChild *blk_root(BlockBackend *blk);
> +
> +#endif /* BLOCK_BACKEND_GS_H */
> diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
> new file mode 100644
> index 0000000000..ab0463cb69
> --- /dev/null
> +++ b/include/sysemu/block-backend-io.h
> @@ -0,0 +1,139 @@
> +/*
> + * QEMU Block backends
> + *
> + * Copyright (C) 2014-2016 Red Hat, Inc.
> + *
> + * Authors:
> + * Markus Armbruster <armbru@redhat.com>,
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2.1
> + * or later. See the COPYING.LIB file in the top-level directory.
> + */
> +
> +#ifndef BLOCK_BACKEND_IO_H
> +#define BLOCK_BACKEND_IO_H
> +
> +#include "block-backend-common.h"
> +
> +/*
> + * I/O API functions. These functions are thread-safe.
> + *
> + * See include/block/block-io.h for more information about
> + * the I/O API.
> + */
> +
> +BlockDriverState *blk_bs(BlockBackend *blk);
> +
> +int blk_replace_bs(BlockBackend *blk, BlockDriverState *new_bs, Error **errp);
This sounds like a GS function to me.
> +
> +void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
> +void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
> +void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
> +
> +int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int bytes);
> +int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int bytes,
> + BdrvRequestFlags flags);
> +int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
> + int64_t bytes, QEMUIOVector *qiov,
> + BdrvRequestFlags flags);
> +int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset,
> + int64_t bytes,
> + QEMUIOVector *qiov, size_t qiov_offset,
> + BdrvRequestFlags flags);
> +int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
> + int64_t bytes, QEMUIOVector *qiov,
> + BdrvRequestFlags flags);
> +
> +static inline int coroutine_fn blk_co_pread(BlockBackend *blk, int64_t offset,
> + int64_t bytes, void *buf,
> + BdrvRequestFlags flags)
> +{
> + QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
> +
> + assert(bytes <= SIZE_MAX);
> +
> + return blk_co_preadv(blk, offset, bytes, &qiov, flags);
> +}
> +
> +static inline int coroutine_fn blk_co_pwrite(BlockBackend *blk, int64_t offset,
> + int64_t bytes, void *buf,
> + BdrvRequestFlags flags)
> +{
> + QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
> +
> + assert(bytes <= SIZE_MAX);
> +
> + return blk_co_pwritev(blk, offset, bytes, &qiov, flags);
> +}
> +
> +BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
> + int64_t bytes, BdrvRequestFlags flags,
> + BlockCompletionFunc *cb, void *opaque);
> +
> +BlockAIOCB *blk_aio_preadv(BlockBackend *blk, int64_t offset,
> + QEMUIOVector *qiov, BdrvRequestFlags flags,
> + BlockCompletionFunc *cb, void *opaque);
> +BlockAIOCB *blk_aio_pwritev(BlockBackend *blk, int64_t offset,
> + QEMUIOVector *qiov, BdrvRequestFlags flags,
> + BlockCompletionFunc *cb, void *opaque);
> +BlockAIOCB *blk_aio_flush(BlockBackend *blk,
> + BlockCompletionFunc *cb, void *opaque);
> +BlockAIOCB *blk_aio_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes,
> + BlockCompletionFunc *cb, void *opaque);
> +void blk_aio_cancel(BlockAIOCB *acb);
> +void blk_aio_cancel_async(BlockAIOCB *acb);
> +int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
> +BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
> + BlockCompletionFunc *cb, void *opaque);
> +int coroutine_fn blk_co_pdiscard(BlockBackend *blk, int64_t offset,
> + int64_t bytes);
> +int coroutine_fn blk_co_flush(BlockBackend *blk);
> +int blk_flush(BlockBackend *blk);
> +void blk_inc_in_flight(BlockBackend *blk);
> +void blk_dec_in_flight(BlockBackend *blk);
> +bool blk_is_inserted(BlockBackend *blk);
> +bool blk_is_available(BlockBackend *blk);
> +int64_t blk_getlength(BlockBackend *blk);
> +void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr);
> +void *blk_try_blockalign(BlockBackend *blk, size_t size);
> +void *blk_blockalign(BlockBackend *blk, size_t size);
> +bool blk_is_writable(BlockBackend *blk);
> +BlockdevOnError blk_get_on_error(BlockBackend *blk, bool is_read);
> +BlockErrorAction blk_get_error_action(BlockBackend *blk, bool is_read,
> + int error);
> +void blk_error_action(BlockBackend *blk, BlockErrorAction action,
> + bool is_read, int error);
> +int blk_get_max_iov(BlockBackend *blk);
> +int blk_get_max_hw_iov(BlockBackend *blk);
> +
> +void blk_invalidate_cache(BlockBackend *blk, Error **errp);
> +
> +void blk_io_plug(BlockBackend *blk);
> +void blk_io_unplug(BlockBackend *blk);
> +AioContext *blk_get_aio_context(BlockBackend *blk);
> +BlockAcctStats *blk_get_stats(BlockBackend *blk);
> +void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
> + BlockCompletionFunc *cb, void *opaque);
> +int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
> + int64_t bytes);
> +int blk_pdiscard(BlockBackend *blk, int64_t offset, int64_t bytes);
> +int blk_pwrite_zeroes(BlockBackend *blk, int64_t offset,
> + int64_t bytes, BdrvRequestFlags flags);
> +int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
> + int64_t bytes, BdrvRequestFlags flags);
> +int blk_truncate(BlockBackend *blk, int64_t offset, bool exact,
> + PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
> +
> +uint32_t blk_get_request_alignment(BlockBackend *blk);
> +uint32_t blk_get_max_transfer(BlockBackend *blk);
> +uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
> +
> +int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
> + BlockBackend *blk_out, int64_t off_out,
> + int64_t bytes, BdrvRequestFlags read_flags,
> + BdrvRequestFlags write_flags);
> +
> +
> +int blk_make_empty(BlockBackend *blk, Error **errp);
bdrv_make_empty() (called by this function) is classified as a GS
Function, and asserts that it’s running in the main thread. I can also
see that the next patch adds the same assertion to blk_make_empty(), so
I believe this should be a GS function, too.
Hanna
>> +int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
>> +int64_t blk_nb_sectors(BlockBackend *blk);
>
> I’d have considered this an I/O function, and blk_getlength() is
> classified as such. Why not this?
This one by itself is only invoked under BQL. I believe in facts that in
migration/block.c is always wrapped by qemu_mutex_{lock/unlock}_iothread()
pairs.
But on the other side, as you said, semantically maybe it makes more
sense to put it as I/O. Also its bdrv_ counterpart, bdrv_nb_sectors, is
an I/O so you are right.
>> +int blk_probe_geometry(BlockBackend *blk, HDGeometry *geo);
>> +BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
>> + BlockCompletionFunc *cb,
>> + void *opaque, int ret);
>
> This sounds more like an I/O function to me.
>
Semantically might make sense as an I/O. Functionally I don't see any
iothread using it.
I agree with the rest of the comments.
Thank you,
Emanuele
On 25.10.21 12:17, Emanuele Giuseppe Esposito wrote: > Similarly to the previous patches, split block-backend.h > in block-backend-io.h and block-backend-global-state.h > > In addition, remove "block/block.h" include as it seems > it is not necessary anymore, together with "qemu/iov.h" > > block-backend-common.h contains the structures shared between > the two headers, and the functions that can't be categorized as > I/O or global state. > > Assertions are added in the next patch. > > Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> > Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> > --- > block/block-backend.c | 9 +- > include/sysemu/block-backend-common.h | 74 ++++++ > include/sysemu/block-backend-global-state.h | 122 +++++++++ > include/sysemu/block-backend-io.h | 139 ++++++++++ > include/sysemu/block-backend.h | 269 +------------------- > 5 files changed, 344 insertions(+), 269 deletions(-) > create mode 100644 include/sysemu/block-backend-common.h > create mode 100644 include/sysemu/block-backend-global-state.h > create mode 100644 include/sysemu/block-backend-io.h [...] > diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h > index e5e1524f06..038be9fc40 100644 > --- a/include/sysemu/block-backend.h > +++ b/include/sysemu/block-backend.h > @@ -13,272 +13,9 @@ > #ifndef BLOCK_BACKEND_H > #define BLOCK_BACKEND_H > > -#include "qemu/iov.h" > -#include "block/throttle-groups.h" > +#include "block-backend-global-state.h" > +#include "block-backend-io.h" > > -/* > - * TODO Have to include block/block.h for a bunch of block layer > - * types. Unfortunately, this pulls in the whole BlockDriverState > - * API, which we don't want used by many BlockBackend users. Some of > - * the types belong here, and the rest should be split into a common > - * header and one for the BlockDriverState API. > - */ > -#include "block/block.h" This note and the include is gone. Sounds like something positive, but why is this possible? Hanna
On 12/11/2021 13:30, Hanna Reitz wrote: > On 25.10.21 12:17, Emanuele Giuseppe Esposito wrote: >> Similarly to the previous patches, split block-backend.h >> in block-backend-io.h and block-backend-global-state.h >> >> In addition, remove "block/block.h" include as it seems >> it is not necessary anymore, together with "qemu/iov.h" >> >> block-backend-common.h contains the structures shared between >> the two headers, and the functions that can't be categorized as >> I/O or global state. >> >> Assertions are added in the next patch. >> >> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> >> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> >> --- >> block/block-backend.c | 9 +- >> include/sysemu/block-backend-common.h | 74 ++++++ >> include/sysemu/block-backend-global-state.h | 122 +++++++++ >> include/sysemu/block-backend-io.h | 139 ++++++++++ >> include/sysemu/block-backend.h | 269 +------------------- >> 5 files changed, 344 insertions(+), 269 deletions(-) >> create mode 100644 include/sysemu/block-backend-common.h >> create mode 100644 include/sysemu/block-backend-global-state.h >> create mode 100644 include/sysemu/block-backend-io.h > > [...] > >> diff --git a/include/sysemu/block-backend.h >> b/include/sysemu/block-backend.h >> index e5e1524f06..038be9fc40 100644 >> --- a/include/sysemu/block-backend.h >> +++ b/include/sysemu/block-backend.h >> @@ -13,272 +13,9 @@ >> #ifndef BLOCK_BACKEND_H >> #define BLOCK_BACKEND_H >> -#include "qemu/iov.h" >> -#include "block/throttle-groups.h" >> +#include "block-backend-global-state.h" >> +#include "block-backend-io.h" >> -/* >> - * TODO Have to include block/block.h for a bunch of block layer >> - * types. Unfortunately, this pulls in the whole BlockDriverState >> - * API, which we don't want used by many BlockBackend users. Some of >> - * the types belong here, and the rest should be split into a common >> - * header and one for the BlockDriverState API. >> - */ >> -#include "block/block.h" > > This note and the include is gone. Sounds like something positive, but > why is this possible? > Basically block/throttle-groups.h includes block/block_int.h that internally includes block/block.h. But I am not sure if you actually want to keep this comment as reminder for future work. Should I keep it? Thank you, Emanuele
On 16.11.21 15:24, Emanuele Giuseppe Esposito wrote: > > > On 12/11/2021 13:30, Hanna Reitz wrote: >> On 25.10.21 12:17, Emanuele Giuseppe Esposito wrote: >>> Similarly to the previous patches, split block-backend.h >>> in block-backend-io.h and block-backend-global-state.h >>> >>> In addition, remove "block/block.h" include as it seems >>> it is not necessary anymore, together with "qemu/iov.h" >>> >>> block-backend-common.h contains the structures shared between >>> the two headers, and the functions that can't be categorized as >>> I/O or global state. >>> >>> Assertions are added in the next patch. >>> >>> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> >>> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> >>> --- >>> block/block-backend.c | 9 +- >>> include/sysemu/block-backend-common.h | 74 ++++++ >>> include/sysemu/block-backend-global-state.h | 122 +++++++++ >>> include/sysemu/block-backend-io.h | 139 ++++++++++ >>> include/sysemu/block-backend.h | 269 >>> +------------------- >>> 5 files changed, 344 insertions(+), 269 deletions(-) >>> create mode 100644 include/sysemu/block-backend-common.h >>> create mode 100644 include/sysemu/block-backend-global-state.h >>> create mode 100644 include/sysemu/block-backend-io.h >> >> [...] >> >>> diff --git a/include/sysemu/block-backend.h >>> b/include/sysemu/block-backend.h >>> index e5e1524f06..038be9fc40 100644 >>> --- a/include/sysemu/block-backend.h >>> +++ b/include/sysemu/block-backend.h >>> @@ -13,272 +13,9 @@ >>> #ifndef BLOCK_BACKEND_H >>> #define BLOCK_BACKEND_H >>> -#include "qemu/iov.h" >>> -#include "block/throttle-groups.h" >>> +#include "block-backend-global-state.h" >>> +#include "block-backend-io.h" >>> -/* >>> - * TODO Have to include block/block.h for a bunch of block layer >>> - * types. Unfortunately, this pulls in the whole BlockDriverState >>> - * API, which we don't want used by many BlockBackend users. Some of >>> - * the types belong here, and the rest should be split into a common >>> - * header and one for the BlockDriverState API. >>> - */ >>> -#include "block/block.h" >> >> This note and the include is gone. Sounds like something positive, >> but why is this possible? >> > > Basically block/throttle-groups.h includes block/block_int.h that > internally includes block/block.h. > > But I am not sure if you actually want to keep this comment as > reminder for future work. Should I keep it? Good question. I think I’d keep it and the block.h include; I mean, the throttle-groups.h include was there before already, so perhaps this was indeed only intended as a reminder. The other reason to keep it is that ideal this is just a refactoring patch, so I wouldn’t touch anything that needn’t be touched. Hanna
© 2016 - 2026 Red Hat, Inc.