block: add BlockJob interface for long-running operations

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2012-01-18 14:40:43 +00:00 committed by Kevin Wolf
parent 470c05047a
commit eeec61f291
2 changed files with 88 additions and 0 deletions

48
block.c
View File

@ -3858,3 +3858,51 @@ out:
return ret;
}
void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque)
{
BlockJob *job;
if (bs->job || bdrv_in_use(bs)) {
return NULL;
}
bdrv_set_in_use(bs, 1);
job = g_malloc0(job_type->instance_size);
job->job_type = job_type;
job->bs = bs;
job->cb = cb;
job->opaque = opaque;
bs->job = job;
return job;
}
void block_job_complete(BlockJob *job, int ret)
{
BlockDriverState *bs = job->bs;
assert(bs->job == job);
job->cb(job->opaque, ret);
bs->job = NULL;
g_free(job);
bdrv_set_in_use(bs, 0);
}
int block_job_set_speed(BlockJob *job, int64_t value)
{
if (!job->job_type->set_speed) {
return -ENOTSUP;
}
return job->job_type->set_speed(job, value);
}
void block_job_cancel(BlockJob *job)
{
job->cancelled = true;
}
bool block_job_is_cancelled(BlockJob *job)
{
return job->cancelled;
}

View File

@ -69,6 +69,36 @@ typedef struct BlockIOBaseValue {
uint64_t ios[2];
} BlockIOBaseValue;
typedef void BlockJobCancelFunc(void *opaque);
typedef struct BlockJob BlockJob;
typedef struct BlockJobType {
/** Derived BlockJob struct size */
size_t instance_size;
/** String describing the operation, part of query-block-jobs QMP API */
const char *job_type;
/** Optional callback for job types that support setting a speed limit */
int (*set_speed)(BlockJob *job, int64_t value);
} BlockJobType;
/**
* Long-running operation on a BlockDriverState
*/
struct BlockJob {
const BlockJobType *job_type;
BlockDriverState *bs;
bool cancelled;
/* These fields are published by the query-block-jobs QMP API */
int64_t offset;
int64_t len;
int64_t speed;
BlockDriverCompletionFunc *cb;
void *opaque;
};
struct BlockDriver {
const char *format_name;
int instance_size;
@ -264,6 +294,9 @@ struct BlockDriverState {
void *private;
QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
/* long-running background operation */
BlockJob *job;
};
struct BlockDriverAIOCB {
@ -287,4 +320,11 @@ void bdrv_set_io_limits(BlockDriverState *bs,
int is_windows_drive(const char *filename);
#endif
void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
void block_job_complete(BlockJob *job, int ret);
int block_job_set_speed(BlockJob *job, int64_t value);
void block_job_cancel(BlockJob *job);
bool block_job_is_cancelled(BlockJob *job);
#endif /* BLOCK_INT_H */