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:
parent
470c05047a
commit
eeec61f291
48
block.c
48
block.c
@ -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;
|
||||
}
|
||||
|
40
block_int.h
40
block_int.h
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user