diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/block/block_int.h | 2 | ||||
-rw-r--r-- | include/block/blockjob.h | 51 |
2 files changed, 41 insertions, 12 deletions
diff --git a/include/block/block_int.h b/include/block/block_int.h index 688c6be..2057156 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -361,6 +361,7 @@ typedef struct BdrvAioNotifier { void (*detach_aio_context)(void *opaque); void *opaque; + bool deleted; QLIST_ENTRY(BdrvAioNotifier) list; } BdrvAioNotifier; @@ -427,6 +428,7 @@ struct BlockDriverState { * BDS may register themselves in this list to be notified of changes * regarding this BDS's context */ QLIST_HEAD(, BdrvAioNotifier) aio_notifiers; + bool walking_aio_notifiers; /* to make removal during iteration safe */ char filename[PATH_MAX]; char backing_file[PATH_MAX]; /* if non zero, the image is a diff of diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 00ac418..7dc720c 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -70,6 +70,27 @@ typedef struct BlockJobDriver { * never both. */ void (*abort)(BlockJob *job); + + /** + * If the callback is not NULL, it will be invoked when the job transitions + * into the paused state. Paused jobs must not perform any asynchronous + * I/O or event loop activity. This callback is used to quiesce jobs. + */ + void coroutine_fn (*pause)(BlockJob *job); + + /** + * If the callback is not NULL, it will be invoked when the job transitions + * out of the paused state. Any asynchronous I/O or event loop activity + * should be restarted from this callback. + */ + void coroutine_fn (*resume)(BlockJob *job); + + /* + * 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 + * besides job->blk to the new AioContext. + */ + void (*attached_aio_context)(BlockJob *job, AioContext *new_context); } BlockJobDriver; /** @@ -119,13 +140,19 @@ struct BlockJob { bool user_paused; /** - * Set to false by the job while it is in a quiescent state, where - * no I/O is pending and the job has yielded on any condition - * that is not detected by #aio_poll, such as a timer. + * Set to false by the job while the coroutine has yielded and may be + * re-entered by block_job_enter(). There may still be I/O or event loop + * activity pending. */ bool busy; /** + * Set to true by the job while it is in a quiescent state, where + * no I/O or event loop activity is pending. + */ + bool paused; + + /** * Set to true when the job is ready to be completed. */ bool ready; @@ -299,6 +326,15 @@ bool block_job_is_cancelled(BlockJob *job); BlockJobInfo *block_job_query(BlockJob *job); /** + * block_job_pause_point: + * @job: The job that is ready to pause. + * + * Pause now if block_job_pause() has been called. Block jobs that perform + * lots of I/O must call this between requests so that the job can be paused. + */ +void coroutine_fn block_job_pause_point(BlockJob *job); + +/** * block_job_pause: * @job: The job to be paused. * @@ -348,15 +384,6 @@ void block_job_event_completed(BlockJob *job, const char *msg); void block_job_event_ready(BlockJob *job); /** - * block_job_is_paused: - * @job: The job being queried. - * - * Returns whether the job is currently paused, or will pause - * as soon as it reaches a sleeping point. - */ -bool block_job_is_paused(BlockJob *job); - -/** * block_job_cancel_sync: * @job: The job to be canceled. * |