Skip to content

Commit

Permalink
backup: Switch block_backup.h to byte-based
Browse files Browse the repository at this point in the history
We are gradually converting to byte-based interfaces, as they are
easier to reason about than sector-based.  Continue by converting
the public interface to backup jobs (no semantic change), including
a change to CowRequest to track by bytes instead of cluster indices.

Note that this does not change the difference between the public
interface (starting point, and size of the subsequent range) and
the internal interface (starting and end points).

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Xie Changlong <xiechanglong@cmss.chinamobile.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
ebblake authored and kevmw committed Jul 10, 2017
1 parent cf79cdf commit f6ac207
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 26 deletions.
31 changes: 15 additions & 16 deletions block/backup.c
Expand Up @@ -64,7 +64,7 @@ static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,
do {
retry = false;
QLIST_FOREACH(req, &job->inflight_reqs, list) {
if (end > req->start && start < req->end) {
if (end > req->start_byte && start < req->end_byte) {
qemu_co_queue_wait(&req->wait_queue, NULL);
retry = true;
break;
Expand All @@ -75,10 +75,10 @@ static void coroutine_fn wait_for_overlapping_requests(BackupBlockJob *job,

/* Keep track of an in-flight request */
static void cow_request_begin(CowRequest *req, BackupBlockJob *job,
int64_t start, int64_t end)
int64_t start, int64_t end)
{
req->start = start;
req->end = end;
req->start_byte = start;
req->end_byte = end;
qemu_co_queue_init(&req->wait_queue);
QLIST_INSERT_HEAD(&job->inflight_reqs, req, list);
}
Expand Down Expand Up @@ -114,8 +114,10 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE);

wait_for_overlapping_requests(job, start, end);
cow_request_begin(&cow_request, job, start, end);
wait_for_overlapping_requests(job, start * job->cluster_size,
end * job->cluster_size);
cow_request_begin(&cow_request, job, start * job->cluster_size,
end * job->cluster_size);

for (; start < end; start++) {
if (test_bit(start, job->done_bitmap)) {
Expand Down Expand Up @@ -277,32 +279,29 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
bitmap_zero(backup_job->done_bitmap, len);
}

void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
int nb_sectors)
void backup_wait_for_overlapping_requests(BlockJob *job, int64_t offset,
uint64_t bytes)
{
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);
start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
wait_for_overlapping_requests(backup_job, start, end);
}

void backup_cow_request_begin(CowRequest *req, BlockJob *job,
int64_t sector_num,
int nb_sectors)
int64_t offset, uint64_t bytes)
{
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);
start = QEMU_ALIGN_DOWN(offset, backup_job->cluster_size);
end = QEMU_ALIGN_UP(offset + bytes, backup_job->cluster_size);
cow_request_begin(req, backup_job, start, end);
}

Expand Down
12 changes: 8 additions & 4 deletions block/replication.c
Expand Up @@ -234,10 +234,14 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
}

if (job) {
backup_wait_for_overlapping_requests(child->bs->job, sector_num,
remaining_sectors);
backup_cow_request_begin(&req, child->bs->job, sector_num,
remaining_sectors);
uint64_t remaining_bytes = remaining_sectors * BDRV_SECTOR_SIZE;

backup_wait_for_overlapping_requests(child->bs->job,
sector_num * BDRV_SECTOR_SIZE,
remaining_bytes);
backup_cow_request_begin(&req, child->bs->job,
sector_num * BDRV_SECTOR_SIZE,
remaining_bytes);
ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors,
qiov);
backup_cow_request_end(&req);
Expand Down
11 changes: 5 additions & 6 deletions include/block/block_backup.h
Expand Up @@ -21,17 +21,16 @@
#include "block/block_int.h"

typedef struct CowRequest {
int64_t start;
int64_t end;
int64_t start_byte;
int64_t end_byte;
QLIST_ENTRY(CowRequest) list;
CoQueue wait_queue; /* coroutines blocked on this request */
} CowRequest;

void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
int nb_sectors);
void backup_wait_for_overlapping_requests(BlockJob *job, int64_t offset,
uint64_t bytes);
void backup_cow_request_begin(CowRequest *req, BlockJob *job,
int64_t sector_num,
int nb_sectors);
int64_t offset, uint64_t bytes);
void backup_cow_request_end(CowRequest *req);

void backup_do_checkpoint(BlockJob *job, Error **errp);
Expand Down

0 comments on commit f6ac207

Please sign in to comment.