From dc534f8fc045a51a8eb678ab3d330fba1e9e631c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 30 Mar 2012 13:17:13 +0200 Subject: [PATCH] block: document job API I am not sure that these are really proper GtkDoc, but they follow the existing documentation in block_int.h. Signed-off-by: Paolo Bonzini Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- block_int.h | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 3 deletions(-) diff --git a/block_int.h b/block_int.h index a96aabdd8..0e5a032e7 100644 --- a/block_int.h +++ b/block_int.h @@ -63,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; @@ -77,20 +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; + + /** + * 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; - /* These fields are published by the query-block-jobs QMP API */ + /** 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; }; @@ -306,14 +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);