diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-09-13 14:31:18 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-09-13 14:31:18 +0100 |
commit | 4dfbe3767af503a4cd137b15c8a9d8f30b20a6e9 (patch) | |
tree | 3e58ae8614b0f372f8fe4f4bb27b85263c3e4934 /block/backup.c | |
parent | fa9701240951093907076db0943f96972a396ef5 (diff) | |
parent | dce8921b2baaf95974af8176406881872067adfa (diff) | |
download | qemu-4dfbe3767af503a4cd137b15c8a9d8f30b20a6e9.zip qemu-4dfbe3767af503a4cd137b15c8a9d8f30b20a6e9.tar.gz qemu-4dfbe3767af503a4cd137b15c8a9d8f30b20a6e9.tar.bz2 |
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Pull request
v2:
* Fixed qcow2 sanitizer warnings [Peter]
* Renamed get_error test cases to get_error_all to avoid tripping "error:"
grep scripts [Peter]
* Added Fam's iothread stop patch
# gpg: Signature made Tue 13 Sep 2016 11:02:30 BST
# gpg: using RSA key 0x9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>"
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8
* remotes/stefanha/tags/block-pull-request:
iothread: Stop threads before main() quits
tests: fix qvirtqueue_kick
MAINTAINERS: add maintainer for replication
support replication driver in blockdev-add
tests: add unit test case for replication
replication: Implement new driver for block replication
replication: Introduce new APIs to do replication operation
configure: support replication
mirror: auto complete active commit
docs: block replication's description
block: Link backup into block core
Backup: export interfaces for extra serialization
Backup: clear all bitmap when doing block checkpoint
block: unblock backup operations in backing file
virtio-blk: rename virtio_device_info to virtio_blk_info
linux-aio: process completions from ioq_submit()
linux-aio: split processing events function
linux-aio: consume events in userspace instead of calling io_getevents
qcow2: avoid memcpy(dst, NULL, len)
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block/backup.c')
-rw-r--r-- | block/backup.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/block/backup.c b/block/backup.c index bb3bb9a..582bd0f 100644 --- a/block/backup.c +++ b/block/backup.c @@ -17,6 +17,7 @@ #include "block/block.h" #include "block/block_int.h" #include "block/blockjob.h" +#include "block/block_backup.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" @@ -27,13 +28,6 @@ #define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16) #define SLICE_TIME 100000000ULL /* ns */ -typedef struct CowRequest { - int64_t start; - int64_t end; - QLIST_ENTRY(CowRequest) list; - CoQueue wait_queue; /* coroutines blocked on this request */ -} CowRequest; - typedef struct BackupBlockJob { BlockJob common; BlockBackend *target; @@ -255,6 +249,57 @@ static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context) blk_set_aio_context(s->target, aio_context); } +void backup_do_checkpoint(BlockJob *job, Error **errp) +{ + BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common); + int64_t len; + + assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP); + + if (backup_job->sync_mode != MIRROR_SYNC_MODE_NONE) { + error_setg(errp, "The backup job only supports block checkpoint in" + " sync=none mode"); + return; + } + + len = DIV_ROUND_UP(backup_job->common.len, backup_job->cluster_size); + bitmap_zero(backup_job->done_bitmap, len); +} + +void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num, + int nb_sectors) +{ + BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common); + int64_t sectors_per_cluster = cluster_size_sectors(backup_job); + int64_t start, end; + + assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP); + + start = sector_num / sectors_per_cluster; + end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster); + wait_for_overlapping_requests(backup_job, start, end); +} + +void backup_cow_request_begin(CowRequest *req, BlockJob *job, + int64_t sector_num, + int nb_sectors) +{ + BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common); + int64_t sectors_per_cluster = cluster_size_sectors(backup_job); + int64_t start, end; + + assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP); + + start = sector_num / sectors_per_cluster; + end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster); + cow_request_begin(req, backup_job, start, end); +} + +void backup_cow_request_end(CowRequest *req) +{ + cow_request_end(req); +} + static const BlockJobDriver backup_job_driver = { .instance_size = sizeof(BackupBlockJob), .job_type = BLOCK_JOB_TYPE_BACKUP, |