Message ID | 1570026166-748566-5-git-send-email-andrey.shinkevich@virtuozzo.com |
---|---|
State | New |
Headers | show |
Series | qcow2: advanced compression options | expand |
02.10.2019 17:22, Andrey Shinkevich wrote: > Support the data compression during block-stream job over a backup > backing chain implemented in the following patch 'block-stream: > add compress option'. > > Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com> > Signed-off-by: Denis V. Lunev <den@openvz.org> > Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com> > --- > block/io.c | 21 ++++++++++++++++----- > block/trace-events | 2 +- > 2 files changed, 17 insertions(+), 6 deletions(-) > > diff --git a/block/io.c b/block/io.c > index f8c3596..a7cd24f 100644 > --- a/block/io.c > +++ b/block/io.c > @@ -1264,12 +1264,13 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, > * allocating cluster in the image file. Note that this value may exceed > * BDRV_REQUEST_MAX_BYTES (even when the original read did not), which > * is one reason we loop rather than doing it all at once. > + * Also, this is crucial for compressed copy-on-read. > */ > bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes); > skip_bytes = offset - cluster_offset; > > trace_bdrv_co_do_copy_on_readv(bs, offset, bytes, > - cluster_offset, cluster_bytes); > + cluster_offset, cluster_bytes, flags); > > while (cluster_bytes) { > int64_t pnum; > @@ -1328,9 +1329,15 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, > /* This does not change the data on the disk, it is not > * necessary to flush even in cache=writethrough mode. > */ > - ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, > - &local_qiov, 0, > - BDRV_REQ_WRITE_UNCHANGED); > + if (flags & BDRV_REQ_WRITE_COMPRESSED) { > + ret = bdrv_driver_pwritev_compressed(bs, cluster_offset, > + pnum, &local_qiov, > + qiov_offset); qiov_offset is wrong: you should use 0 together with local_qiov, as local_qiov is buffer with data to be written. > + } else { > + ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, > + &local_qiov, 0, > + BDRV_REQ_WRITE_UNCHANGED); > + } > } > > if (ret < 0) { > @@ -1396,7 +1403,11 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, > * to pass through to drivers. For now, there aren't any > * passthrough flags. */ > assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ | > - BDRV_REQ_PREFETCH))); > + BDRV_REQ_PREFETCH | BDRV_REQ_WRITE_COMPRESSED))); > + > + /* write compressed only makes sense with copy on read */ > + assert(!(flags & BDRV_REQ_WRITE_COMPRESSED) || > + (flags & BDRV_REQ_COPY_ON_READ)); > > /* Handle Copy on Read and associated serialisation */ > if (flags & BDRV_REQ_COPY_ON_READ) { > diff --git a/block/trace-events b/block/trace-events > index 3aa27e6..f444548 100644 > --- a/block/trace-events > +++ b/block/trace-events > @@ -14,7 +14,7 @@ blk_root_detach(void *child, void *blk, void *bs) "child %p blk %p bs %p" > bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" > bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" > bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x" > -bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64 > +bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes, int flags) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64" flags 0x%x" > bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x" > bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x" > >
diff --git a/block/io.c b/block/io.c index f8c3596..a7cd24f 100644 --- a/block/io.c +++ b/block/io.c @@ -1264,12 +1264,13 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, * allocating cluster in the image file. Note that this value may exceed * BDRV_REQUEST_MAX_BYTES (even when the original read did not), which * is one reason we loop rather than doing it all at once. + * Also, this is crucial for compressed copy-on-read. */ bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes); skip_bytes = offset - cluster_offset; trace_bdrv_co_do_copy_on_readv(bs, offset, bytes, - cluster_offset, cluster_bytes); + cluster_offset, cluster_bytes, flags); while (cluster_bytes) { int64_t pnum; @@ -1328,9 +1329,15 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, /* This does not change the data on the disk, it is not * necessary to flush even in cache=writethrough mode. */ - ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, - &local_qiov, 0, - BDRV_REQ_WRITE_UNCHANGED); + if (flags & BDRV_REQ_WRITE_COMPRESSED) { + ret = bdrv_driver_pwritev_compressed(bs, cluster_offset, + pnum, &local_qiov, + qiov_offset); + } else { + ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, + &local_qiov, 0, + BDRV_REQ_WRITE_UNCHANGED); + } } if (ret < 0) { @@ -1396,7 +1403,11 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, * to pass through to drivers. For now, there aren't any * passthrough flags. */ assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ | - BDRV_REQ_PREFETCH))); + BDRV_REQ_PREFETCH | BDRV_REQ_WRITE_COMPRESSED))); + + /* write compressed only makes sense with copy on read */ + assert(!(flags & BDRV_REQ_WRITE_COMPRESSED) || + (flags & BDRV_REQ_COPY_ON_READ)); /* Handle Copy on Read and associated serialisation */ if (flags & BDRV_REQ_COPY_ON_READ) { diff --git a/block/trace-events b/block/trace-events index 3aa27e6..f444548 100644 --- a/block/trace-events +++ b/block/trace-events @@ -14,7 +14,7 @@ blk_root_detach(void *child, void *blk, void *bs) "child %p blk %p bs %p" bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x" -bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64 +bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes, int flags) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64" flags 0x%x" bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x" bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x"