mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'v7.2.0' into sync/qemu-7.2.0
v7.2.0 release
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "qemu/timed-average.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "qapi/qapi-builtin-types.h"
|
||||
#include "qapi/qapi-types-common.h"
|
||||
|
||||
typedef struct BlockAcctTimedStats BlockAcctTimedStats;
|
||||
typedef struct BlockAcctStats BlockAcctStats;
|
||||
@@ -100,8 +100,8 @@ typedef struct BlockAcctCookie {
|
||||
} BlockAcctCookie;
|
||||
|
||||
void block_acct_init(BlockAcctStats *stats);
|
||||
void block_acct_setup(BlockAcctStats *stats, bool account_invalid,
|
||||
bool account_failed);
|
||||
void block_acct_setup(BlockAcctStats *stats, enum OnOffAuto account_invalid,
|
||||
enum OnOffAuto account_failed);
|
||||
void block_acct_cleanup(BlockAcctStats *stats);
|
||||
void block_acct_add_interval(BlockAcctStats *stats, unsigned interval_length);
|
||||
BlockAcctTimedStats *block_acct_interval_next(BlockAcctStats *stats,
|
||||
|
||||
@@ -59,10 +59,13 @@ typedef struct {
|
||||
extern AioWait global_aio_wait;
|
||||
|
||||
/**
|
||||
* AIO_WAIT_WHILE:
|
||||
* AIO_WAIT_WHILE_INTERNAL:
|
||||
* @ctx: the aio context, or NULL if multiple aio contexts (for which the
|
||||
* caller does not hold a lock) are involved in the polling condition.
|
||||
* @cond: wait while this conditional expression is true
|
||||
* @unlock: whether to unlock and then lock again @ctx. This apples
|
||||
* only when waiting for another AioContext from the main loop.
|
||||
* Otherwise it's ignored.
|
||||
*
|
||||
* Wait while a condition is true. Use this to implement synchronous
|
||||
* operations that require event loop activity.
|
||||
@@ -75,12 +78,14 @@ extern AioWait global_aio_wait;
|
||||
* wait on conditions between two IOThreads since that could lead to deadlock,
|
||||
* go via the main loop instead.
|
||||
*/
|
||||
#define AIO_WAIT_WHILE(ctx, cond) ({ \
|
||||
#define AIO_WAIT_WHILE_INTERNAL(ctx, cond, unlock) ({ \
|
||||
bool waited_ = false; \
|
||||
AioWait *wait_ = &global_aio_wait; \
|
||||
AioContext *ctx_ = (ctx); \
|
||||
/* Increment wait_->num_waiters before evaluating cond. */ \
|
||||
qatomic_inc(&wait_->num_waiters); \
|
||||
/* Paired with smp_mb in aio_wait_kick(). */ \
|
||||
smp_mb(); \
|
||||
if (ctx_ && in_aio_context_home_thread(ctx_)) { \
|
||||
while ((cond)) { \
|
||||
aio_poll(ctx_, true); \
|
||||
@@ -90,11 +95,11 @@ extern AioWait global_aio_wait;
|
||||
assert(qemu_get_current_aio_context() == \
|
||||
qemu_get_aio_context()); \
|
||||
while ((cond)) { \
|
||||
if (ctx_) { \
|
||||
if (unlock && ctx_) { \
|
||||
aio_context_release(ctx_); \
|
||||
} \
|
||||
aio_poll(qemu_get_aio_context(), true); \
|
||||
if (ctx_) { \
|
||||
if (unlock && ctx_) { \
|
||||
aio_context_acquire(ctx_); \
|
||||
} \
|
||||
waited_ = true; \
|
||||
@@ -103,6 +108,12 @@ extern AioWait global_aio_wait;
|
||||
qatomic_dec(&wait_->num_waiters); \
|
||||
waited_; })
|
||||
|
||||
#define AIO_WAIT_WHILE(ctx, cond) \
|
||||
AIO_WAIT_WHILE_INTERNAL(ctx, cond, true)
|
||||
|
||||
#define AIO_WAIT_WHILE_UNLOCKED(ctx, cond) \
|
||||
AIO_WAIT_WHILE_INTERNAL(ctx, cond, false)
|
||||
|
||||
/**
|
||||
* aio_wait_kick:
|
||||
* Wake up the main thread if it is waiting on AIO_WAIT_WHILE(). During
|
||||
|
||||
+13
-1
@@ -192,6 +192,8 @@ struct AioContext {
|
||||
QSLIST_HEAD(, Coroutine) scheduled_coroutines;
|
||||
QEMUBH *co_schedule_bh;
|
||||
|
||||
int thread_pool_min;
|
||||
int thread_pool_max;
|
||||
/* Thread pool for performing work and receiving completion callbacks.
|
||||
* Has its own locking.
|
||||
*/
|
||||
@@ -469,6 +471,7 @@ void aio_set_fd_handler(AioContext *ctx,
|
||||
IOHandler *io_read,
|
||||
IOHandler *io_write,
|
||||
AioPollFn *io_poll,
|
||||
IOHandler *io_poll_ready,
|
||||
void *opaque);
|
||||
|
||||
/* Set polling begin/end callbacks for a file descriptor that has already been
|
||||
@@ -490,7 +493,8 @@ void aio_set_event_notifier(AioContext *ctx,
|
||||
EventNotifier *notifier,
|
||||
bool is_external,
|
||||
EventNotifierHandler *io_read,
|
||||
AioPollFn *io_poll);
|
||||
AioPollFn *io_poll,
|
||||
EventNotifierHandler *io_poll_ready);
|
||||
|
||||
/* Set polling begin/end callbacks for an event notifier that has already been
|
||||
* registered with aio_set_event_notifier. Do nothing if the event notifier is
|
||||
@@ -767,4 +771,12 @@ void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
|
||||
void aio_context_set_aio_params(AioContext *ctx, int64_t max_batch,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* aio_context_set_thread_pool_params:
|
||||
* @ctx: the aio context
|
||||
* @min: min number of threads to have readily available in the thread pool
|
||||
* @min: max number of threads the thread pool can contain
|
||||
*/
|
||||
void aio_context_set_thread_pool_params(AioContext *ctx, int64_t min,
|
||||
int64_t max, Error **errp);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* QEMU System Emulator block driver
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef BLOCK_COMMON_H
|
||||
#define BLOCK_COMMON_H
|
||||
|
||||
#include "block/aio.h"
|
||||
#include "block/aio-wait.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/coroutine.h"
|
||||
#include "block/accounting.h"
|
||||
#include "block/dirty-bitmap.h"
|
||||
#include "block/blockjob.h"
|
||||
#include "qemu/hbitmap.h"
|
||||
#include "qemu/transactions.h"
|
||||
|
||||
/*
|
||||
* generated_co_wrapper
|
||||
*
|
||||
* Function specifier, which does nothing but mark functions to be
|
||||
* generated by scripts/block-coroutine-wrapper.py
|
||||
*
|
||||
* Read more in docs/devel/block-coroutine-wrapper.rst
|
||||
*/
|
||||
#define generated_co_wrapper
|
||||
|
||||
/* block.c */
|
||||
typedef struct BlockDriver BlockDriver;
|
||||
typedef struct BdrvChild BdrvChild;
|
||||
typedef struct BdrvChildClass BdrvChildClass;
|
||||
|
||||
typedef struct BlockDriverInfo {
|
||||
/* in bytes, 0 if irrelevant */
|
||||
int cluster_size;
|
||||
/* offset at which the VM state can be saved (0 if not possible) */
|
||||
int64_t vm_state_offset;
|
||||
bool is_dirty;
|
||||
/*
|
||||
* True if this block driver only supports compressed writes
|
||||
*/
|
||||
bool needs_compressed_writes;
|
||||
} BlockDriverInfo;
|
||||
|
||||
typedef struct BlockFragInfo {
|
||||
uint64_t allocated_clusters;
|
||||
uint64_t total_clusters;
|
||||
uint64_t fragmented_clusters;
|
||||
uint64_t compressed_clusters;
|
||||
} BlockFragInfo;
|
||||
|
||||
typedef enum {
|
||||
BDRV_REQ_COPY_ON_READ = 0x1,
|
||||
BDRV_REQ_ZERO_WRITE = 0x2,
|
||||
|
||||
/*
|
||||
* The BDRV_REQ_MAY_UNMAP flag is used in write_zeroes requests to indicate
|
||||
* that the block driver should unmap (discard) blocks if it is guaranteed
|
||||
* that the result will read back as zeroes. The flag is only passed to the
|
||||
* driver if the block device is opened with BDRV_O_UNMAP.
|
||||
*/
|
||||
BDRV_REQ_MAY_UNMAP = 0x4,
|
||||
|
||||
/*
|
||||
* An optimization hint when all QEMUIOVector elements are within
|
||||
* previously registered bdrv_register_buf() memory ranges.
|
||||
*
|
||||
* Code that replaces the user's QEMUIOVector elements with bounce buffers
|
||||
* must take care to clear this flag.
|
||||
*/
|
||||
BDRV_REQ_REGISTERED_BUF = 0x8,
|
||||
|
||||
BDRV_REQ_FUA = 0x10,
|
||||
BDRV_REQ_WRITE_COMPRESSED = 0x20,
|
||||
|
||||
/*
|
||||
* Signifies that this write request will not change the visible disk
|
||||
* content.
|
||||
*/
|
||||
BDRV_REQ_WRITE_UNCHANGED = 0x40,
|
||||
|
||||
/*
|
||||
* Forces request serialisation. Use only with write requests.
|
||||
*/
|
||||
BDRV_REQ_SERIALISING = 0x80,
|
||||
|
||||
/*
|
||||
* Execute the request only if the operation can be offloaded or otherwise
|
||||
* be executed efficiently, but return an error instead of using a slow
|
||||
* fallback.
|
||||
*/
|
||||
BDRV_REQ_NO_FALLBACK = 0x100,
|
||||
|
||||
/*
|
||||
* BDRV_REQ_PREFETCH makes sense only in the context of copy-on-read
|
||||
* (i.e., together with the BDRV_REQ_COPY_ON_READ flag or when a COR
|
||||
* filter is involved), in which case it signals that the COR operation
|
||||
* need not read the data into memory (qiov) but only ensure they are
|
||||
* copied to the top layer (i.e., that COR operation is done).
|
||||
*/
|
||||
BDRV_REQ_PREFETCH = 0x200,
|
||||
|
||||
/*
|
||||
* If we need to wait for other requests, just fail immediately. Used
|
||||
* only together with BDRV_REQ_SERIALISING. Used only with requests aligned
|
||||
* to request_alignment (corresponding assertions are in block/io.c).
|
||||
*/
|
||||
BDRV_REQ_NO_WAIT = 0x400,
|
||||
|
||||
/* Mask of valid flags */
|
||||
BDRV_REQ_MASK = 0x7ff,
|
||||
} BdrvRequestFlags;
|
||||
|
||||
#define BDRV_O_NO_SHARE 0x0001 /* don't share permissions */
|
||||
#define BDRV_O_RDWR 0x0002
|
||||
#define BDRV_O_RESIZE 0x0004 /* request permission for resizing the node */
|
||||
#define BDRV_O_SNAPSHOT 0x0008 /* open the file read only and save
|
||||
writes in a snapshot */
|
||||
#define BDRV_O_TEMPORARY 0x0010 /* delete the file after use */
|
||||
#define BDRV_O_NOCACHE 0x0020 /* do not use the host page cache */
|
||||
#define BDRV_O_NATIVE_AIO 0x0080 /* use native AIO instead of the
|
||||
thread pool */
|
||||
#define BDRV_O_NO_BACKING 0x0100 /* don't open the backing file */
|
||||
#define BDRV_O_NO_FLUSH 0x0200 /* disable flushing on this disk */
|
||||
#define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
|
||||
#define BDRV_O_INACTIVE 0x0800 /* consistency hint for migration handoff */
|
||||
#define BDRV_O_CHECK 0x1000 /* open solely for consistency check */
|
||||
#define BDRV_O_ALLOW_RDWR 0x2000 /* allow reopen to change from r/o to r/w */
|
||||
#define BDRV_O_UNMAP 0x4000 /* execute guest UNMAP/TRIM operations */
|
||||
#define BDRV_O_PROTOCOL 0x8000 /* if no block driver is explicitly given:
|
||||
select an appropriate protocol driver,
|
||||
ignoring the format layer */
|
||||
#define BDRV_O_NO_IO 0x10000 /* don't initialize for I/O */
|
||||
#define BDRV_O_AUTO_RDONLY 0x20000 /* degrade to read-only if opening
|
||||
read-write fails */
|
||||
#define BDRV_O_IO_URING 0x40000 /* use io_uring instead of the thread pool */
|
||||
|
||||
#define BDRV_O_CACHE_MASK (BDRV_O_NOCACHE | BDRV_O_NO_FLUSH)
|
||||
|
||||
|
||||
/* Option names of options parsed by the block layer */
|
||||
|
||||
#define BDRV_OPT_CACHE_WB "cache.writeback"
|
||||
#define BDRV_OPT_CACHE_DIRECT "cache.direct"
|
||||
#define BDRV_OPT_CACHE_NO_FLUSH "cache.no-flush"
|
||||
#define BDRV_OPT_READ_ONLY "read-only"
|
||||
#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
|
||||
#define BDRV_OPT_DISCARD "discard"
|
||||
#define BDRV_OPT_FORCE_SHARE "force-share"
|
||||
|
||||
|
||||
#define BDRV_SECTOR_BITS 9
|
||||
#define BDRV_SECTOR_SIZE (1ULL << BDRV_SECTOR_BITS)
|
||||
|
||||
#define BDRV_REQUEST_MAX_SECTORS MIN_CONST(SIZE_MAX >> BDRV_SECTOR_BITS, \
|
||||
INT_MAX >> BDRV_SECTOR_BITS)
|
||||
#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
|
||||
|
||||
/*
|
||||
* We want allow aligning requests and disk length up to any 32bit alignment
|
||||
* and don't afraid of overflow.
|
||||
* To achieve it, and in the same time use some pretty number as maximum disk
|
||||
* size, let's define maximum "length" (a limit for any offset/bytes request and
|
||||
* for disk size) to be the greatest power of 2 less than INT64_MAX.
|
||||
*/
|
||||
#define BDRV_MAX_ALIGNMENT (1L << 30)
|
||||
#define BDRV_MAX_LENGTH (QEMU_ALIGN_DOWN(INT64_MAX, BDRV_MAX_ALIGNMENT))
|
||||
|
||||
/*
|
||||
* Allocation status flags for bdrv_block_status() and friends.
|
||||
*
|
||||
* Public flags:
|
||||
* BDRV_BLOCK_DATA: allocation for data at offset is tied to this layer
|
||||
* BDRV_BLOCK_ZERO: offset reads as zero
|
||||
* BDRV_BLOCK_OFFSET_VALID: an associated offset exists for accessing raw data
|
||||
* BDRV_BLOCK_ALLOCATED: the content of the block is determined by this
|
||||
* layer rather than any backing, set by block layer
|
||||
* BDRV_BLOCK_EOF: the returned pnum covers through end of file for this
|
||||
* layer, set by block layer
|
||||
*
|
||||
* Internal flags:
|
||||
* BDRV_BLOCK_RAW: for use by passthrough drivers, such as raw, to request
|
||||
* that the block layer recompute the answer from the returned
|
||||
* BDS; must be accompanied by just BDRV_BLOCK_OFFSET_VALID.
|
||||
* BDRV_BLOCK_RECURSE: request that the block layer will recursively search for
|
||||
* zeroes in file child of current block node inside
|
||||
* returned region. Only valid together with both
|
||||
* BDRV_BLOCK_DATA and BDRV_BLOCK_OFFSET_VALID. Should not
|
||||
* appear with BDRV_BLOCK_ZERO.
|
||||
*
|
||||
* If BDRV_BLOCK_OFFSET_VALID is set, the map parameter represents the
|
||||
* host offset within the returned BDS that is allocated for the
|
||||
* corresponding raw guest data. However, whether that offset
|
||||
* actually contains data also depends on BDRV_BLOCK_DATA, as follows:
|
||||
*
|
||||
* DATA ZERO OFFSET_VALID
|
||||
* t t t sectors read as zero, returned file is zero at offset
|
||||
* t f t sectors read as valid from file at offset
|
||||
* f t t sectors preallocated, read as zero, returned file not
|
||||
* necessarily zero at offset
|
||||
* f f t sectors preallocated but read from backing_hd,
|
||||
* returned file contains garbage at offset
|
||||
* t t f sectors preallocated, read as zero, unknown offset
|
||||
* t f f sectors read from unknown file or offset
|
||||
* f t f not allocated or unknown offset, read as zero
|
||||
* f f f not allocated or unknown offset, read from backing_hd
|
||||
*/
|
||||
#define BDRV_BLOCK_DATA 0x01
|
||||
#define BDRV_BLOCK_ZERO 0x02
|
||||
#define BDRV_BLOCK_OFFSET_VALID 0x04
|
||||
#define BDRV_BLOCK_RAW 0x08
|
||||
#define BDRV_BLOCK_ALLOCATED 0x10
|
||||
#define BDRV_BLOCK_EOF 0x20
|
||||
#define BDRV_BLOCK_RECURSE 0x40
|
||||
|
||||
typedef QTAILQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
|
||||
|
||||
typedef struct BDRVReopenState {
|
||||
BlockDriverState *bs;
|
||||
int flags;
|
||||
BlockdevDetectZeroesOptions detect_zeroes;
|
||||
bool backing_missing;
|
||||
BlockDriverState *old_backing_bs; /* keep pointer for permissions update */
|
||||
BlockDriverState *old_file_bs; /* keep pointer for permissions update */
|
||||
QDict *options;
|
||||
QDict *explicit_options;
|
||||
void *opaque;
|
||||
} BDRVReopenState;
|
||||
|
||||
/*
|
||||
* Block operation types
|
||||
*/
|
||||
typedef enum BlockOpType {
|
||||
BLOCK_OP_TYPE_BACKUP_SOURCE,
|
||||
BLOCK_OP_TYPE_BACKUP_TARGET,
|
||||
BLOCK_OP_TYPE_CHANGE,
|
||||
BLOCK_OP_TYPE_COMMIT_SOURCE,
|
||||
BLOCK_OP_TYPE_COMMIT_TARGET,
|
||||
BLOCK_OP_TYPE_DATAPLANE,
|
||||
BLOCK_OP_TYPE_DRIVE_DEL,
|
||||
BLOCK_OP_TYPE_EJECT,
|
||||
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
|
||||
BLOCK_OP_TYPE_INTERNAL_SNAPSHOT,
|
||||
BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
|
||||
BLOCK_OP_TYPE_MIRROR_SOURCE,
|
||||
BLOCK_OP_TYPE_MIRROR_TARGET,
|
||||
BLOCK_OP_TYPE_RESIZE,
|
||||
BLOCK_OP_TYPE_STREAM,
|
||||
BLOCK_OP_TYPE_REPLACE,
|
||||
BLOCK_OP_TYPE_MAX,
|
||||
} BlockOpType;
|
||||
|
||||
/* Block node permission constants */
|
||||
enum {
|
||||
/**
|
||||
* A user that has the "permission" of consistent reads is guaranteed that
|
||||
* their view of the contents of the block device is complete and
|
||||
* self-consistent, representing the contents of a disk at a specific
|
||||
* point.
|
||||
*
|
||||
* For most block devices (including their backing files) this is true, but
|
||||
* the property cannot be maintained in a few situations like for
|
||||
* intermediate nodes of a commit block job.
|
||||
*/
|
||||
BLK_PERM_CONSISTENT_READ = 0x01,
|
||||
|
||||
/** This permission is required to change the visible disk contents. */
|
||||
BLK_PERM_WRITE = 0x02,
|
||||
|
||||
/**
|
||||
* This permission (which is weaker than BLK_PERM_WRITE) is both enough and
|
||||
* required for writes to the block node when the caller promises that
|
||||
* the visible disk content doesn't change.
|
||||
*
|
||||
* As the BLK_PERM_WRITE permission is strictly stronger, either is
|
||||
* sufficient to perform an unchanging write.
|
||||
*/
|
||||
BLK_PERM_WRITE_UNCHANGED = 0x04,
|
||||
|
||||
/** This permission is required to change the size of a block node. */
|
||||
BLK_PERM_RESIZE = 0x08,
|
||||
|
||||
/**
|
||||
* There was a now-removed bit BLK_PERM_GRAPH_MOD, with value of 0x10. QEMU
|
||||
* 6.1 and earlier may still lock the corresponding byte in block/file-posix
|
||||
* locking. So, implementing some new permission should be very careful to
|
||||
* not interfere with this old unused thing.
|
||||
*/
|
||||
|
||||
BLK_PERM_ALL = 0x0f,
|
||||
|
||||
DEFAULT_PERM_PASSTHROUGH = BLK_PERM_CONSISTENT_READ
|
||||
| BLK_PERM_WRITE
|
||||
| BLK_PERM_WRITE_UNCHANGED
|
||||
| BLK_PERM_RESIZE,
|
||||
|
||||
DEFAULT_PERM_UNCHANGED = BLK_PERM_ALL & ~DEFAULT_PERM_PASSTHROUGH,
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags that parent nodes assign to child nodes to specify what kind of
|
||||
* role(s) they take.
|
||||
*
|
||||
* At least one of DATA, METADATA, FILTERED, or COW must be set for
|
||||
* every child.
|
||||
*
|
||||
*
|
||||
* = Connection with bs->children, bs->file and bs->backing fields =
|
||||
*
|
||||
* 1. Filters
|
||||
*
|
||||
* Filter drivers have drv->is_filter = true.
|
||||
*
|
||||
* Filter node has exactly one FILTERED|PRIMARY child, and may have other
|
||||
* children which must not have these bits (one example is the
|
||||
* copy-before-write filter, which also has its target DATA child).
|
||||
*
|
||||
* Filter nodes never have COW children.
|
||||
*
|
||||
* For most filters, the filtered child is linked in bs->file, bs->backing is
|
||||
* NULL. For some filters (as an exception), it is the other way around; those
|
||||
* drivers will have drv->filtered_child_is_backing set to true (see that
|
||||
* field’s documentation for what drivers this concerns)
|
||||
*
|
||||
* 2. "raw" driver (block/raw-format.c)
|
||||
*
|
||||
* Formally it's not a filter (drv->is_filter = false)
|
||||
*
|
||||
* bs->backing is always NULL
|
||||
*
|
||||
* Only has one child, linked in bs->file. Its role is either FILTERED|PRIMARY
|
||||
* (like filter) or DATA|PRIMARY depending on options.
|
||||
*
|
||||
* 3. Other drivers
|
||||
*
|
||||
* Don't have any FILTERED children.
|
||||
*
|
||||
* May have at most one COW child. In this case it's linked in bs->backing.
|
||||
* Otherwise bs->backing is NULL. COW child is never PRIMARY.
|
||||
*
|
||||
* May have at most one PRIMARY child. In this case it's linked in bs->file.
|
||||
* Otherwise bs->file is NULL.
|
||||
*
|
||||
* May also have some other children that don't have the PRIMARY or COW bit set.
|
||||
*/
|
||||
enum BdrvChildRoleBits {
|
||||
/*
|
||||
* This child stores data.
|
||||
* Any node may have an arbitrary number of such children.
|
||||
*/
|
||||
BDRV_CHILD_DATA = (1 << 0),
|
||||
|
||||
/*
|
||||
* This child stores metadata.
|
||||
* Any node may have an arbitrary number of metadata-storing
|
||||
* children.
|
||||
*/
|
||||
BDRV_CHILD_METADATA = (1 << 1),
|
||||
|
||||
/*
|
||||
* A child that always presents exactly the same visible data as
|
||||
* the parent, e.g. by virtue of the parent forwarding all reads
|
||||
* and writes.
|
||||
* This flag is mutually exclusive with DATA, METADATA, and COW.
|
||||
* Any node may have at most one filtered child at a time.
|
||||
*/
|
||||
BDRV_CHILD_FILTERED = (1 << 2),
|
||||
|
||||
/*
|
||||
* Child from which to read all data that isn't allocated in the
|
||||
* parent (i.e., the backing child); such data is copied to the
|
||||
* parent through COW (and optionally COR).
|
||||
* This field is mutually exclusive with DATA, METADATA, and
|
||||
* FILTERED.
|
||||
* Any node may have at most one such backing child at a time.
|
||||
*/
|
||||
BDRV_CHILD_COW = (1 << 3),
|
||||
|
||||
/*
|
||||
* The primary child. For most drivers, this is the child whose
|
||||
* filename applies best to the parent node.
|
||||
* Any node may have at most one primary child at a time.
|
||||
*/
|
||||
BDRV_CHILD_PRIMARY = (1 << 4),
|
||||
|
||||
/* Useful combination of flags */
|
||||
BDRV_CHILD_IMAGE = BDRV_CHILD_DATA
|
||||
| BDRV_CHILD_METADATA
|
||||
| BDRV_CHILD_PRIMARY,
|
||||
};
|
||||
|
||||
/* Mask of BdrvChildRoleBits values */
|
||||
typedef unsigned int BdrvChildRole;
|
||||
|
||||
typedef struct BdrvCheckResult {
|
||||
int corruptions;
|
||||
int leaks;
|
||||
int check_errors;
|
||||
int corruptions_fixed;
|
||||
int leaks_fixed;
|
||||
int64_t image_end_offset;
|
||||
BlockFragInfo bfi;
|
||||
} BdrvCheckResult;
|
||||
|
||||
typedef enum {
|
||||
BDRV_FIX_LEAKS = 1,
|
||||
BDRV_FIX_ERRORS = 2,
|
||||
} BdrvCheckMode;
|
||||
|
||||
typedef struct BlockSizes {
|
||||
uint32_t phys;
|
||||
uint32_t log;
|
||||
} BlockSizes;
|
||||
|
||||
typedef struct HDGeometry {
|
||||
uint32_t heads;
|
||||
uint32_t sectors;
|
||||
uint32_t cylinders;
|
||||
} HDGeometry;
|
||||
|
||||
/*
|
||||
* Common functions that are neither I/O nor Global State.
|
||||
*
|
||||
* These functions must never call any function from other categories
|
||||
* (I/O, "I/O or GS", Global State) except this one, but can be invoked by
|
||||
* all of them.
|
||||
*/
|
||||
|
||||
char *bdrv_perm_names(uint64_t perm);
|
||||
uint64_t bdrv_qapi_perm_to_blk_perm(BlockPermission qapi_perm);
|
||||
|
||||
void bdrv_init_with_whitelist(void);
|
||||
bool bdrv_uses_whitelist(void);
|
||||
int bdrv_is_whitelisted(BlockDriver *drv, bool read_only);
|
||||
|
||||
int bdrv_parse_aio(const char *mode, int *flags);
|
||||
int bdrv_parse_cache_mode(const char *mode, int *flags, bool *writethrough);
|
||||
int bdrv_parse_discard_flags(const char *mode, int *flags);
|
||||
|
||||
int path_has_protocol(const char *path);
|
||||
int path_is_absolute(const char *path);
|
||||
char *path_combine(const char *base_path, const char *filename);
|
||||
|
||||
char *bdrv_get_full_backing_filename_from_filename(const char *backed,
|
||||
const char *backing,
|
||||
Error **errp);
|
||||
|
||||
#endif /* BLOCK_COMMON_H */
|
||||
@@ -25,19 +25,24 @@ typedef struct BlockCopyState BlockCopyState;
|
||||
typedef struct BlockCopyCallState BlockCopyCallState;
|
||||
|
||||
BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
|
||||
int64_t cluster_size, bool use_copy_range,
|
||||
BdrvRequestFlags write_flags,
|
||||
const BdrvDirtyBitmap *bitmap,
|
||||
Error **errp);
|
||||
|
||||
/* Function should be called prior any actual copy request */
|
||||
void block_copy_set_copy_opts(BlockCopyState *s, bool use_copy_range,
|
||||
bool compress);
|
||||
void block_copy_set_progress_meter(BlockCopyState *s, ProgressMeter *pm);
|
||||
|
||||
void block_copy_state_free(BlockCopyState *s);
|
||||
|
||||
void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes);
|
||||
int64_t block_copy_reset_unallocated(BlockCopyState *s,
|
||||
int64_t offset, int64_t *count);
|
||||
|
||||
int coroutine_fn block_copy(BlockCopyState *s, int64_t offset, int64_t bytes,
|
||||
bool ignore_ratelimit);
|
||||
bool ignore_ratelimit, uint64_t timeout_ns,
|
||||
BlockCopyAsyncCallbackFunc cb,
|
||||
void *cb_opaque);
|
||||
|
||||
/*
|
||||
* Run block-copy in a coroutine, create corresponding BlockCopyCallState
|
||||
@@ -89,6 +94,7 @@ void block_copy_kick(BlockCopyCallState *call_state);
|
||||
void block_copy_call_cancel(BlockCopyCallState *call_state);
|
||||
|
||||
BdrvDirtyBitmap *block_copy_dirty_bitmap(BlockCopyState *s);
|
||||
int64_t block_copy_cluster_size(BlockCopyState *s);
|
||||
void block_copy_set_skip_unallocated(BlockCopyState *s, bool skip);
|
||||
|
||||
#endif /* BLOCK_COPY_H */
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* QEMU System Emulator block driver
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef BLOCK_GLOBAL_STATE_H
|
||||
#define BLOCK_GLOBAL_STATE_H
|
||||
|
||||
#include "block-common.h"
|
||||
|
||||
/*
|
||||
* Global state (GS) API. These functions run under the BQL.
|
||||
*
|
||||
* If a function modifies the graph, it also uses drain and/or
|
||||
* aio_context_acquire/release to be sure it has unique access.
|
||||
* aio_context locking is needed together with BQL because of
|
||||
* the thread-safe I/O API that concurrently runs and accesses
|
||||
* the graph without the BQL.
|
||||
*
|
||||
* It is important to note that not all of these functions are
|
||||
* necessarily limited to running under the BQL, but they would
|
||||
* require additional auditing and many small thread-safety changes
|
||||
* to move them into the I/O API. Often it's not worth doing that
|
||||
* work since the APIs are only used with the BQL held at the
|
||||
* moment, so they have been placed in the GS API (for now).
|
||||
*
|
||||
* These functions can call any function from this and other categories
|
||||
* (I/O, "I/O or GS", Common), but must be invoked only by other GS APIs.
|
||||
*
|
||||
* All functions in this header must use the macro
|
||||
* GLOBAL_STATE_CODE();
|
||||
* to catch when they are accidentally called without the BQL.
|
||||
*/
|
||||
|
||||
void bdrv_init(void);
|
||||
BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
bool allow_protocol_prefix,
|
||||
Error **errp);
|
||||
BlockDriver *bdrv_find_format(const char *format_name);
|
||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||
QemuOpts *opts, Error **errp);
|
||||
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
|
||||
|
||||
BlockDriverState *bdrv_new(void);
|
||||
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
|
||||
Error **errp);
|
||||
int bdrv_replace_node(BlockDriverState *from, BlockDriverState *to,
|
||||
Error **errp);
|
||||
int bdrv_replace_child_bs(BdrvChild *child, BlockDriverState *new_bs,
|
||||
Error **errp);
|
||||
BlockDriverState *bdrv_insert_node(BlockDriverState *bs, QDict *node_options,
|
||||
int flags, Error **errp);
|
||||
int bdrv_drop_filter(BlockDriverState *bs, Error **errp);
|
||||
|
||||
BdrvChild *bdrv_open_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
bool allow_none, Error **errp);
|
||||
int bdrv_open_file_child(const char *filename,
|
||||
QDict *options, const char *bdref_key,
|
||||
BlockDriverState *parent, Error **errp);
|
||||
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
|
||||
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
||||
Error **errp);
|
||||
int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
|
||||
const char *bdref_key, Error **errp);
|
||||
BlockDriverState *bdrv_open(const char *filename, const char *reference,
|
||||
QDict *options, int flags, Error **errp);
|
||||
BlockDriverState *bdrv_new_open_driver_opts(BlockDriver *drv,
|
||||
const char *node_name,
|
||||
QDict *options, int flags,
|
||||
Error **errp);
|
||||
BlockDriverState *bdrv_new_open_driver(BlockDriver *drv, const char *node_name,
|
||||
int flags, Error **errp);
|
||||
BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
||||
BlockDriverState *bs, QDict *options,
|
||||
bool keep_old_opts);
|
||||
void bdrv_reopen_queue_free(BlockReopenQueue *bs_queue);
|
||||
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
|
||||
int bdrv_reopen(BlockDriverState *bs, QDict *opts, bool keep_old_opts,
|
||||
Error **errp);
|
||||
int bdrv_reopen_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
Error **errp);
|
||||
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
|
||||
const char *backing_file);
|
||||
void bdrv_refresh_filename(BlockDriverState *bs);
|
||||
void bdrv_refresh_limits(BlockDriverState *bs, Transaction *tran, Error **errp);
|
||||
int bdrv_commit(BlockDriverState *bs);
|
||||
int bdrv_make_empty(BdrvChild *c, Error **errp);
|
||||
int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file,
|
||||
const char *backing_fmt, bool warn);
|
||||
void bdrv_register(BlockDriver *bdrv);
|
||||
int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
|
||||
const char *backing_file_str);
|
||||
BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
|
||||
BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_find_base(BlockDriverState *bs);
|
||||
bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
|
||||
Error **errp);
|
||||
int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
|
||||
Error **errp);
|
||||
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base);
|
||||
|
||||
/*
|
||||
* The units of offset and total_work_size may be chosen arbitrarily by the
|
||||
* block driver; total_work_size may change during the course of the amendment
|
||||
* operation
|
||||
*/
|
||||
typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
|
||||
int64_t total_work_size, void *opaque);
|
||||
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
|
||||
bool force,
|
||||
Error **errp);
|
||||
|
||||
/* check if a named node can be replaced when doing drive-mirror */
|
||||
BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs,
|
||||
const char *node_name, Error **errp);
|
||||
|
||||
int bdrv_activate(BlockDriverState *bs, Error **errp);
|
||||
void bdrv_activate_all(Error **errp);
|
||||
int bdrv_inactivate_all(void);
|
||||
|
||||
int bdrv_flush_all(void);
|
||||
void bdrv_close_all(void);
|
||||
void bdrv_drain_all_begin(void);
|
||||
void bdrv_drain_all_end(void);
|
||||
void bdrv_drain_all(void);
|
||||
|
||||
int bdrv_has_zero_init_1(BlockDriverState *bs);
|
||||
int bdrv_has_zero_init(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_find_node(const char *node_name);
|
||||
BlockDeviceInfoList *bdrv_named_nodes_list(bool flat, Error **errp);
|
||||
XDbgBlockGraph *bdrv_get_xdbg_block_graph(Error **errp);
|
||||
BlockDriverState *bdrv_lookup_bs(const char *device,
|
||||
const char *node_name,
|
||||
Error **errp);
|
||||
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
|
||||
BlockDriverState *bdrv_next_node(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_next_all_states(BlockDriverState *bs);
|
||||
|
||||
typedef struct BdrvNextIterator {
|
||||
enum {
|
||||
BDRV_NEXT_BACKEND_ROOTS,
|
||||
BDRV_NEXT_MONITOR_OWNED,
|
||||
} phase;
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
} BdrvNextIterator;
|
||||
|
||||
BlockDriverState *bdrv_first(BdrvNextIterator *it);
|
||||
BlockDriverState *bdrv_next(BdrvNextIterator *it);
|
||||
void bdrv_next_cleanup(BdrvNextIterator *it);
|
||||
|
||||
BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
|
||||
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
|
||||
void *opaque, bool read_only);
|
||||
char *bdrv_get_full_backing_filename(BlockDriverState *bs, Error **errp);
|
||||
char *bdrv_dirname(BlockDriverState *bs, Error **errp);
|
||||
|
||||
void bdrv_img_create(const char *filename, const char *fmt,
|
||||
const char *base_filename, const char *base_fmt,
|
||||
char *options, uint64_t img_size, int flags,
|
||||
bool quiet, Error **errp);
|
||||
|
||||
void bdrv_ref(BlockDriverState *bs);
|
||||
void bdrv_unref(BlockDriverState *bs);
|
||||
void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child);
|
||||
BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
|
||||
BlockDriverState *child_bs,
|
||||
const char *child_name,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
Error **errp);
|
||||
|
||||
bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp);
|
||||
void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason);
|
||||
void bdrv_op_unblock(BlockDriverState *bs, BlockOpType op, Error *reason);
|
||||
void bdrv_op_block_all(BlockDriverState *bs, Error *reason);
|
||||
void bdrv_op_unblock_all(BlockDriverState *bs, Error *reason);
|
||||
bool bdrv_op_blocker_is_empty(BlockDriverState *bs);
|
||||
|
||||
int bdrv_debug_breakpoint(BlockDriverState *bs, const char *event,
|
||||
const char *tag);
|
||||
int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
|
||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
|
||||
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
|
||||
|
||||
/**
|
||||
* Locks the AioContext of @bs if it's not the current AioContext. This avoids
|
||||
* double locking which could lead to deadlocks: This is a coroutine_fn, so we
|
||||
* know we already own the lock of the current AioContext.
|
||||
*
|
||||
* May only be called in the main thread.
|
||||
*/
|
||||
void coroutine_fn bdrv_co_lock(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* Unlocks the AioContext of @bs if it's not the current AioContext.
|
||||
*/
|
||||
void coroutine_fn bdrv_co_unlock(BlockDriverState *bs);
|
||||
|
||||
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp);
|
||||
int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
BdrvChild *ignore_child, Error **errp);
|
||||
|
||||
int bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
|
||||
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
|
||||
|
||||
void bdrv_add_child(BlockDriverState *parent, BlockDriverState *child,
|
||||
Error **errp);
|
||||
void bdrv_del_child(BlockDriverState *parent, BdrvChild *child, Error **errp);
|
||||
|
||||
/**
|
||||
*
|
||||
* bdrv_register_buf/bdrv_unregister_buf:
|
||||
*
|
||||
* Register/unregister a buffer for I/O. For example, VFIO drivers are
|
||||
* interested to know the memory areas that would later be used for I/O, so
|
||||
* that they can prepare IOMMU mapping etc., to get better performance.
|
||||
*
|
||||
* Buffers must not overlap and they must be unregistered with the same <host,
|
||||
* size> values that they were registered with.
|
||||
*
|
||||
* Returns: true on success, false on failure
|
||||
*/
|
||||
bool bdrv_register_buf(BlockDriverState *bs, void *host, size_t size,
|
||||
Error **errp);
|
||||
void bdrv_unregister_buf(BlockDriverState *bs, void *host, size_t size);
|
||||
|
||||
void bdrv_cancel_in_flight(BlockDriverState *bs);
|
||||
|
||||
#endif /* BLOCK_GLOBAL_STATE_H */
|
||||
@@ -12,8 +12,8 @@
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef BLOCK_HMP_COMMANDS_H
|
||||
#define BLOCK_HMP_COMMANDS_H
|
||||
#ifndef BLOCK_BLOCK_HMP_CMDS_H
|
||||
#define BLOCK_BLOCK_HMP_CMDS_H
|
||||
|
||||
void hmp_drive_add(Monitor *mon, const QDict *qdict);
|
||||
|
||||
@@ -38,7 +38,7 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_block_resize(Monitor *mon, const QDict *qdict);
|
||||
void coroutine_fn hmp_block_resize(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_stream(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_passwd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* QEMU System Emulator block driver
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef BLOCK_IO_H
|
||||
#define BLOCK_IO_H
|
||||
|
||||
#include "block-common.h"
|
||||
|
||||
/*
|
||||
* I/O API functions. These functions are thread-safe, and therefore
|
||||
* can run in any thread as long as the thread has called
|
||||
* aio_context_acquire/release().
|
||||
*
|
||||
* These functions can only call functions from I/O and Common categories,
|
||||
* but can be invoked by GS, "I/O or GS" and I/O APIs.
|
||||
*
|
||||
* All functions in this category must use the macro
|
||||
* IO_CODE();
|
||||
* to catch when they are accidentally called by the wrong API.
|
||||
*/
|
||||
|
||||
int generated_co_wrapper bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes,
|
||||
BdrvRequestFlags flags);
|
||||
int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags);
|
||||
int generated_co_wrapper bdrv_pread(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes, void *buf,
|
||||
BdrvRequestFlags flags);
|
||||
int generated_co_wrapper bdrv_pwrite(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes, const void *buf,
|
||||
BdrvRequestFlags flags);
|
||||
int generated_co_wrapper bdrv_pwrite_sync(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes, const void *buf,
|
||||
BdrvRequestFlags flags);
|
||||
int coroutine_fn bdrv_co_pwrite_sync(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes, const void *buf,
|
||||
BdrvRequestFlags flags);
|
||||
/*
|
||||
* Efficiently zero a region of the disk image. Note that this is a regular
|
||||
* I/O request like read or write and should have a reasonable size. This
|
||||
* function is not suitable for zeroing the entire image in a single request
|
||||
* because it may allocate memory for the entire region.
|
||||
*/
|
||||
int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes, BdrvRequestFlags flags);
|
||||
|
||||
int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, BdrvRequestFlags flags,
|
||||
Error **errp);
|
||||
|
||||
int64_t bdrv_nb_sectors(BlockDriverState *bs);
|
||||
int64_t bdrv_getlength(BlockDriverState *bs);
|
||||
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
|
||||
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
||||
BlockDriverState *in_bs, Error **errp);
|
||||
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
|
||||
int coroutine_fn bdrv_co_delete_file(BlockDriverState *bs, Error **errp);
|
||||
void coroutine_fn bdrv_co_delete_file_noerr(BlockDriverState *bs);
|
||||
|
||||
|
||||
/* async block I/O */
|
||||
void bdrv_aio_cancel(BlockAIOCB *acb);
|
||||
void bdrv_aio_cancel_async(BlockAIOCB *acb);
|
||||
|
||||
/* sg packet commands */
|
||||
int coroutine_fn bdrv_co_ioctl(BlockDriverState *bs, int req, void *buf);
|
||||
|
||||
/* Ensure contents are flushed to disk. */
|
||||
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
|
||||
|
||||
int coroutine_fn bdrv_co_pdiscard(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes);
|
||||
bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs);
|
||||
int bdrv_block_status(BlockDriverState *bs, int64_t offset,
|
||||
int64_t bytes, int64_t *pnum, int64_t *map,
|
||||
BlockDriverState **file);
|
||||
int bdrv_block_status_above(BlockDriverState *bs, BlockDriverState *base,
|
||||
int64_t offset, int64_t bytes, int64_t *pnum,
|
||||
int64_t *map, BlockDriverState **file);
|
||||
int bdrv_is_allocated(BlockDriverState *bs, int64_t offset, int64_t bytes,
|
||||
int64_t *pnum);
|
||||
int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
|
||||
bool include_base, int64_t offset, int64_t bytes,
|
||||
int64_t *pnum);
|
||||
int coroutine_fn bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset,
|
||||
int64_t bytes);
|
||||
|
||||
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
|
||||
bool ignore_allow_rdw, Error **errp);
|
||||
int bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
|
||||
Error **errp);
|
||||
bool bdrv_is_read_only(BlockDriverState *bs);
|
||||
bool bdrv_is_writable(BlockDriverState *bs);
|
||||
bool bdrv_is_sg(BlockDriverState *bs);
|
||||
int bdrv_get_flags(BlockDriverState *bs);
|
||||
bool bdrv_is_inserted(BlockDriverState *bs);
|
||||
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
|
||||
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
|
||||
const char *bdrv_get_format_name(BlockDriverState *bs);
|
||||
|
||||
bool bdrv_supports_compressed_writes(BlockDriverState *bs);
|
||||
const char *bdrv_get_node_name(const BlockDriverState *bs);
|
||||
const char *bdrv_get_device_name(const BlockDriverState *bs);
|
||||
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
|
||||
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
|
||||
ImageInfoSpecific *bdrv_get_specific_info(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
BlockStatsSpecific *bdrv_get_specific_stats(BlockDriverState *bs);
|
||||
void bdrv_round_to_clusters(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes,
|
||||
int64_t *cluster_offset,
|
||||
int64_t *cluster_bytes);
|
||||
|
||||
void bdrv_get_backing_filename(BlockDriverState *bs,
|
||||
char *filename, int filename_size);
|
||||
|
||||
int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
|
||||
int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||
int64_t pos, int size);
|
||||
|
||||
/*
|
||||
* Returns the alignment in bytes that is required so that no bounce buffer
|
||||
* is required throughout the stack
|
||||
*/
|
||||
size_t bdrv_min_mem_align(BlockDriverState *bs);
|
||||
/* Returns optimal alignment in bytes for bounce buffer */
|
||||
size_t bdrv_opt_mem_align(BlockDriverState *bs);
|
||||
void *qemu_blockalign(BlockDriverState *bs, size_t size);
|
||||
void *qemu_blockalign0(BlockDriverState *bs, size_t size);
|
||||
void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
|
||||
void *qemu_try_blockalign0(BlockDriverState *bs, size_t size);
|
||||
|
||||
void bdrv_enable_copy_on_read(BlockDriverState *bs);
|
||||
void bdrv_disable_copy_on_read(BlockDriverState *bs);
|
||||
|
||||
void bdrv_debug_event(BlockDriverState *bs, BlkdebugEvent event);
|
||||
|
||||
#define BLKDBG_EVENT(child, evt) \
|
||||
do { \
|
||||
if (child) { \
|
||||
bdrv_debug_event(child->bs, evt); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* bdrv_get_aio_context:
|
||||
*
|
||||
* Returns: the currently bound #AioContext
|
||||
*/
|
||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
|
||||
|
||||
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
|
||||
|
||||
/**
|
||||
* Move the current coroutine to the AioContext of @bs and return the old
|
||||
* AioContext of the coroutine. Increase bs->in_flight so that draining @bs
|
||||
* will wait for the operation to proceed until the corresponding
|
||||
* bdrv_co_leave().
|
||||
*
|
||||
* Consequently, you can't call drain inside a bdrv_co_enter/leave() section as
|
||||
* this will deadlock.
|
||||
*/
|
||||
AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* Ends a section started by bdrv_co_enter(). Move the current coroutine back
|
||||
* to old_ctx and decrease bs->in_flight again.
|
||||
*/
|
||||
void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
|
||||
|
||||
/**
|
||||
* Transfer control to @co in the aio context of @bs
|
||||
*/
|
||||
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co);
|
||||
|
||||
AioContext *child_of_bds_get_parent_aio_context(BdrvChild *c);
|
||||
|
||||
void bdrv_io_plug(BlockDriverState *bs);
|
||||
void bdrv_io_unplug(BlockDriverState *bs);
|
||||
|
||||
bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
|
||||
uint32_t granularity, Error **errp);
|
||||
|
||||
/**
|
||||
*
|
||||
* bdrv_co_copy_range:
|
||||
*
|
||||
* Do offloaded copy between two children. If the operation is not implemented
|
||||
* by the driver, or if the backend storage doesn't support it, a negative
|
||||
* error code will be returned.
|
||||
*
|
||||
* Note: block layer doesn't emulate or fallback to a bounce buffer approach
|
||||
* because usually the caller shouldn't attempt offloaded copy any more (e.g.
|
||||
* calling copy_file_range(2)) after the first error, thus it should fall back
|
||||
* to a read+write path in the caller level.
|
||||
*
|
||||
* @src: Source child to copy data from
|
||||
* @src_offset: offset in @src image to read data
|
||||
* @dst: Destination child to copy data to
|
||||
* @dst_offset: offset in @dst image to write data
|
||||
* @bytes: number of bytes to copy
|
||||
* @flags: request flags. Supported flags:
|
||||
* BDRV_REQ_ZERO_WRITE - treat the @src range as zero data and do zero
|
||||
* write on @dst as if bdrv_co_pwrite_zeroes is
|
||||
* called. Used to simplify caller code, or
|
||||
* during BlockDriver.bdrv_co_copy_range_from()
|
||||
* recursion.
|
||||
* BDRV_REQ_NO_SERIALISING - do not serialize with other overlapping
|
||||
* requests currently in flight.
|
||||
*
|
||||
* Returns: 0 if succeeded; negative error code if failed.
|
||||
**/
|
||||
int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
|
||||
BdrvChild *dst, int64_t dst_offset,
|
||||
int64_t bytes, BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags);
|
||||
|
||||
/**
|
||||
* bdrv_drained_end_no_poll:
|
||||
*
|
||||
* Same as bdrv_drained_end(), but do not poll for the subgraph to
|
||||
* actually become unquiesced. Therefore, no graph changes will occur
|
||||
* with this function.
|
||||
*
|
||||
* *drained_end_counter is incremented for every background operation
|
||||
* that is scheduled, and will be decremented for every operation once
|
||||
* it settles. The caller must poll until it reaches 0. The counter
|
||||
* should be accessed using atomic operations only.
|
||||
*/
|
||||
void bdrv_drained_end_no_poll(BlockDriverState *bs, int *drained_end_counter);
|
||||
|
||||
|
||||
/*
|
||||
* "I/O or GS" API functions. These functions can run without
|
||||
* the BQL, but only in one specific iothread/main loop.
|
||||
*
|
||||
* More specifically, these functions use BDRV_POLL_WHILE(bs), which
|
||||
* requires the caller to be either in the main thread and hold
|
||||
* the BlockdriverState (bs) AioContext lock, or directly in the
|
||||
* home thread that runs the bs AioContext. Calling them from
|
||||
* another thread in another AioContext would cause deadlocks.
|
||||
*
|
||||
* Therefore, these functions are not proper I/O, because they
|
||||
* can't run in *any* iothreads, but only in a specific one.
|
||||
*
|
||||
* These functions can call any function from I/O, Common and this
|
||||
* categories, but must be invoked only by other "I/O or GS" and GS APIs.
|
||||
*
|
||||
* All functions in this category must use the macro
|
||||
* IO_OR_GS_CODE();
|
||||
* to catch when they are accidentally called by the wrong API.
|
||||
*/
|
||||
|
||||
#define BDRV_POLL_WHILE(bs, cond) ({ \
|
||||
BlockDriverState *bs_ = (bs); \
|
||||
IO_OR_GS_CODE(); \
|
||||
AIO_WAIT_WHILE(bdrv_get_aio_context(bs_), \
|
||||
cond); })
|
||||
|
||||
void bdrv_drain(BlockDriverState *bs);
|
||||
|
||||
int generated_co_wrapper
|
||||
bdrv_truncate(BdrvChild *child, int64_t offset, bool exact,
|
||||
PreallocMode prealloc, BdrvRequestFlags flags, Error **errp);
|
||||
|
||||
int generated_co_wrapper bdrv_check(BlockDriverState *bs, BdrvCheckResult *res,
|
||||
BdrvCheckMode fix);
|
||||
|
||||
/* Invalidate any cached metadata used by image formats */
|
||||
int generated_co_wrapper bdrv_invalidate_cache(BlockDriverState *bs,
|
||||
Error **errp);
|
||||
int generated_co_wrapper bdrv_flush(BlockDriverState *bs);
|
||||
int generated_co_wrapper bdrv_pdiscard(BdrvChild *child, int64_t offset,
|
||||
int64_t bytes);
|
||||
int generated_co_wrapper
|
||||
bdrv_readv_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
||||
int generated_co_wrapper
|
||||
bdrv_writev_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos);
|
||||
|
||||
/**
|
||||
* bdrv_parent_drained_begin_single:
|
||||
*
|
||||
* Begin a quiesced section for the parent of @c. If @poll is true, wait for
|
||||
* any pending activity to cease.
|
||||
*/
|
||||
void bdrv_parent_drained_begin_single(BdrvChild *c, bool poll);
|
||||
|
||||
/**
|
||||
* bdrv_parent_drained_end_single:
|
||||
*
|
||||
* End a quiesced section for the parent of @c.
|
||||
*
|
||||
* This polls @bs's AioContext until all scheduled sub-drained_ends
|
||||
* have settled, which may result in graph changes.
|
||||
*/
|
||||
void bdrv_parent_drained_end_single(BdrvChild *c);
|
||||
|
||||
/**
|
||||
* bdrv_drain_poll:
|
||||
*
|
||||
* Poll for pending requests in @bs, its parents (except for @ignore_parent),
|
||||
* and if @recursive is true its children as well (used for subtree drain).
|
||||
*
|
||||
* If @ignore_bds_parents is true, parents that are BlockDriverStates must
|
||||
* ignore the drain request because they will be drained separately (used for
|
||||
* drain_all).
|
||||
*
|
||||
* This is part of bdrv_drained_begin.
|
||||
*/
|
||||
bool bdrv_drain_poll(BlockDriverState *bs, bool recursive,
|
||||
BdrvChild *ignore_parent, bool ignore_bds_parents);
|
||||
|
||||
/**
|
||||
* bdrv_drained_begin:
|
||||
*
|
||||
* Begin a quiesced section for exclusive access to the BDS, by disabling
|
||||
* external request sources including NBD server, block jobs, and device model.
|
||||
*
|
||||
* This function can be recursive.
|
||||
*/
|
||||
void bdrv_drained_begin(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* bdrv_do_drained_begin_quiesce:
|
||||
*
|
||||
* Quiesces a BDS like bdrv_drained_begin(), but does not wait for already
|
||||
* running requests to complete.
|
||||
*/
|
||||
void bdrv_do_drained_begin_quiesce(BlockDriverState *bs,
|
||||
BdrvChild *parent, bool ignore_bds_parents);
|
||||
|
||||
/**
|
||||
* Like bdrv_drained_begin, but recursively begins a quiesced section for
|
||||
* exclusive access to all child nodes as well.
|
||||
*/
|
||||
void bdrv_subtree_drained_begin(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* bdrv_drained_end:
|
||||
*
|
||||
* End a quiescent section started by bdrv_drained_begin().
|
||||
*
|
||||
* This polls @bs's AioContext until all scheduled sub-drained_ends
|
||||
* have settled. On one hand, that may result in graph changes. On
|
||||
* the other, this requires that the caller either runs in the main
|
||||
* loop; or that all involved nodes (@bs and all of its parents) are
|
||||
* in the caller's AioContext.
|
||||
*/
|
||||
void bdrv_drained_end(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* End a quiescent section started by bdrv_subtree_drained_begin().
|
||||
*/
|
||||
void bdrv_subtree_drained_end(BlockDriverState *bs);
|
||||
|
||||
#endif /* BLOCK_IO_H */
|
||||
+27
-855
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* QEMU System Emulator block driver
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef BLOCK_INT_GLOBAL_STATE_H
|
||||
#define BLOCK_INT_GLOBAL_STATE_H
|
||||
|
||||
#include "block_int-common.h"
|
||||
|
||||
/*
|
||||
* Global state (GS) API. These functions run under the BQL.
|
||||
*
|
||||
* See include/block/block-global-state.h for more information about
|
||||
* the GS API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* stream_start:
|
||||
* @job_id: The id of the newly-created job, or %NULL to use the
|
||||
* device name of @bs.
|
||||
* @bs: Block device to operate on.
|
||||
* @base: Block device that will become the new base, or %NULL to
|
||||
* flatten the whole backing file chain onto @bs.
|
||||
* @backing_file_str: The file name that will be written to @bs as the
|
||||
* the new backing file if the job completes. Ignored if @base is %NULL.
|
||||
* @creation_flags: Flags that control the behavior of the Job lifetime.
|
||||
* See @BlockJobCreateFlags
|
||||
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
|
||||
* @on_error: The action to take upon error.
|
||||
* @filter_node_name: The node name that should be assigned to the filter
|
||||
* driver that the stream job inserts into the graph above
|
||||
* @bs. NULL means that a node name should be autogenerated.
|
||||
* @errp: Error object.
|
||||
*
|
||||
* Start a streaming operation on @bs. Clusters that are unallocated
|
||||
* in @bs, but allocated in any image between @base and @bs (both
|
||||
* exclusive) will be written to @bs. At the end of a successful
|
||||
* streaming job, the backing file of @bs will be changed to
|
||||
* @backing_file_str in the written image and to @base in the live
|
||||
* BlockDriverState.
|
||||
*/
|
||||
void stream_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *base, const char *backing_file_str,
|
||||
BlockDriverState *bottom,
|
||||
int creation_flags, int64_t speed,
|
||||
BlockdevOnError on_error,
|
||||
const char *filter_node_name,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* commit_start:
|
||||
* @job_id: The id of the newly-created job, or %NULL to use the
|
||||
* device name of @bs.
|
||||
* @bs: Active block device.
|
||||
* @top: Top block device to be committed.
|
||||
* @base: Block device that will be written into, and become the new top.
|
||||
* @creation_flags: Flags that control the behavior of the Job lifetime.
|
||||
* See @BlockJobCreateFlags
|
||||
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
|
||||
* @on_error: The action to take upon error.
|
||||
* @backing_file_str: String to use as the backing file in @top's overlay
|
||||
* @filter_node_name: The node name that should be assigned to the filter
|
||||
* driver that the commit job inserts into the graph above @top. NULL means
|
||||
* that a node name should be autogenerated.
|
||||
* @errp: Error object.
|
||||
*
|
||||
*/
|
||||
void commit_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *base, BlockDriverState *top,
|
||||
int creation_flags, int64_t speed,
|
||||
BlockdevOnError on_error, const char *backing_file_str,
|
||||
const char *filter_node_name, Error **errp);
|
||||
/**
|
||||
* commit_active_start:
|
||||
* @job_id: The id of the newly-created job, or %NULL to use the
|
||||
* device name of @bs.
|
||||
* @bs: Active block device to be committed.
|
||||
* @base: Block device that will be written into, and become the new top.
|
||||
* @creation_flags: Flags that control the behavior of the Job lifetime.
|
||||
* See @BlockJobCreateFlags
|
||||
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
|
||||
* @on_error: The action to take upon error.
|
||||
* @filter_node_name: The node name that should be assigned to the filter
|
||||
* driver that the commit job inserts into the graph above @bs. NULL means that
|
||||
* a node name should be autogenerated.
|
||||
* @cb: Completion function for the job.
|
||||
* @opaque: Opaque pointer value passed to @cb.
|
||||
* @auto_complete: Auto complete the job.
|
||||
* @errp: Error object.
|
||||
*
|
||||
*/
|
||||
BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *base, int creation_flags,
|
||||
int64_t speed, BlockdevOnError on_error,
|
||||
const char *filter_node_name,
|
||||
BlockCompletionFunc *cb, void *opaque,
|
||||
bool auto_complete, Error **errp);
|
||||
/*
|
||||
* mirror_start:
|
||||
* @job_id: The id of the newly-created job, or %NULL to use the
|
||||
* device name of @bs.
|
||||
* @bs: Block device to operate on.
|
||||
* @target: Block device to write to.
|
||||
* @replaces: Block graph node name to replace once the mirror is done. Can
|
||||
* only be used when full mirroring is selected.
|
||||
* @creation_flags: Flags that control the behavior of the Job lifetime.
|
||||
* See @BlockJobCreateFlags
|
||||
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
|
||||
* @granularity: The chosen granularity for the dirty bitmap.
|
||||
* @buf_size: The amount of data that can be in flight at one time.
|
||||
* @mode: Whether to collapse all images in the chain to the target.
|
||||
* @backing_mode: How to establish the target's backing chain after completion.
|
||||
* @zero_target: Whether the target should be explicitly zero-initialized
|
||||
* @on_source_error: The action to take upon error reading from the source.
|
||||
* @on_target_error: The action to take upon error writing to the target.
|
||||
* @unmap: Whether to unmap target where source sectors only contain zeroes.
|
||||
* @filter_node_name: The node name that should be assigned to the filter
|
||||
* driver that the mirror job inserts into the graph above @bs. NULL means that
|
||||
* a node name should be autogenerated.
|
||||
* @copy_mode: When to trigger writes to the target.
|
||||
* @errp: Error object.
|
||||
*
|
||||
* Start a mirroring operation on @bs. Clusters that are allocated
|
||||
* in @bs will be written to @target until the job is cancelled or
|
||||
* manually completed. At the end of a successful mirroring job,
|
||||
* @bs will be switched to read from @target.
|
||||
*/
|
||||
void mirror_start(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target, const char *replaces,
|
||||
int creation_flags, int64_t speed,
|
||||
uint32_t granularity, int64_t buf_size,
|
||||
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
|
||||
bool zero_target,
|
||||
BlockdevOnError on_source_error,
|
||||
BlockdevOnError on_target_error,
|
||||
bool unmap, const char *filter_node_name,
|
||||
MirrorCopyMode copy_mode, Error **errp);
|
||||
|
||||
/*
|
||||
* backup_job_create:
|
||||
* @job_id: The id of the newly-created job, or %NULL to use the
|
||||
* device name of @bs.
|
||||
* @bs: Block device to operate on.
|
||||
* @target: Block device to write to.
|
||||
* @speed: The maximum speed, in bytes per second, or 0 for unlimited.
|
||||
* @sync_mode: What parts of the disk image should be copied to the destination.
|
||||
* @sync_bitmap: The dirty bitmap if sync_mode is 'bitmap' or 'incremental'
|
||||
* @bitmap_mode: The bitmap synchronization policy to use.
|
||||
* @perf: Performance options. All actual fields assumed to be present,
|
||||
* all ".has_*" fields are ignored.
|
||||
* @on_source_error: The action to take upon error reading from the source.
|
||||
* @on_target_error: The action to take upon error writing to the target.
|
||||
* @creation_flags: Flags that control the behavior of the Job lifetime.
|
||||
* See @BlockJobCreateFlags
|
||||
* @cb: Completion function for the job.
|
||||
* @opaque: Opaque pointer value passed to @cb.
|
||||
* @txn: Transaction that this job is part of (may be NULL).
|
||||
*
|
||||
* Create a backup operation on @bs. Clusters in @bs are written to @target
|
||||
* until the job is cancelled or manually completed.
|
||||
*/
|
||||
BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
||||
BlockDriverState *target, int64_t speed,
|
||||
MirrorSyncMode sync_mode,
|
||||
BdrvDirtyBitmap *sync_bitmap,
|
||||
BitmapSyncMode bitmap_mode,
|
||||
bool compress,
|
||||
const char *filter_node_name,
|
||||
BackupPerf *perf,
|
||||
BlockdevOnError on_source_error,
|
||||
BlockdevOnError on_target_error,
|
||||
int creation_flags,
|
||||
BlockCompletionFunc *cb, void *opaque,
|
||||
JobTxn *txn, Error **errp);
|
||||
|
||||
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
|
||||
const char *child_name,
|
||||
const BdrvChildClass *child_class,
|
||||
BdrvChildRole child_role,
|
||||
uint64_t perm, uint64_t shared_perm,
|
||||
void *opaque, Error **errp);
|
||||
void bdrv_root_unref_child(BdrvChild *child);
|
||||
|
||||
void bdrv_get_cumulative_perm(BlockDriverState *bs, uint64_t *perm,
|
||||
uint64_t *shared_perm);
|
||||
|
||||
/**
|
||||
* Sets a BdrvChild's permissions. Avoid if the parent is a BDS; use
|
||||
* bdrv_child_refresh_perms() instead and make the parent's
|
||||
* .bdrv_child_perm() implementation return the correct values.
|
||||
*/
|
||||
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
* Calls bs->drv->bdrv_child_perm() and updates the child's permission
|
||||
* masks with the result.
|
||||
* Drivers should invoke this function whenever an event occurs that
|
||||
* makes their .bdrv_child_perm() implementation return different
|
||||
* values than before, but which will not result in the block layer
|
||||
* automatically refreshing the permissions.
|
||||
*/
|
||||
int bdrv_child_refresh_perms(BlockDriverState *bs, BdrvChild *c, Error **errp);
|
||||
|
||||
bool bdrv_recurse_can_replace(BlockDriverState *bs,
|
||||
BlockDriverState *to_replace);
|
||||
|
||||
/*
|
||||
* Default implementation for BlockDriver.bdrv_child_perm() that can
|
||||
* be used by block filters and image formats, as long as they use the
|
||||
* child_of_bds child class and set an appropriate BdrvChildRole.
|
||||
*/
|
||||
void bdrv_default_perms(BlockDriverState *bs, BdrvChild *c,
|
||||
BdrvChildRole role, BlockReopenQueue *reopen_queue,
|
||||
uint64_t perm, uint64_t shared,
|
||||
uint64_t *nperm, uint64_t *nshared);
|
||||
|
||||
void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
|
||||
bool blk_dev_has_removable_media(BlockBackend *blk);
|
||||
void blk_dev_eject_request(BlockBackend *blk, bool force);
|
||||
bool blk_dev_is_medium_locked(BlockBackend *blk);
|
||||
|
||||
void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup);
|
||||
|
||||
void bdrv_set_monitor_owned(BlockDriverState *bs);
|
||||
|
||||
void blockdev_close_all_bdrv_states(void);
|
||||
|
||||
BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
|
||||
|
||||
/**
|
||||
* Simple implementation of bdrv_co_create_opts for protocol drivers
|
||||
* which only support creation via opening a file
|
||||
* (usually existing raw storage device)
|
||||
*/
|
||||
int coroutine_fn bdrv_co_create_opts_simple(BlockDriver *drv,
|
||||
const char *filename,
|
||||
QemuOpts *opts,
|
||||
Error **errp);
|
||||
|
||||
BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
|
||||
const char *name,
|
||||
BlockDriverState **pbs,
|
||||
Error **errp);
|
||||
BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, const char *target,
|
||||
BlockDirtyBitmapOrStrList *bms,
|
||||
HBitmap **backup, Error **errp);
|
||||
BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
|
||||
bool release,
|
||||
BlockDriverState **bitmap_bs,
|
||||
Error **errp);
|
||||
|
||||
|
||||
BlockDriverState *bdrv_skip_implicit_filters(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* bdrv_add_aio_context_notifier:
|
||||
*
|
||||
* If a long-running job intends to be always run in the same AioContext as a
|
||||
* certain BDS, it may use this function to be notified of changes regarding the
|
||||
* association of the BDS to an AioContext.
|
||||
*
|
||||
* attached_aio_context() is called after the target BDS has been attached to a
|
||||
* new AioContext; detach_aio_context() is called before the target BDS is being
|
||||
* detached from its old AioContext.
|
||||
*/
|
||||
void bdrv_add_aio_context_notifier(BlockDriverState *bs,
|
||||
void (*attached_aio_context)(AioContext *new_context, void *opaque),
|
||||
void (*detach_aio_context)(void *opaque), void *opaque);
|
||||
|
||||
/**
|
||||
* bdrv_remove_aio_context_notifier:
|
||||
*
|
||||
* Unsubscribe of change notifications regarding the BDS's AioContext. The
|
||||
* parameters given here have to be the same as those given to
|
||||
* bdrv_add_aio_context_notifier().
|
||||
*/
|
||||
void bdrv_remove_aio_context_notifier(BlockDriverState *bs,
|
||||
void (*aio_context_attached)(AioContext *,
|
||||
void *),
|
||||
void (*aio_context_detached)(void *),
|
||||
void *opaque);
|
||||
|
||||
/**
|
||||
* End all quiescent sections started by bdrv_drain_all_begin(). This is
|
||||
* needed when deleting a BDS before bdrv_drain_all_end() is called.
|
||||
*
|
||||
* NOTE: this is an internal helper for bdrv_close() *only*. No one else
|
||||
* should call it.
|
||||
*/
|
||||
void bdrv_drain_all_end_quiesce(BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* Make sure that the function is running under both drain and BQL.
|
||||
* The latter protects from concurrent writings
|
||||
* from the GS API, while the former prevents concurrent reads
|
||||
* from I/O.
|
||||
*/
|
||||
static inline void assert_bdrv_graph_writable(BlockDriverState *bs)
|
||||
{
|
||||
/*
|
||||
* TODO: this function is incomplete. Because the users of this
|
||||
* assert lack the necessary drains, check only for BQL.
|
||||
* Once the necessary drains are added,
|
||||
* assert also for qatomic_read(&bs->quiesce_counter) > 0
|
||||
*/
|
||||
assert(qemu_in_main_thread());
|
||||
}
|
||||
|
||||
#endif /* BLOCK_INT_GLOBAL_STATE_H */
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* QEMU System Emulator block driver
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef BLOCK_INT_IO_H
|
||||
#define BLOCK_INT_IO_H
|
||||
|
||||
#include "block_int-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.
|
||||
*/
|
||||
|
||||
int coroutine_fn bdrv_co_preadv_snapshot(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
|
||||
int coroutine_fn bdrv_co_snapshot_block_status(BlockDriverState *bs,
|
||||
bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
|
||||
int64_t *map, BlockDriverState **file);
|
||||
int coroutine_fn bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes);
|
||||
|
||||
|
||||
int coroutine_fn bdrv_co_preadv(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags);
|
||||
int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes,
|
||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
||||
int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes, QEMUIOVector *qiov,
|
||||
BdrvRequestFlags flags);
|
||||
int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes,
|
||||
QEMUIOVector *qiov, size_t qiov_offset, BdrvRequestFlags flags);
|
||||
|
||||
static inline int coroutine_fn bdrv_co_pread(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes, void *buf, BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
IO_CODE();
|
||||
|
||||
return bdrv_co_preadv(child, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
static inline int coroutine_fn bdrv_co_pwrite(BdrvChild *child,
|
||||
int64_t offset, int64_t bytes, const void *buf, BdrvRequestFlags flags)
|
||||
{
|
||||
QEMUIOVector qiov = QEMU_IOVEC_INIT_BUF(qiov, buf, bytes);
|
||||
IO_CODE();
|
||||
|
||||
return bdrv_co_pwritev(child, offset, bytes, &qiov, flags);
|
||||
}
|
||||
|
||||
void coroutine_fn bdrv_make_request_serialising(BdrvTrackedRequest *req,
|
||||
uint64_t align);
|
||||
BdrvTrackedRequest *coroutine_fn bdrv_co_get_self_request(BlockDriverState *bs);
|
||||
|
||||
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
|
||||
const char *filename);
|
||||
|
||||
/**
|
||||
* bdrv_wakeup:
|
||||
* @bs: The BlockDriverState for which an I/O operation has been completed.
|
||||
*
|
||||
* Wake up the main thread if it is waiting on BDRV_POLL_WHILE. During
|
||||
* synchronous I/O on a BlockDriverState that is attached to another
|
||||
* I/O thread, the main thread lets the I/O thread's event loop run,
|
||||
* waiting for the I/O operation to complete. A bdrv_wakeup will wake
|
||||
* up the main thread if necessary.
|
||||
*
|
||||
* Manual calls to bdrv_wakeup are rarely necessary, because
|
||||
* bdrv_dec_in_flight already calls it.
|
||||
*/
|
||||
void bdrv_wakeup(BlockDriverState *bs);
|
||||
|
||||
const char *bdrv_get_parent_name(const BlockDriverState *bs);
|
||||
bool blk_dev_has_tray(BlockBackend *blk);
|
||||
bool blk_dev_is_tray_open(BlockBackend *blk);
|
||||
|
||||
void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes);
|
||||
|
||||
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
|
||||
void bdrv_dirty_bitmap_merge_internal(BdrvDirtyBitmap *dest,
|
||||
const BdrvDirtyBitmap *src,
|
||||
HBitmap **backup, bool lock);
|
||||
|
||||
void bdrv_inc_in_flight(BlockDriverState *bs);
|
||||
void bdrv_dec_in_flight(BlockDriverState *bs);
|
||||
|
||||
int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
|
||||
BdrvChild *dst, int64_t dst_offset,
|
||||
int64_t bytes,
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags);
|
||||
int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
|
||||
BdrvChild *dst, int64_t dst_offset,
|
||||
int64_t bytes,
|
||||
BdrvRequestFlags read_flags,
|
||||
BdrvRequestFlags write_flags);
|
||||
|
||||
int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
|
||||
|
||||
BdrvChild *bdrv_cow_child(BlockDriverState *bs);
|
||||
BdrvChild *bdrv_filter_child(BlockDriverState *bs);
|
||||
BdrvChild *bdrv_filter_or_cow_child(BlockDriverState *bs);
|
||||
BdrvChild *bdrv_primary_child(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_skip_filters(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_backing_chain_next(BlockDriverState *bs);
|
||||
|
||||
static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs)
|
||||
{
|
||||
IO_CODE();
|
||||
return child_bs(bdrv_cow_child(bs));
|
||||
}
|
||||
|
||||
static inline BlockDriverState *bdrv_filter_bs(BlockDriverState *bs)
|
||||
{
|
||||
IO_CODE();
|
||||
return child_bs(bdrv_filter_child(bs));
|
||||
}
|
||||
|
||||
static inline BlockDriverState *bdrv_filter_or_cow_bs(BlockDriverState *bs)
|
||||
{
|
||||
IO_CODE();
|
||||
return child_bs(bdrv_filter_or_cow_child(bs));
|
||||
}
|
||||
|
||||
static inline BlockDriverState *bdrv_primary_bs(BlockDriverState *bs)
|
||||
{
|
||||
IO_CODE();
|
||||
return child_bs(bdrv_primary_child(bs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the given offset is in the cached block-status data
|
||||
* region.
|
||||
*
|
||||
* If it is, and @pnum is not NULL, *pnum is set to
|
||||
* `bsc.data_end - offset`, i.e. how many bytes, starting from
|
||||
* @offset, are data (according to the cache).
|
||||
* Otherwise, *pnum is not touched.
|
||||
*/
|
||||
bool bdrv_bsc_is_data(BlockDriverState *bs, int64_t offset, int64_t *pnum);
|
||||
|
||||
/**
|
||||
* If [offset, offset + bytes) overlaps with the currently cached
|
||||
* block-status region, invalidate the cache.
|
||||
*
|
||||
* (To be used by I/O paths that cause data regions to be zero or
|
||||
* holes.)
|
||||
*/
|
||||
void bdrv_bsc_invalidate_range(BlockDriverState *bs,
|
||||
int64_t offset, int64_t bytes);
|
||||
|
||||
/**
|
||||
* Mark the range [offset, offset + bytes) as a data region.
|
||||
*/
|
||||
void bdrv_bsc_fill(BlockDriverState *bs, int64_t offset, int64_t bytes);
|
||||
|
||||
|
||||
/*
|
||||
* "I/O or GS" API functions. These functions can run without
|
||||
* the BQL, but only in one specific iothread/main loop.
|
||||
*
|
||||
* See include/block/block-io.h for more information about
|
||||
* the "I/O or GS" API.
|
||||
*/
|
||||
|
||||
void bdrv_apply_subtree_drain(BdrvChild *child, BlockDriverState *new_parent);
|
||||
void bdrv_unapply_subtree_drain(BdrvChild *child, BlockDriverState *old_parent);
|
||||
|
||||
#endif /* BLOCK_INT_IO_H */
|
||||
+3
-1409
File diff suppressed because it is too large
Load Diff
+67
-17
@@ -40,24 +40,38 @@ typedef struct BlockJobDriver BlockJobDriver;
|
||||
* Long-running operation on a BlockDriverState.
|
||||
*/
|
||||
typedef struct BlockJob {
|
||||
/** Data belonging to the generic Job infrastructure */
|
||||
/**
|
||||
* Data belonging to the generic Job infrastructure.
|
||||
* Protected by job mutex.
|
||||
*/
|
||||
Job job;
|
||||
|
||||
/** The block device on which the job is operating. */
|
||||
BlockBackend *blk;
|
||||
|
||||
/** Status that is published by the query-block-jobs QMP API */
|
||||
/**
|
||||
* Status that is published by the query-block-jobs QMP API.
|
||||
* Protected by job mutex.
|
||||
*/
|
||||
BlockDeviceIoStatus iostatus;
|
||||
|
||||
/** Speed that was set with @block_job_set_speed. */
|
||||
/**
|
||||
* Speed that was set with @block_job_set_speed.
|
||||
* Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE).
|
||||
*/
|
||||
int64_t speed;
|
||||
|
||||
/** Rate limiting data structure for implementing @speed. */
|
||||
/**
|
||||
* Rate limiting data structure for implementing @speed.
|
||||
* RateLimit API is thread-safe.
|
||||
*/
|
||||
RateLimit limit;
|
||||
|
||||
/** Block other operations when block job is running */
|
||||
/**
|
||||
* Block other operations when block job is running.
|
||||
* Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE).
|
||||
*/
|
||||
Error *blocker;
|
||||
|
||||
/** All notifiers are set once in block_job_create() and never modified. */
|
||||
|
||||
/** Called when a cancelled job is finalised. */
|
||||
Notifier finalize_cancelled_notifier;
|
||||
|
||||
@@ -73,20 +87,31 @@ typedef struct BlockJob {
|
||||
/** Called when the job coroutine yields or terminates */
|
||||
Notifier idle_notifier;
|
||||
|
||||
/** BlockDriverStates that are involved in this block job */
|
||||
/**
|
||||
* BlockDriverStates that are involved in this block job.
|
||||
* Always modified and read under QEMU global mutex (GLOBAL_STATE_CODE).
|
||||
*/
|
||||
GSList *nodes;
|
||||
} BlockJob;
|
||||
|
||||
/*
|
||||
* Global state (GS) API. These functions run under the BQL.
|
||||
*
|
||||
* See include/block/block-global-state.h for more information about
|
||||
* the GS API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* block_job_next:
|
||||
* block_job_next_locked:
|
||||
* @job: A block job, or %NULL.
|
||||
*
|
||||
* Get the next element from the list of block jobs after @job, or the
|
||||
* first one if @job is %NULL.
|
||||
*
|
||||
* Returns the requested job, or %NULL if there are no more jobs left.
|
||||
* Called with job lock held.
|
||||
*/
|
||||
BlockJob *block_job_next(BlockJob *job);
|
||||
BlockJob *block_job_next_locked(BlockJob *job);
|
||||
|
||||
/**
|
||||
* block_job_get:
|
||||
@@ -95,9 +120,13 @@ BlockJob *block_job_next(BlockJob *job);
|
||||
* Get the block job identified by @id (which must not be %NULL).
|
||||
*
|
||||
* Returns the requested job, or %NULL if it doesn't exist.
|
||||
* Called with job lock *not* held.
|
||||
*/
|
||||
BlockJob *block_job_get(const char *id);
|
||||
|
||||
/* Same as block_job_get(), but called with job lock held. */
|
||||
BlockJob *block_job_get_locked(const char *id);
|
||||
|
||||
/**
|
||||
* block_job_add_bdrv:
|
||||
* @job: A block job
|
||||
@@ -131,32 +160,53 @@ void block_job_remove_all_bdrv(BlockJob *job);
|
||||
bool block_job_has_bdrv(BlockJob *job, BlockDriverState *bs);
|
||||
|
||||
/**
|
||||
* block_job_set_speed:
|
||||
* block_job_set_speed_locked:
|
||||
* @job: The job to set the speed for.
|
||||
* @speed: The new value
|
||||
* @errp: Error object.
|
||||
*
|
||||
* Set a rate-limiting parameter for the job; the actual meaning may
|
||||
* vary depending on the job type.
|
||||
*
|
||||
* Called with job lock held, but might release it temporarily.
|
||||
*/
|
||||
bool block_job_set_speed(BlockJob *job, int64_t speed, Error **errp);
|
||||
bool block_job_set_speed_locked(BlockJob *job, int64_t speed, Error **errp);
|
||||
|
||||
/**
|
||||
* block_job_query:
|
||||
* block_job_query_locked:
|
||||
* @job: The job to get information about.
|
||||
*
|
||||
* Return information about a job.
|
||||
*
|
||||
* Called with job lock held.
|
||||
*/
|
||||
BlockJobInfo *block_job_query(BlockJob *job, Error **errp);
|
||||
BlockJobInfo *block_job_query_locked(BlockJob *job, Error **errp);
|
||||
|
||||
/**
|
||||
* block_job_iostatus_reset:
|
||||
* block_job_iostatus_reset_locked:
|
||||
* @job: The job whose I/O status should be reset.
|
||||
*
|
||||
* Reset I/O status on @job and on BlockDriverState objects it uses,
|
||||
* other than job->blk.
|
||||
*
|
||||
* Called with job lock held.
|
||||
*/
|
||||
void block_job_iostatus_reset_locked(BlockJob *job);
|
||||
|
||||
/*
|
||||
* block_job_get_aio_context:
|
||||
*
|
||||
* Returns aio context associated with a block job.
|
||||
*/
|
||||
AioContext *block_job_get_aio_context(BlockJob *job);
|
||||
|
||||
|
||||
/*
|
||||
* Common functions that are neither I/O nor Global State.
|
||||
*
|
||||
* See include/block/block-common.h for more information about
|
||||
* the Common API.
|
||||
*/
|
||||
void block_job_iostatus_reset(BlockJob *job);
|
||||
|
||||
/**
|
||||
* block_job_is_internal:
|
||||
|
||||
@@ -38,6 +38,13 @@ struct BlockJobDriver {
|
||||
/** Generic JobDriver callbacks and settings */
|
||||
JobDriver job_driver;
|
||||
|
||||
/*
|
||||
* I/O API functions. These functions are thread-safe.
|
||||
*
|
||||
* See include/block/block-io.h for more information about
|
||||
* the I/O API.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns whether the job has pending requests for the child or will
|
||||
* submit new requests before the next pause point. This callback is polled
|
||||
@@ -46,6 +53,13 @@ struct BlockJobDriver {
|
||||
*/
|
||||
bool (*drained_poll)(BlockJob *job);
|
||||
|
||||
/*
|
||||
* Global state (GS) API. These functions run under the BQL.
|
||||
*
|
||||
* See include/block/block-global-state.h for more information about
|
||||
* the GS API.
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the callback is not NULL, it will be invoked before the job is
|
||||
* resumed in a new AioContext. This is the place to move any resources
|
||||
@@ -56,6 +70,13 @@ struct BlockJobDriver {
|
||||
void (*set_speed)(BlockJob *job, int64_t speed);
|
||||
};
|
||||
|
||||
/*
|
||||
* Global state (GS) API. These functions run under the BQL.
|
||||
*
|
||||
* See include/block/block-global-state.h for more information about
|
||||
* the GS API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* block_job_create:
|
||||
* @job_id: The id of the newly-created job, or %NULL to have one
|
||||
@@ -98,6 +119,13 @@ void block_job_free(Job *job);
|
||||
*/
|
||||
void block_job_user_resume(Job *job);
|
||||
|
||||
/*
|
||||
* I/O API functions. These functions are thread-safe.
|
||||
*
|
||||
* See include/block/block-io.h for more information about
|
||||
* the I/O API.
|
||||
*/
|
||||
|
||||
/**
|
||||
* block_job_ratelimit_get_delay:
|
||||
*
|
||||
|
||||
@@ -77,7 +77,7 @@ void bdrv_dirty_bitmap_set_persistence(BdrvDirtyBitmap *bitmap,
|
||||
bool persistent);
|
||||
void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap);
|
||||
void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy);
|
||||
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
||||
bool bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
||||
HBitmap **backup, Error **errp);
|
||||
void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip);
|
||||
bool bdrv_dirty_bitmap_get(BdrvDirtyBitmap *bitmap, int64_t offset);
|
||||
@@ -115,6 +115,8 @@ int64_t bdrv_dirty_bitmap_next_zero(BdrvDirtyBitmap *bitmap, int64_t offset,
|
||||
bool bdrv_dirty_bitmap_next_dirty_area(BdrvDirtyBitmap *bitmap,
|
||||
int64_t start, int64_t end, int64_t max_dirty_count,
|
||||
int64_t *dirty_start, int64_t *dirty_count);
|
||||
bool bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap, int64_t offset,
|
||||
int64_t bytes, int64_t *count);
|
||||
BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap_locked(BdrvDirtyBitmap *bitmap,
|
||||
Error **errp);
|
||||
|
||||
|
||||
+6
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2020 Red Hat, Inc.
|
||||
* Copyright (C) 2016-2022 Red Hat, Inc.
|
||||
* Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws>
|
||||
*
|
||||
* Network Block Device
|
||||
@@ -344,8 +344,9 @@ void nbd_client_new(QIOChannelSocket *sioc,
|
||||
void nbd_client_get(NBDClient *client);
|
||||
void nbd_client_put(NBDClient *client);
|
||||
|
||||
void nbd_server_is_qemu_nbd(bool value);
|
||||
void nbd_server_is_qemu_nbd(int max_connections);
|
||||
bool nbd_server_is_running(void);
|
||||
int nbd_server_max_connections(void);
|
||||
void nbd_server_start(SocketAddress *addr, const char *tls_creds,
|
||||
const char *tls_authz, uint32_t max_connections,
|
||||
Error **errp);
|
||||
@@ -415,13 +416,14 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
|
||||
bool do_negotiation,
|
||||
const char *export_name,
|
||||
const char *x_dirty_bitmap,
|
||||
QCryptoTLSCreds *tlscreds);
|
||||
QCryptoTLSCreds *tlscreds,
|
||||
const char *tlshostname);
|
||||
void nbd_client_connection_release(NBDClientConnection *conn);
|
||||
|
||||
QIOChannel *coroutine_fn
|
||||
nbd_co_establish_connection(NBDClientConnection *conn, NBDExportInfo *info,
|
||||
bool blocking, Error **errp);
|
||||
|
||||
void coroutine_fn nbd_co_establish_connection_cancel(NBDClientConnection *conn);
|
||||
void nbd_co_establish_connection_cancel(NBDClientConnection *conn);
|
||||
|
||||
#endif
|
||||
|
||||
+200
-37
@@ -98,28 +98,28 @@ enum NvmeCapMask {
|
||||
#define NVME_CAP_PMRS(cap) (((cap) >> CAP_PMRS_SHIFT) & CAP_PMRS_MASK)
|
||||
#define NVME_CAP_CMBS(cap) (((cap) >> CAP_CMBS_SHIFT) & CAP_CMBS_MASK)
|
||||
|
||||
#define NVME_CAP_SET_MQES(cap, val) (cap |= (uint64_t)(val & CAP_MQES_MASK) \
|
||||
<< CAP_MQES_SHIFT)
|
||||
#define NVME_CAP_SET_CQR(cap, val) (cap |= (uint64_t)(val & CAP_CQR_MASK) \
|
||||
<< CAP_CQR_SHIFT)
|
||||
#define NVME_CAP_SET_AMS(cap, val) (cap |= (uint64_t)(val & CAP_AMS_MASK) \
|
||||
<< CAP_AMS_SHIFT)
|
||||
#define NVME_CAP_SET_TO(cap, val) (cap |= (uint64_t)(val & CAP_TO_MASK) \
|
||||
<< CAP_TO_SHIFT)
|
||||
#define NVME_CAP_SET_DSTRD(cap, val) (cap |= (uint64_t)(val & CAP_DSTRD_MASK) \
|
||||
<< CAP_DSTRD_SHIFT)
|
||||
#define NVME_CAP_SET_NSSRS(cap, val) (cap |= (uint64_t)(val & CAP_NSSRS_MASK) \
|
||||
<< CAP_NSSRS_SHIFT)
|
||||
#define NVME_CAP_SET_CSS(cap, val) (cap |= (uint64_t)(val & CAP_CSS_MASK) \
|
||||
<< CAP_CSS_SHIFT)
|
||||
#define NVME_CAP_SET_MPSMIN(cap, val) (cap |= (uint64_t)(val & CAP_MPSMIN_MASK)\
|
||||
<< CAP_MPSMIN_SHIFT)
|
||||
#define NVME_CAP_SET_MPSMAX(cap, val) (cap |= (uint64_t)(val & CAP_MPSMAX_MASK)\
|
||||
<< CAP_MPSMAX_SHIFT)
|
||||
#define NVME_CAP_SET_PMRS(cap, val) (cap |= (uint64_t)(val & CAP_PMRS_MASK) \
|
||||
<< CAP_PMRS_SHIFT)
|
||||
#define NVME_CAP_SET_CMBS(cap, val) (cap |= (uint64_t)(val & CAP_CMBS_MASK) \
|
||||
<< CAP_CMBS_SHIFT)
|
||||
#define NVME_CAP_SET_MQES(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_MQES_MASK) << CAP_MQES_SHIFT)
|
||||
#define NVME_CAP_SET_CQR(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_CQR_MASK) << CAP_CQR_SHIFT)
|
||||
#define NVME_CAP_SET_AMS(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_AMS_MASK) << CAP_AMS_SHIFT)
|
||||
#define NVME_CAP_SET_TO(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_TO_MASK) << CAP_TO_SHIFT)
|
||||
#define NVME_CAP_SET_DSTRD(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_DSTRD_MASK) << CAP_DSTRD_SHIFT)
|
||||
#define NVME_CAP_SET_NSSRS(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_NSSRS_MASK) << CAP_NSSRS_SHIFT)
|
||||
#define NVME_CAP_SET_CSS(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_CSS_MASK) << CAP_CSS_SHIFT)
|
||||
#define NVME_CAP_SET_MPSMIN(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_MPSMIN_MASK) << CAP_MPSMIN_SHIFT)
|
||||
#define NVME_CAP_SET_MPSMAX(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_MPSMAX_MASK) << CAP_MPSMAX_SHIFT)
|
||||
#define NVME_CAP_SET_PMRS(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_PMRS_MASK) << CAP_PMRS_SHIFT)
|
||||
#define NVME_CAP_SET_CMBS(cap, val) \
|
||||
((cap) |= (uint64_t)((val) & CAP_CMBS_MASK) << CAP_CMBS_SHIFT)
|
||||
|
||||
enum NvmeCapCss {
|
||||
NVME_CAP_CSS_NVM = 1 << 0,
|
||||
@@ -595,6 +595,8 @@ enum NvmeAdminCommands {
|
||||
NVME_ADM_CMD_ACTIVATE_FW = 0x10,
|
||||
NVME_ADM_CMD_DOWNLOAD_FW = 0x11,
|
||||
NVME_ADM_CMD_NS_ATTACHMENT = 0x15,
|
||||
NVME_ADM_CMD_VIRT_MNGMT = 0x1c,
|
||||
NVME_ADM_CMD_DBBUF_CONFIG = 0x7c,
|
||||
NVME_ADM_CMD_FORMAT_NVM = 0x80,
|
||||
NVME_ADM_CMD_SECURITY_SEND = 0x81,
|
||||
NVME_ADM_CMD_SECURITY_RECV = 0x82,
|
||||
@@ -695,7 +697,8 @@ typedef struct QEMU_PACKED NvmeRwCmd {
|
||||
uint8_t flags;
|
||||
uint16_t cid;
|
||||
uint32_t nsid;
|
||||
uint64_t rsvd2;
|
||||
uint32_t cdw2;
|
||||
uint32_t cdw3;
|
||||
uint64_t mptr;
|
||||
NvmeCmdDptr dptr;
|
||||
uint64_t slba;
|
||||
@@ -731,7 +734,6 @@ enum {
|
||||
NVME_RW_PRINFO_PRCHK_APP = 1 << 11,
|
||||
NVME_RW_PRINFO_PRCHK_REF = 1 << 10,
|
||||
NVME_RW_PRINFO_PRCHK_MASK = 7 << 10,
|
||||
|
||||
};
|
||||
|
||||
#define NVME_RW_PRINFO(control) ((control >> 10) & 0xf)
|
||||
@@ -770,6 +772,7 @@ typedef struct QEMU_PACKED NvmeDsmRange {
|
||||
|
||||
enum {
|
||||
NVME_COPY_FORMAT_0 = 0x0,
|
||||
NVME_COPY_FORMAT_1 = 0x1,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeCopyCmd {
|
||||
@@ -777,7 +780,9 @@ typedef struct QEMU_PACKED NvmeCopyCmd {
|
||||
uint8_t flags;
|
||||
uint16_t cid;
|
||||
uint32_t nsid;
|
||||
uint32_t rsvd2[4];
|
||||
uint32_t cdw2;
|
||||
uint32_t cdw3;
|
||||
uint32_t rsvd2[2];
|
||||
NvmeCmdDptr dptr;
|
||||
uint64_t sdlba;
|
||||
uint8_t nr;
|
||||
@@ -789,7 +794,7 @@ typedef struct QEMU_PACKED NvmeCopyCmd {
|
||||
uint16_t appmask;
|
||||
} NvmeCopyCmd;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeCopySourceRange {
|
||||
typedef struct QEMU_PACKED NvmeCopySourceRangeFormat0 {
|
||||
uint8_t rsvd0[8];
|
||||
uint64_t slba;
|
||||
uint16_t nlb;
|
||||
@@ -797,7 +802,17 @@ typedef struct QEMU_PACKED NvmeCopySourceRange {
|
||||
uint32_t reftag;
|
||||
uint16_t apptag;
|
||||
uint16_t appmask;
|
||||
} NvmeCopySourceRange;
|
||||
} NvmeCopySourceRangeFormat0;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeCopySourceRangeFormat1 {
|
||||
uint8_t rsvd0[8];
|
||||
uint64_t slba;
|
||||
uint16_t nlb;
|
||||
uint8_t rsvd18[8];
|
||||
uint8_t sr[10];
|
||||
uint16_t apptag;
|
||||
uint16_t appmask;
|
||||
} NvmeCopySourceRangeFormat1;
|
||||
|
||||
enum NvmeAsyncEventRequest {
|
||||
NVME_AER_TYPE_ERROR = 0,
|
||||
@@ -886,10 +901,16 @@ enum NvmeStatusCodes {
|
||||
NVME_NS_PRIVATE = 0x0119,
|
||||
NVME_NS_NOT_ATTACHED = 0x011a,
|
||||
NVME_NS_CTRL_LIST_INVALID = 0x011c,
|
||||
NVME_INVALID_CTRL_ID = 0x011f,
|
||||
NVME_INVALID_SEC_CTRL_STATE = 0x0120,
|
||||
NVME_INVALID_NUM_RESOURCES = 0x0121,
|
||||
NVME_INVALID_RESOURCE_ID = 0x0122,
|
||||
NVME_CONFLICTING_ATTRS = 0x0180,
|
||||
NVME_INVALID_PROT_INFO = 0x0181,
|
||||
NVME_WRITE_TO_RO = 0x0182,
|
||||
NVME_CMD_SIZE_LIMIT = 0x0183,
|
||||
NVME_INVALID_ZONE_OP = 0x01b6,
|
||||
NVME_NOZRWA = 0x01b7,
|
||||
NVME_ZONE_BOUNDARY_ERROR = 0x01b8,
|
||||
NVME_ZONE_FULL = 0x01b9,
|
||||
NVME_ZONE_READ_ONLY = 0x01ba,
|
||||
@@ -906,6 +927,7 @@ enum NvmeStatusCodes {
|
||||
NVME_CMP_FAILURE = 0x0285,
|
||||
NVME_ACCESS_DENIED = 0x0286,
|
||||
NVME_DULB = 0x0287,
|
||||
NVME_E2E_STORAGE_TAG_ERROR = 0x0288,
|
||||
NVME_MORE = 0x2000,
|
||||
NVME_DNR = 0x4000,
|
||||
NVME_NO_COMPLETE = 0xffff,
|
||||
@@ -1017,6 +1039,8 @@ enum NvmeIdCns {
|
||||
NVME_ID_CNS_NS_PRESENT = 0x11,
|
||||
NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
|
||||
NVME_ID_CNS_CTRL_LIST = 0x13,
|
||||
NVME_ID_CNS_PRIMARY_CTRL_CAP = 0x14,
|
||||
NVME_ID_CNS_SECONDARY_CTRL_LIST = 0x15,
|
||||
NVME_ID_CNS_CS_NS_PRESENT_LIST = 0x1a,
|
||||
NVME_ID_CNS_CS_NS_PRESENT = 0x1b,
|
||||
NVME_ID_CNS_IO_COMMAND_SET = 0x1c,
|
||||
@@ -1109,11 +1133,16 @@ enum NvmeIdCtrlOaes {
|
||||
NVME_OAES_NS_ATTR = 1 << 8,
|
||||
};
|
||||
|
||||
enum NvmeIdCtrlCtratt {
|
||||
NVME_CTRATT_ELBAS = 1 << 15,
|
||||
};
|
||||
|
||||
enum NvmeIdCtrlOacs {
|
||||
NVME_OACS_SECURITY = 1 << 0,
|
||||
NVME_OACS_FORMAT = 1 << 1,
|
||||
NVME_OACS_FW = 1 << 2,
|
||||
NVME_OACS_NS_MGMT = 1 << 3,
|
||||
NVME_OACS_DBBUF = 1 << 8,
|
||||
};
|
||||
|
||||
enum NvmeIdCtrlOncs {
|
||||
@@ -1129,7 +1158,8 @@ enum NvmeIdCtrlOncs {
|
||||
};
|
||||
|
||||
enum NvmeIdCtrlOcfs {
|
||||
NVME_OCFS_COPY_FORMAT_0 = 1 << 0,
|
||||
NVME_OCFS_COPY_FORMAT_0 = 1 << NVME_COPY_FORMAT_0,
|
||||
NVME_OCFS_COPY_FORMAT_1 = 1 << NVME_COPY_FORMAT_1,
|
||||
};
|
||||
|
||||
enum NvmeIdctrlVwc {
|
||||
@@ -1154,6 +1184,11 @@ enum NvmeIdCtrlCmic {
|
||||
NVME_CMIC_MULTI_CTRL = 1 << 1,
|
||||
};
|
||||
|
||||
enum NvmeNsAttachmentOperation {
|
||||
NVME_NS_ATTACHMENT_ATTACH = 0x0,
|
||||
NVME_NS_ATTACHMENT_DETACH = 0x1,
|
||||
};
|
||||
|
||||
#define NVME_CTRL_SQES_MIN(sqes) ((sqes) & 0xf)
|
||||
#define NVME_CTRL_SQES_MAX(sqes) (((sqes) >> 4) & 0xf)
|
||||
#define NVME_CTRL_CQES_MIN(cqes) ((cqes) & 0xf)
|
||||
@@ -1209,6 +1244,7 @@ enum NvmeFeatureIds {
|
||||
NVME_WRITE_ATOMICITY = 0xa,
|
||||
NVME_ASYNCHRONOUS_EVENT_CONF = 0xb,
|
||||
NVME_TIMESTAMP = 0xe,
|
||||
NVME_HOST_BEHAVIOR_SUPPORT = 0x16,
|
||||
NVME_COMMAND_SET_PROFILE = 0x19,
|
||||
NVME_SOFTWARE_PROGRESS_MARKER = 0x80,
|
||||
NVME_FID_MAX = 0x100,
|
||||
@@ -1250,6 +1286,13 @@ typedef struct QEMU_PACKED NvmeRangeType {
|
||||
uint8_t rsvd48[16];
|
||||
} NvmeRangeType;
|
||||
|
||||
typedef struct NvmeHostBehaviorSupport {
|
||||
uint8_t acre;
|
||||
uint8_t etdas;
|
||||
uint8_t lbafee;
|
||||
uint8_t rsvd3[509];
|
||||
} NvmeHostBehaviorSupport;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeLBAF {
|
||||
uint16_t ms;
|
||||
uint8_t ds;
|
||||
@@ -1263,6 +1306,7 @@ typedef struct QEMU_PACKED NvmeLBAFE {
|
||||
} NvmeLBAFE;
|
||||
|
||||
#define NVME_NSID_BROADCAST 0xffffffff
|
||||
#define NVME_MAX_NLBAF 64
|
||||
|
||||
typedef struct QEMU_PACKED NvmeIdNs {
|
||||
uint64_t nsze;
|
||||
@@ -1297,11 +1341,20 @@ typedef struct QEMU_PACKED NvmeIdNs {
|
||||
uint8_t rsvd81[23];
|
||||
uint8_t nguid[16];
|
||||
uint64_t eui64;
|
||||
NvmeLBAF lbaf[16];
|
||||
uint8_t rsvd192[192];
|
||||
NvmeLBAF lbaf[NVME_MAX_NLBAF];
|
||||
uint8_t vs[3712];
|
||||
} NvmeIdNs;
|
||||
|
||||
#define NVME_ID_NS_NVM_ELBAF_PIF(elbaf) (((elbaf) >> 7) & 0x3)
|
||||
|
||||
typedef struct QEMU_PACKED NvmeIdNsNvm {
|
||||
uint64_t lbstm;
|
||||
uint8_t pic;
|
||||
uint8_t rsvd9[3];
|
||||
uint32_t elbaf[NVME_MAX_NLBAF];
|
||||
uint8_t rsvd268[3828];
|
||||
} NvmeIdNsNvm;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeIdNsDescr {
|
||||
uint8_t nidt;
|
||||
uint8_t nidl;
|
||||
@@ -1340,12 +1393,26 @@ typedef struct QEMU_PACKED NvmeIdNsZoned {
|
||||
uint32_t mor;
|
||||
uint32_t rrl;
|
||||
uint32_t frl;
|
||||
uint8_t rsvd20[2796];
|
||||
uint8_t rsvd12[24];
|
||||
uint32_t numzrwa;
|
||||
uint16_t zrwafg;
|
||||
uint16_t zrwas;
|
||||
uint8_t zrwacap;
|
||||
uint8_t rsvd53[2763];
|
||||
NvmeLBAFE lbafe[16];
|
||||
uint8_t rsvd3072[768];
|
||||
uint8_t vs[256];
|
||||
} NvmeIdNsZoned;
|
||||
|
||||
enum NvmeIdNsZonedOzcs {
|
||||
NVME_ID_NS_ZONED_OZCS_RAZB = 1 << 0,
|
||||
NVME_ID_NS_ZONED_OZCS_ZRWASUP = 1 << 1,
|
||||
};
|
||||
|
||||
enum NvmeIdNsZonedZrwacap {
|
||||
NVME_ID_NS_ZONED_ZRWACAP_EXPFLUSHSUP = 1 << 0,
|
||||
};
|
||||
|
||||
/*Deallocate Logical Block Features*/
|
||||
#define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat) ((dlfeat) & 0x10)
|
||||
#define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat) ((dlfeat) & 0x08)
|
||||
@@ -1389,16 +1456,30 @@ enum NvmeIdNsMc {
|
||||
|
||||
#define NVME_ID_NS_DPS_TYPE(dps) (dps & NVME_ID_NS_DPS_TYPE_MASK)
|
||||
|
||||
typedef struct NvmeDifTuple {
|
||||
uint16_t guard;
|
||||
uint16_t apptag;
|
||||
uint32_t reftag;
|
||||
enum NvmePIFormat {
|
||||
NVME_PI_GUARD_16 = 0,
|
||||
NVME_PI_GUARD_64 = 2,
|
||||
};
|
||||
|
||||
typedef union NvmeDifTuple {
|
||||
struct {
|
||||
uint16_t guard;
|
||||
uint16_t apptag;
|
||||
uint32_t reftag;
|
||||
} g16;
|
||||
|
||||
struct {
|
||||
uint64_t guard;
|
||||
uint16_t apptag;
|
||||
uint8_t sr[6];
|
||||
} g64;
|
||||
} NvmeDifTuple;
|
||||
|
||||
enum NvmeZoneAttr {
|
||||
NVME_ZA_FINISHED_BY_CTLR = 1 << 0,
|
||||
NVME_ZA_FINISH_RECOMMENDED = 1 << 1,
|
||||
NVME_ZA_RESET_RECOMMENDED = 1 << 2,
|
||||
NVME_ZA_ZRWA_VALID = 1 << 3,
|
||||
NVME_ZA_ZD_EXT_VALID = 1 << 7,
|
||||
};
|
||||
|
||||
@@ -1428,6 +1509,21 @@ enum NvmeZoneType {
|
||||
NVME_ZONE_TYPE_SEQ_WRITE = 0x02,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeZoneSendCmd {
|
||||
uint8_t opcode;
|
||||
uint8_t flags;
|
||||
uint16_t cid;
|
||||
uint32_t nsid;
|
||||
uint32_t rsvd8[4];
|
||||
NvmeCmdDptr dptr;
|
||||
uint64_t slba;
|
||||
uint32_t rsvd48;
|
||||
uint8_t zsa;
|
||||
uint8_t zsflags;
|
||||
uint8_t rsvd54[2];
|
||||
uint32_t rsvd56[2];
|
||||
} NvmeZoneSendCmd;
|
||||
|
||||
enum NvmeZoneSendAction {
|
||||
NVME_ZONE_ACTION_RSD = 0x00,
|
||||
NVME_ZONE_ACTION_CLOSE = 0x01,
|
||||
@@ -1436,6 +1532,12 @@ enum NvmeZoneSendAction {
|
||||
NVME_ZONE_ACTION_RESET = 0x04,
|
||||
NVME_ZONE_ACTION_OFFLINE = 0x05,
|
||||
NVME_ZONE_ACTION_SET_ZD_EXT = 0x10,
|
||||
NVME_ZONE_ACTION_ZRWA_FLUSH = 0x11,
|
||||
};
|
||||
|
||||
enum {
|
||||
NVME_ZSFLAG_SELECT_ALL = 1 << 0,
|
||||
NVME_ZSFLAG_ZRWA_ALLOC = 1 << 1,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeZoneDescr {
|
||||
@@ -1460,6 +1562,61 @@ typedef enum NvmeZoneState {
|
||||
NVME_ZONE_STATE_OFFLINE = 0x0f,
|
||||
} NvmeZoneState;
|
||||
|
||||
typedef struct QEMU_PACKED NvmePriCtrlCap {
|
||||
uint16_t cntlid;
|
||||
uint16_t portid;
|
||||
uint8_t crt;
|
||||
uint8_t rsvd5[27];
|
||||
uint32_t vqfrt;
|
||||
uint32_t vqrfa;
|
||||
uint16_t vqrfap;
|
||||
uint16_t vqprt;
|
||||
uint16_t vqfrsm;
|
||||
uint16_t vqgran;
|
||||
uint8_t rsvd48[16];
|
||||
uint32_t vifrt;
|
||||
uint32_t virfa;
|
||||
uint16_t virfap;
|
||||
uint16_t viprt;
|
||||
uint16_t vifrsm;
|
||||
uint16_t vigran;
|
||||
uint8_t rsvd80[4016];
|
||||
} NvmePriCtrlCap;
|
||||
|
||||
typedef enum NvmePriCtrlCapCrt {
|
||||
NVME_CRT_VQ = 1 << 0,
|
||||
NVME_CRT_VI = 1 << 1,
|
||||
} NvmePriCtrlCapCrt;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeSecCtrlEntry {
|
||||
uint16_t scid;
|
||||
uint16_t pcid;
|
||||
uint8_t scs;
|
||||
uint8_t rsvd5[3];
|
||||
uint16_t vfn;
|
||||
uint16_t nvq;
|
||||
uint16_t nvi;
|
||||
uint8_t rsvd14[18];
|
||||
} NvmeSecCtrlEntry;
|
||||
|
||||
typedef struct QEMU_PACKED NvmeSecCtrlList {
|
||||
uint8_t numcntl;
|
||||
uint8_t rsvd1[31];
|
||||
NvmeSecCtrlEntry sec[127];
|
||||
} NvmeSecCtrlList;
|
||||
|
||||
typedef enum NvmeVirtMngmtAction {
|
||||
NVME_VIRT_MNGMT_ACTION_PRM_ALLOC = 0x01,
|
||||
NVME_VIRT_MNGMT_ACTION_SEC_OFFLINE = 0x07,
|
||||
NVME_VIRT_MNGMT_ACTION_SEC_ASSIGN = 0x08,
|
||||
NVME_VIRT_MNGMT_ACTION_SEC_ONLINE = 0x09,
|
||||
} NvmeVirtMngmtAction;
|
||||
|
||||
typedef enum NvmeVirtualResourceType {
|
||||
NVME_VIRT_RES_QUEUE = 0x00,
|
||||
NVME_VIRT_RES_INTERRUPT = 0x01,
|
||||
} NvmeVirtualResourceType;
|
||||
|
||||
static inline void _nvme_check_size(void)
|
||||
{
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096);
|
||||
@@ -1467,7 +1624,8 @@ static inline void _nvme_check_size(void)
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeZonedResult) != 8);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRange) != 32);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat0) != 32);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat1) != 40);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) != 64);
|
||||
@@ -1477,6 +1635,7 @@ static inline void _nvme_check_size(void)
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeDsmCmd) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeCopyCmd) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeRangeType) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeHostBehaviorSupport) != 512);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
|
||||
@@ -1487,10 +1646,14 @@ static inline void _nvme_check_size(void)
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsNvm) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsZoned) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsDescr) != 4);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeZoneDescr) != 64);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeDifTuple) != 8);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeDifTuple) != 16);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmePriCtrlCap) != 4096);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSecCtrlEntry) != 32);
|
||||
QEMU_BUILD_BUG_ON(sizeof(NvmeSecCtrlList) != 4096);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
#include "qapi/qmp/qdict.h"
|
||||
|
||||
QObject *qdict_crumple(const QDict *src, Error **errp);
|
||||
void qdict_flatten(QDict *qdict);
|
||||
|
||||
void qdict_copy_default(QDict *dst, QDict *src, const char *key);
|
||||
void qdict_set_default_str(QDict *dst, const char *key, const char *val);
|
||||
|
||||
|
||||
@@ -51,11 +51,13 @@ typedef struct LinuxAioState LinuxAioState;
|
||||
LinuxAioState *laio_init(Error **errp);
|
||||
void laio_cleanup(LinuxAioState *s);
|
||||
int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,
|
||||
uint64_t offset, QEMUIOVector *qiov, int type);
|
||||
uint64_t offset, QEMUIOVector *qiov, int type,
|
||||
uint64_t dev_max_batch);
|
||||
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
|
||||
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context);
|
||||
void laio_io_plug(BlockDriverState *bs, LinuxAioState *s);
|
||||
void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s);
|
||||
void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s,
|
||||
uint64_t dev_max_batch);
|
||||
#endif
|
||||
/* io_uring.c - Linux io_uring implementation */
|
||||
#ifdef CONFIG_LINUX_IO_URING
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user