diff options
Diffstat (limited to 'block_int.h')
-rw-r--r-- | block_int.h | 135 |
1 files changed, 114 insertions, 21 deletions
diff --git a/block_int.h b/block_int.h index b460c369ca..0e5a032e77 100644 --- a/block_int.h +++ b/block_int.h @@ -53,12 +53,6 @@ typedef struct BdrvTrackedRequest BdrvTrackedRequest; -typedef struct AIOPool { - void (*cancel)(BlockDriverAIOCB *acb); - int aiocb_size; - BlockDriverAIOCB *free_aiocb; -} AIOPool; - typedef struct BlockIOLimit { int64_t bps[3]; int64_t iops[3]; @@ -69,8 +63,13 @@ typedef struct BlockIOBaseValue { uint64_t ios[2]; } BlockIOBaseValue; -typedef void BlockJobCancelFunc(void *opaque); typedef struct BlockJob BlockJob; + +/** + * BlockJobType: + * + * A class type for block job objects. + */ typedef struct BlockJobType { /** Derived BlockJob struct size */ size_t instance_size; @@ -83,19 +82,48 @@ typedef struct BlockJobType { } BlockJobType; /** - * Long-running operation on a BlockDriverState + * BlockJob: + * + * Long-running operation on a BlockDriverState. */ struct BlockJob { + /** The job type, including the job vtable. */ const BlockJobType *job_type; + + /** The block device on which the job is operating. */ BlockDriverState *bs; + + /** + * Set to true if the job should cancel itself. The flag must + * always be tested just before toggling the busy flag from false + * to true. After a job has detected that the cancelled flag is + * true, it should not anymore issue any I/O operation to the + * block device. + */ bool cancelled; - /* These fields are published by the query-block-jobs QMP API */ + /** + * Set to false by the job while it is in a quiescent state, where + * no I/O is pending and cancellation can be processed without + * issuing new I/O. The busy flag must be set to false when the + * job goes to sleep on any condition that is not detected by + * #qemu_aio_wait, such as a timer. + */ + bool busy; + + /** Offset that is published by the query-block-jobs QMP API */ int64_t offset; + + /** Length that is published by the query-block-jobs QMP API */ int64_t len; + + /** Speed that was set with @block_job_set_speed. */ int64_t speed; + /** The completion function that will be called when the job completes. */ BlockDriverCompletionFunc *cb; + + /** The opaque value that is passed to the completion function. */ void *opaque; }; @@ -302,20 +330,8 @@ struct BlockDriverState { BlockJob *job; }; -struct BlockDriverAIOCB { - AIOPool *pool; - BlockDriverState *bs; - BlockDriverCompletionFunc *cb; - void *opaque; - BlockDriverAIOCB *next; -}; - void get_tmp_filename(char *filename, int size); -void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs, - BlockDriverCompletionFunc *cb, void *opaque); -void qemu_aio_release(void *p); - void bdrv_set_io_limits(BlockDriverState *bs, BlockIOLimit *io_limits); @@ -323,13 +339,90 @@ void bdrv_set_io_limits(BlockDriverState *bs, int is_windows_drive(const char *filename); #endif +/** + * block_job_create: + * @job_type: The class object for the newly-created job. + * @bs: The block + * @cb: Completion function for the job. + * @opaque: Opaque pointer value passed to @cb. + * + * Create a new long-running block device job and return it. The job + * will call @cb asynchronously when the job completes. Note that + * @bs may have been closed at the time the @cb it is called. If + * this is the case, the job may be reported as either cancelled or + * completed. + * + * This function is not part of the public job interface; it should be + * called from a wrapper that is specific to the job type. + */ void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, BlockDriverCompletionFunc *cb, void *opaque); + +/** + * block_job_complete: + * @job: The job being completed. + * @ret: The status code. + * + * Call the completion function that was registered at creation time, and + * free @job. + */ void block_job_complete(BlockJob *job, int ret); + +/** + * block_job_set_speed: + * @job: The job to set the speed for. + * @speed: The new value + * + * Set a rate-limiting parameter for the job; the actual meaning may + * vary depending on the job type. + */ int block_job_set_speed(BlockJob *job, int64_t value); + +/** + * block_job_cancel: + * @job: The job to be canceled. + * + * Asynchronously cancel the specified job. + */ void block_job_cancel(BlockJob *job); + +/** + * block_job_is_cancelled: + * @job: The job being queried. + * + * Returns whether the job is scheduled for cancellation. + */ bool block_job_is_cancelled(BlockJob *job); +/** + * block_job_cancel: + * @job: The job to be canceled. + * + * Asynchronously cancel the job and wait for it to reach a quiescent + * state. Note that the completion callback will still be called + * asynchronously, hence it is *not* valid to call #bdrv_delete + * immediately after #block_job_cancel_sync. Users of block jobs + * will usually protect the BlockDriverState objects with a reference + * count, should this be a concern. + */ +void block_job_cancel_sync(BlockJob *job); + +/** + * stream_start: + * @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. + * @base_id: The file name that will be written to @bs as the new + * backing file if the job completes. Ignored if @base is %NULL. + * @cb: Completion function for the job. + * @opaque: Opaque pointer value passed to @cb. + * + * 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 + * @base_id in the written image and to @base in the live BlockDriverState. + */ int stream_start(BlockDriverState *bs, BlockDriverState *base, const char *base_id, BlockDriverCompletionFunc *cb, void *opaque); |