在 8/10/2017 8:26 PM, Vladimir Sementsov-Ogievskiy 写道:
09.08.2017 17:11, Vladimir Sementsov-Ogievskiy wrote:
Hi Wen!

I'm trying to understand block/replication code and have a question.

Why should we block the region from intersecting cow requests when read? If I understand correctly

regardless of writes to the secondary-disk we have consistent view of it through hidden-disk:

Even if we are intersecting with some writes to secondary-disk (and corresponding cow-requests), the

data in secondary disk will not be updated until backed up to hidden-disk, therefore, for read we have two

options:

1. read old data from secondary-disk (unallocated region in hidden-disk means data in secondary-disk is not updated yet)

2. read backed-up data from hidden-disk (data in secondary-disk may be already updated but we don't care)

(the whole region to read may consists of parts, corresponding to 1 or 2, but this should be ok too)

Where am I wrong?

Ok, now I think this is needed to prevent intersecting of writes and reads on hidden-disk. If it so, I think it is better to use serializing

Hi, Vladimir. Pls refer https://lists.nongnu.org/archive/html/qemu-devel/2016-05/msg03025.html

BTW, wen's email has changed, also CC Zhang Hailiang, Zhang Chen, Li Zhijian

requests
mechanism (just serialize all requests on hidden-disk, and on write wait for all intersecting serializing requests, on read wait for intersecting serializing writes) - it may require additional option for BlockDriverState, but it is more generic and more clear than export internal backup things to lock disk region. This also can be reused for image-fleecing scheme (which is based on same pattern [active-disk is backing for temp-disk, backup sync=none from active to temp, read from temp])



======

static coroutine_fn int replication_co_readv(BlockDriverState *bs,
                                             int64_t sector_num,
                                             int remaining_sectors,
                                             QEMUIOVector *qiov)
{
    BDRVReplicationState *s = bs->opaque;
    BdrvChild *child = s->secondary_disk;
    BlockJob *job = NULL;
    CowRequest req;
    int ret;

    if (s->mode == REPLICATION_MODE_PRIMARY) {
        /* We only use it to forward primary write requests */
        return -EIO;
}

    ret = replication_get_io_status(s);
    if (ret < 0) {
        return ret;
}

    if (child && child->bs) {
        job = child->bs->job;
}

    if (job) {
        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);
        goto out;
}

    ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors, qiov);
out:
    return replication_return_value(s, ret);
}



--
Thanks
    -Xie

Reply via email to