|
From: | Vladimir Sementsov-Ogievskiy |
Subject: | Re: [Qemu-devel] block replication |
Date: | Thu, 10 Aug 2017 15:26:33 +0300 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 |
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 correctlyregardless 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), thedata in secondary disk will not be updated until backed up to hidden-disk, therefore, for read we have twooptions: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 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); }
-- Best regards, Vladimir
[Prev in Thread] | Current Thread | [Next in Thread] |