From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55346) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yku1S-0004fH-0c for qemu-devel@nongnu.org; Wed, 22 Apr 2015 08:45:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yku1K-0006q4-D1 for qemu-devel@nongnu.org; Wed, 22 Apr 2015 08:44:56 -0400 Received: from relay.parallels.com ([195.214.232.42]:56131) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yku1K-0006pr-0W for qemu-devel@nongnu.org; Wed, 22 Apr 2015 08:44:50 -0400 Message-ID: <553797B7.20406@openvz.org> Date: Wed, 22 Apr 2015 15:44:39 +0300 From: "Denis V. Lunev" MIME-Version: 1.0 References: <1426069701-1405-1-git-send-email-den@openvz.org> <1426069701-1405-9-git-send-email-den@openvz.org> In-Reply-To: <1426069701-1405-9-git-send-email-den@openvz.org> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 08/27] block/parallels: _co_writev callback for Parallels format List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Stefan Hajnoczi On 11/03/15 13:28, Denis V. Lunev wrote: > Support write on Parallels images. The code is almost the same as one > in the previous patch implemented scatter-gather IO for read. > > Signed-off-by: Denis V. Lunev > Reviewed-by: Roman Kagan > CC: Kevin Wolf > CC: Stefan Hajnoczi > --- > block/parallels.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 75 insertions(+), 2 deletions(-) > > diff --git a/block/parallels.c b/block/parallels.c > index 306f2e3..61d7da7 100644 > --- a/block/parallels.c > +++ b/block/parallels.c > @@ -81,8 +81,6 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags, > ParallelsHeader ph; > int ret; > > - bs->read_only = 1; // no write support yet > - > ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph)); > if (ret < 0) { > goto fail; > @@ -166,6 +164,37 @@ static int cluster_remainder(BDRVParallelsState *s, int64_t sector_num, > return MIN(nb_sectors, ret); > } > > +static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num) > +{ > + BDRVParallelsState *s = bs->opaque; > + uint32_t idx, offset, tmp; > + int64_t pos; > + int ret; > + > + idx = sector_num / s->tracks; > + offset = sector_num % s->tracks; > + > + if (idx >= s->catalog_size) { > + return -EINVAL; > + } > + if (s->catalog_bitmap[idx] != 0) { > + return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset; > + } > + > + pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS; > + bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS); > + s->catalog_bitmap[idx] = pos / s->off_multiplier; > + > + tmp = cpu_to_le32(s->catalog_bitmap[idx]); > + > + ret = bdrv_pwrite_sync(bs->file, > + sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp)); > + if (ret < 0) { > + return ret; > + } > + return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset; > +} > + > static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs, > int64_t sector_num, int nb_sectors, int *pnum) > { > @@ -186,6 +215,49 @@ static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs, > BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID; > } > > +static coroutine_fn int parallels_co_writev(BlockDriverState *bs, > + int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) > +{ > + BDRVParallelsState *s = bs->opaque; > + uint64_t bytes_done = 0; > + QEMUIOVector hd_qiov; > + int ret = 0; > + > + qemu_iovec_init(&hd_qiov, qiov->niov); > + > + qemu_co_mutex_lock(&s->lock); > + while (nb_sectors > 0) { > + int64_t position = allocate_cluster(bs, sector_num); > + int n = cluster_remainder(s, sector_num, nb_sectors); > + int nbytes = n << BDRV_SECTOR_BITS; > + > + if (position < 0) { > + ret = (int)position; > + break; > + } > + > + qemu_iovec_reset(&hd_qiov); > + qemu_iovec_concat(&hd_qiov, qiov, bytes_done, nbytes); > + > + qemu_co_mutex_unlock(&s->lock); > + ret = bdrv_co_writev(bs->file, position, n, &hd_qiov); > + qemu_co_mutex_lock(&s->lock); > + > + if (ret < 0) { > + goto fail; same problem with unlock as in patch 6 > + } > + > + nb_sectors -= n; > + sector_num += n; > + bytes_done += nbytes; > + } > + qemu_co_mutex_unlock(&s->lock); > + > +fail: > + qemu_iovec_destroy(&hd_qiov); > + return ret; > +} > + > static coroutine_fn int parallels_co_readv(BlockDriverState *bs, > int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) > { > @@ -242,6 +314,7 @@ static BlockDriver bdrv_parallels = { > .bdrv_close = parallels_close, > .bdrv_co_get_block_status = parallels_co_get_block_status, > .bdrv_co_readv = parallels_co_readv, > + .bdrv_co_writev = parallels_co_writev, > }; > > static void bdrv_parallels_init(void)