From: Ari Sundholm <ari@tuxera.com>
To: qemu-devel@nongnu.org
Cc: Ari Sundholm <ari@tuxera.com>, Kevin Wolf <kwolf@redhat.com>,
Max Reitz <mreitz@redhat.com>,
"open list:blklogwrites" <qemu-block@nongnu.org>
Subject: [Qemu-devel] [PATCH v4 10/10] block/blklogwrites: Use the block device logical sector size when logging writes
Date: Fri, 8 Jun 2018 15:32:28 +0300 [thread overview]
Message-ID: <1528461148-17925-11-git-send-email-ari@tuxera.com> (raw)
In-Reply-To: <1528461148-17925-1-git-send-email-ari@tuxera.com>
The guest OS may perform writes which are aligned to the logical
sector size instead of the physical one, so logging at this granularity
records the writes performed on the block device most faithfully.
Signed-off-by: Ari Sundholm <ari@tuxera.com>
---
block/blklogwrites.c | 47 ++++++++++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index 216367f..decf5e5 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -47,6 +47,8 @@ struct log_write_entry {
typedef struct {
BdrvChild *log_file;
+ uint32_t sectorsize;
+ uint32_t sectorbits;
uint64_t cur_log_sector;
uint64_t nr_entries;
} BDRVBlkLogWritesState;
@@ -67,6 +69,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
goto fail;
}
+ s->sectorsize = BDRV_SECTOR_SIZE; /* May be updated later */
+ s->sectorbits = BDRV_SECTOR_BITS;
s->cur_log_sector = 1;
s->nr_entries = 0;
@@ -173,11 +177,20 @@ static void blk_log_writes_refresh_limits(BlockDriverState *bs, Error **errp)
}
}
+static inline uint32_t blk_log_writes_log2(uint32_t value)
+{
+ assert(value > 0);
+ return 31 - clz32(value);
+}
+
static void blk_log_writes_apply_blkconf(BlockDriverState *bs, BlockConf *conf)
{
- assert(bs && conf && conf->blk);
+ BDRVBlkLogWritesState *s = bs->opaque;
+ assert(bs && conf && conf->blk && s);
- bs->bl.request_alignment = conf->logical_block_size;
+ s->sectorsize = conf->logical_block_size;
+ s->sectorbits = blk_log_writes_log2(s->sectorsize);
+ bs->bl.request_alignment = s->sectorsize;
if (conf->discard_granularity != (uint32_t)-1) {
bs->bl.pdiscard_alignment = conf->discard_granularity;
}
@@ -220,20 +233,20 @@ typedef struct {
static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
{
BDRVBlkLogWritesState *s = lr->bs->opaque;
- uint64_t cur_log_offset = s->cur_log_sector << BDRV_SECTOR_BITS;
+ uint64_t cur_log_offset = s->cur_log_sector << s->sectorbits;
s->nr_entries++;
s->cur_log_sector +=
- ROUND_UP(lr->qiov->size, BDRV_SECTOR_SIZE) >> BDRV_SECTOR_BITS;
+ ROUND_UP(lr->qiov->size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwritev(s->log_file, cur_log_offset, lr->qiov->size,
lr->qiov, 0);
/* Logging for the "write zeroes" operation */
if (lr->log_ret == 0 && lr->zero_size) {
- cur_log_offset = s->cur_log_sector << BDRV_SECTOR_BITS;
+ cur_log_offset = s->cur_log_sector << s->sectorbits;
s->cur_log_sector +=
- ROUND_UP(lr->zero_size, BDRV_SECTOR_SIZE) >> BDRV_SECTOR_BITS;
+ ROUND_UP(lr->zero_size, s->sectorsize) >> s->sectorbits;
lr->log_ret = bdrv_co_pwrite_zeroes(s->log_file, cur_log_offset,
lr->zero_size, 0);
@@ -245,21 +258,22 @@ static void coroutine_fn blk_log_writes_co_do_log(BlkLogWritesLogReq *lr)
.magic = cpu_to_le64(WRITE_LOG_MAGIC),
.version = cpu_to_le64(WRITE_LOG_VERSION),
.nr_entries = cpu_to_le64(s->nr_entries),
- .sectorsize = cpu_to_le32(1 << BDRV_SECTOR_BITS),
+ .sectorsize = cpu_to_le32(s->sectorsize),
};
- static const char zeroes[BDRV_SECTOR_SIZE - sizeof(super)] = { '\0' };
+ void *zeroes = g_malloc0(s->sectorsize - sizeof(super));
QEMUIOVector qiov;
qemu_iovec_init(&qiov, 2);
qemu_iovec_add(&qiov, &super, sizeof(super));
- qemu_iovec_add(&qiov, (void *)zeroes, sizeof(zeroes));
+ qemu_iovec_add(&qiov, zeroes, s->sectorsize - sizeof(super));
lr->log_ret =
- bdrv_co_pwritev(s->log_file, 0, BDRV_SECTOR_SIZE, &qiov, 0);
+ bdrv_co_pwritev(s->log_file, 0, s->sectorsize, &qiov, 0);
if (lr->log_ret == 0) {
lr->log_ret = bdrv_co_flush(s->log_file->bs);
}
qemu_iovec_destroy(&qiov);
+ g_free(zeroes);
}
}
@@ -277,6 +291,7 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
QEMUIOVector log_qiov;
size_t niov = qiov ? qiov->niov : 0;
size_t i;
+ BDRVBlkLogWritesState *s = bs->opaque;
BlkLogWritesFileReq fr = {
.bs = bs,
.offset = offset,
@@ -289,22 +304,23 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
.bs = bs,
.qiov = &log_qiov,
.entry = {
- .sector = cpu_to_le64(offset >> BDRV_SECTOR_BITS),
- .nr_sectors = cpu_to_le64(bytes >> BDRV_SECTOR_BITS),
+ .sector = cpu_to_le64(offset >> s->sectorbits),
+ .nr_sectors = cpu_to_le64(bytes >> s->sectorbits),
.flags = cpu_to_le64(entry_flags),
.data_len = 0,
},
.zero_size = is_zero_write ? bytes : 0,
};
- static const char zeroes[BDRV_SECTOR_SIZE - sizeof(struct log_write_entry)]
- = { '\0' };
+ void *zeroes = g_malloc0(s->sectorsize - sizeof(lr.entry));
+ assert((1 << s->sectorbits) == s->sectorsize);
+ assert(bs->bl.request_alignment == s->sectorsize);
assert(QEMU_IS_ALIGNED(offset, bs->bl.request_alignment));
assert(QEMU_IS_ALIGNED(bytes, bs->bl.request_alignment));
qemu_iovec_init(&log_qiov, niov + 2);
qemu_iovec_add(&log_qiov, &lr.entry, sizeof(lr.entry));
- qemu_iovec_add(&log_qiov, (void *)zeroes, sizeof(zeroes));
+ qemu_iovec_add(&log_qiov, zeroes, s->sectorsize - sizeof(lr.entry));
for (i = 0; i < niov; ++i) {
qemu_iovec_add(&log_qiov, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
}
@@ -313,6 +329,7 @@ blk_log_writes_co_log(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
blk_log_writes_co_do_log(&lr);
qemu_iovec_destroy(&log_qiov);
+ g_free(zeroes);
if (lr.log_ret < 0) {
return lr.log_ret;
--
2.7.4
next prev parent reply other threads:[~2018-06-08 12:32 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-08 12:32 [Qemu-devel] [PATCH v4 00/10] New block driver: blklogwrites Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 01/10] block: Move two block permission constants to the relevant enum Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 02/10] block: Add blklogwrites Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 03/10] block: Add a mechanism for passing a block driver a block configuration Ari Sundholm
2018-06-11 15:06 ` Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 04/10] hw/scsi/scsi-disk: Always apply block configuration to block driver Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 05/10] hw/ide/qdev: " Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 06/10] hw/block/virtio-blk: " Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 07/10] hw/block/nvme: " Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 08/10] hw/block/fdc: " Ari Sundholm
2018-06-08 12:32 ` [Qemu-devel] [PATCH v4 09/10] block/blklogwrites: Use block limits from the backend block configuration Ari Sundholm
2018-06-08 12:32 ` Ari Sundholm [this message]
2018-06-18 15:36 ` [Qemu-devel] [Qemu-block] [PATCH v4 10/10] block/blklogwrites: Use the block device logical sector size when logging writes Alberto Garcia
2018-06-18 15:53 ` Ari Sundholm
2018-06-19 11:22 ` Alberto Garcia
2018-06-14 22:23 ` [Qemu-devel] [PATCH v4 00/10] New block driver: blklogwrites Ari Sundholm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1528461148-17925-11-git-send-email-ari@tuxera.com \
--to=ari@tuxera.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).