aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/block/block.h9
-rw-r--r--include/block/block_int.h28
-rw-r--r--include/block/blockjob.h32
-rw-r--r--include/block/blockjob_int.h11
-rw-r--r--include/block/raw-aio.h2
-rw-r--r--include/qemu/log.h1
6 files changed, 70 insertions, 13 deletions
diff --git a/include/block/block.h b/include/block/block.h
index cdec3639a3..3894edda9d 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -54,8 +54,12 @@ typedef enum {
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,
+
/* Mask of valid flags */
- BDRV_REQ_MASK = 0x3f,
+ BDRV_REQ_MASK = 0x7f,
} BdrvRequestFlags;
typedef struct BlockSizes {
@@ -205,6 +209,9 @@ enum {
* 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,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index c4dd1d4bb8..76b589da57 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -141,11 +141,11 @@ struct BlockDriver {
void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options);
/* aio */
- BlockAIOCB *(*bdrv_aio_readv)(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ BlockAIOCB *(*bdrv_aio_preadv)(BlockDriverState *bs,
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb, void *opaque);
- BlockAIOCB *(*bdrv_aio_writev)(BlockDriverState *bs,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ BlockAIOCB *(*bdrv_aio_pwritev)(BlockDriverState *bs,
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags,
BlockCompletionFunc *cb, void *opaque);
BlockAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
BlockCompletionFunc *cb, void *opaque);
@@ -174,8 +174,6 @@ struct BlockDriver {
int coroutine_fn (*bdrv_co_preadv)(BlockDriverState *bs,
uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags);
int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
- int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
- int coroutine_fn (*bdrv_co_writev_flags)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int flags);
/**
* @offset: position in bytes to write at
@@ -658,10 +656,24 @@ struct BlockDriverState {
/* I/O Limits */
BlockLimits bl;
- /* Flags honored during pwrite (so far: BDRV_REQ_FUA) */
+ /* Flags honored during pwrite (so far: BDRV_REQ_FUA,
+ * BDRV_REQ_WRITE_UNCHANGED).
+ * If a driver does not support BDRV_REQ_WRITE_UNCHANGED, those
+ * writes will be issued as normal writes without the flag set.
+ * This is important to note for drivers that do not explicitly
+ * request a WRITE permission for their children and instead take
+ * the same permissions as their parent did (this is commonly what
+ * block filters do). Such drivers have to be aware that the
+ * parent may have taken a WRITE_UNCHANGED permission only and is
+ * issuing such requests. Drivers either must make sure that
+ * these requests do not result in plain WRITE accesses (usually
+ * by supporting BDRV_REQ_WRITE_UNCHANGED, and then forwarding
+ * every incoming write request as-is, including potentially that
+ * flag), or they have to explicitly take the WRITE permission for
+ * their children. */
unsigned int supported_write_flags;
/* Flags honored during pwrite_zeroes (so far: BDRV_REQ_FUA,
- * BDRV_REQ_MAY_UNMAP) */
+ * BDRV_REQ_MAY_UNMAP, BDRV_REQ_WRITE_UNCHANGED) */
unsigned int supported_zero_flags;
/* the following member gives a name to every node on the bs graph. */
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index fc645dac68..0f56f723de 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -27,6 +27,9 @@
#define BLOCKJOB_H
#include "block/block.h"
+#include "qemu/ratelimit.h"
+
+#define BLOCK_JOB_SLICE_TIME 100000000ULL /* ns */
typedef struct BlockJobDriver BlockJobDriver;
typedef struct BlockJobTxn BlockJobTxn;
@@ -118,6 +121,9 @@ typedef struct BlockJob {
/** Speed that was set with @block_job_set_speed. */
int64_t speed;
+ /** Rate limiting data structure for implementing @speed. */
+ RateLimit limit;
+
/** The completion function that will be called when the job completes. */
BlockCompletionFunc *cb;
@@ -278,6 +284,25 @@ void block_job_finalize(BlockJob *job, Error **errp);
void block_job_dismiss(BlockJob **job, Error **errp);
/**
+ * block_job_progress_update:
+ * @job: The job that has made progress
+ * @done: How much progress the job made
+ *
+ * Updates the progress counter of the job.
+ */
+void block_job_progress_update(BlockJob *job, uint64_t done);
+
+/**
+ * block_job_progress_set_remaining:
+ * @job: The job whose expected progress end value is set
+ * @remaining: Expected end value of the progress counter of the job
+ *
+ * Sets the expected end value of the progress counter of a job so that a
+ * completion percentage can be calculated when the progress is updated.
+ */
+void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining);
+
+/**
* block_job_query:
* @job: The job to get information about.
*
@@ -427,4 +452,11 @@ void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job);
*/
bool block_job_is_internal(BlockJob *job);
+/**
+ * block_job_driver:
+ *
+ * Returns the driver associated with a block job.
+ */
+const BlockJobDriver *block_job_driver(BlockJob *job);
+
#endif
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index d5a515de9b..62ec964d09 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -41,9 +41,6 @@ struct BlockJobDriver {
/** String describing the operation, part of query-block-jobs QMP API */
BlockJobType job_type;
- /** Optional callback for job types that support setting a speed limit */
- void (*set_speed)(BlockJob *job, int64_t speed, Error **errp);
-
/** Mandatory: Entrypoint for the Coroutine. */
CoroutineEntry *start;
@@ -169,6 +166,14 @@ void block_job_sleep_ns(BlockJob *job, int64_t ns);
void block_job_yield(BlockJob *job);
/**
+ * block_job_ratelimit_get_delay:
+ *
+ * Calculate and return delay for the next request in ns. See the documentation
+ * of ratelimit_calculate_delay() for details.
+ */
+int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n);
+
+/**
* block_job_early_fail:
* @bs: The block device.
*
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
index a4cdbbf1b7..9e47b8a629 100644
--- a/include/block/raw-aio.h
+++ b/include/block/raw-aio.h
@@ -57,7 +57,7 @@ void win32_aio_cleanup(QEMUWin32AIOState *aio);
int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile);
BlockAIOCB *win32_aio_submit(BlockDriverState *bs,
QEMUWin32AIOState *aio, HANDLE hfile,
- int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+ uint64_t offset, uint64_t bytes, QEMUIOVector *qiov,
BlockCompletionFunc *cb, void *opaque, int type);
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
AioContext *old_context);
diff --git a/include/qemu/log.h b/include/qemu/log.h
index ff92a8b86a..b097a6cae1 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -44,6 +44,7 @@ static inline bool qemu_log_separate(void)
#define CPU_LOG_PAGE (1 << 14)
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
#define CPU_LOG_TB_OP_IND (1 << 16)
+#define CPU_LOG_TB_FPU (1 << 17)
/* Lock output for a series of related logs. Since this is not needed
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we