On 12.10.20 19:43, Andrey Shinkevich wrote: > Limit COR operations by the base node in the backing chain when the > overlay base node name is given. It will be useful for a block stream > job when the COR-filter is applied. The overlay base node is passed as > the base itself may change due to concurrent commit jobs on the same > backing chain. > > Signed-off-by: Andrey Shinkevich <andrey.shinkevich@xxxxxxxxxxxxx> > --- > block/copy-on-read.c | 39 +++++++++++++++++++++++++++++++++++++-- > 1 file changed, 37 insertions(+), 2 deletions(-) > > diff --git a/block/copy-on-read.c b/block/copy-on-read.c > index c578b1b..dfbd6ad 100644 > --- a/block/copy-on-read.c > +++ b/block/copy-on-read.c > @@ -122,8 +122,43 @@ static int coroutine_fn cor_co_preadv_part(BlockDriverState *bs, > size_t qiov_offset, > int flags) > { > - return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, > - flags | BDRV_REQ_COPY_ON_READ); > + int64_t n = 0; > + int64_t size = offset + bytes; Just when I hit send I noticed that “end” would be a more fitting name for this variable. > + int local_flags; > + int ret; > + BDRVStateCOR *state = bs->opaque; > + > + if (!state->base_overlay) { > + return bdrv_co_preadv_part(bs->file, offset, bytes, qiov, qiov_offset, > + flags | BDRV_REQ_COPY_ON_READ); > + } > + > + while (offset < size) { (because I got a bit confused looking at this) (Though dropping @size (or @end) and just checking when @bytes becomes 0 should work, too.) > + local_flags = flags; > + > + /* In case of failure, try to copy-on-read anyway */ > + ret = bdrv_is_allocated(bs->file->bs, offset, bytes, &n); > + if (!ret) { > + ret = bdrv_is_allocated_above(bdrv_cow_bs(bs->file->bs), > + state->base_overlay, true, offset, > + n, &n); > + if (ret) { > + local_flags |= BDRV_REQ_COPY_ON_READ; > + } > + } Furthermore, I just noticed – can the is_allocated functions not return 0 in @n, when @offset is a the EOF? Is that something to look out for? (I’m not sure.) Max > + > + ret = bdrv_co_preadv_part(bs->file, offset, n, qiov, qiov_offset, > + local_flags); > + if (ret < 0) { > + return ret; > + } > + > + offset += n; > + qiov_offset += n; > + bytes -= n; > + } > + > + return 0; > } > > >
Attachment:
signature.asc
Description: OpenPGP digital signature