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;
|
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];
|
uint64_t ios[2];
|
||||||
} BlockIOBaseValue;
|
} 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 {
|
struct BlockDriver {
|
||||||
const char *format_name;
|
const char *format_name;
|
||||||
int instance_size;
|
int instance_size;
|
||||||
|
@ -264,6 +294,9 @@ struct BlockDriverState {
|
||||||
void *private;
|
void *private;
|
||||||
|
|
||||||
QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
|
QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
|
||||||
|
|
||||||
|
/* long-running background operation */
|
||||||
|
BlockJob *job;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockDriverAIOCB {
|
struct BlockDriverAIOCB {
|
||||||
|
@ -287,4 +320,11 @@ void bdrv_set_io_limits(BlockDriverState *bs,
|
||||||
int is_windows_drive(const char *filename);
|
int is_windows_drive(const char *filename);
|
||||||
#endif
|
#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 */
|
#endif /* BLOCK_INT_H */
|
||||||
|
|
Loading…
Reference in New Issue