From: Charlie Shepherd <charlie@ctshepherd.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, pbonzini@redhat.com, gabriel@kerneis.info,
Charlie Shepherd <charlie@ctshepherd.com>,
stefanha@gmail.com
Subject: [Qemu-devel] [PATCH v2 1/3] COW: Speed up writes
Date: Wed, 6 Nov 2013 13:56:55 +0100 [thread overview]
Message-ID: <1383742617-14742-2-git-send-email-charlie@ctshepherd.com> (raw)
In-Reply-To: <1383742617-14742-1-git-send-email-charlie@ctshepherd.com>
Process a whole sector's worth of COW bits by reading a sector, setting the bits, then writing it
out again. Make sure we only flush once, before writing metadata.
Signed-off-by: Charlie Shepherd <charlie@ctshepherd.com>
---
block/cow.c | 79 ++++++++++++++++++++++++++++++++-----------------------------
1 file changed, 41 insertions(+), 38 deletions(-)
diff --git a/block/cow.c b/block/cow.c
index 909c3e7..5dfffb0 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -103,40 +103,18 @@ static int cow_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}
-/*
- * XXX(hch): right now these functions are extremely inefficient.
- * We should just read the whole bitmap we'll need in one go instead.
- */
-static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum, bool *first)
+static inline void cow_set_bits(uint8_t *bitmap, int start, int64_t nb_sectors)
{
- uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
- uint8_t bitmap;
- int ret;
-
- ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
- if (ret < 0) {
- return ret;
- }
-
- if (bitmap & (1 << (bitnum % 8))) {
- return 0;
- }
-
- if (*first) {
- ret = bdrv_flush(bs->file);
- if (ret < 0) {
- return ret;
+ int64_t bitnum = start, last = start + nb_sectors;
+ while (bitnum < last) {
+ if ((bitnum & 7) == 0 && bitnum + 8 <= last) {
+ bitmap[bitnum / 8] = 0xFF;
+ bitnum += 8;
+ continue;
}
- *first = false;
- }
-
- bitmap |= (1 << (bitnum % 8));
-
- ret = bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap));
- if (ret < 0) {
- return ret;
+ bitmap[bitnum/8] |= (1 << (bitnum % 8));
+ bitnum++;
}
- return 0;
}
#define BITS_PER_BITMAP_SECTOR (512 * 8)
@@ -204,18 +182,43 @@ static int64_t coroutine_fn cow_co_get_block_status(BlockDriverState *bs,
static int cow_update_bitmap(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
- int error = 0;
- int i;
+ int64_t bitnum = sector_num + sizeof(struct cow_header_v2) * 8;
+ uint64_t offset = (bitnum / 8) & -BDRV_SECTOR_SIZE;
bool first = true;
- for (i = 0; i < nb_sectors; i++) {
- error = cow_set_bit(bs, sector_num + i, &first);
- if (error) {
- break;
+ while (nb_sectors) {
+ int ret;
+ uint8_t bitmap[BDRV_SECTOR_SIZE];
+
+ bitnum &= BITS_PER_BITMAP_SECTOR - 1;
+ int sector_bits = MIN(nb_sectors, BITS_PER_BITMAP_SECTOR - bitnum);
+
+ ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
+ if (ret < 0) {
+ return ret;
}
+
+ if (first) {
+ ret = bdrv_flush(bs->file);
+ if (ret < 0) {
+ return ret;
+ }
+ first = false;
+ }
+
+ cow_set_bits(bitmap, bitnum, sector_bits);
+
+ ret = bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap));
+ if (ret < 0) {
+ return ret;
+ }
+
+ bitnum += sector_bits;
+ nb_sectors -= sector_bits;
+ offset += BDRV_SECTOR_SIZE;
}
- return error;
+ return 0;
}
static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,
--
1.8.4.rc3
next prev parent reply other threads:[~2013-11-06 12:57 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-06 12:56 [Qemu-devel] [PATCH v2 0/3] COW: Speed up writes Charlie Shepherd
2013-11-06 12:56 ` Charlie Shepherd [this message]
2013-11-06 12:56 ` [Qemu-devel] [PATCH v2 2/3] COW: Extend checking allocated bits to beyond one sector Charlie Shepherd
2013-11-06 12:56 ` [Qemu-devel] [PATCH v2 3/3] COW: Skip setting already set bits Charlie Shepherd
2013-11-06 13:03 ` Paolo Bonzini
2013-11-06 13:07 ` Charlie Shepherd
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=1383742617-14742-2-git-send-email-charlie@ctshepherd.com \
--to=charlie@ctshepherd.com \
--cc=gabriel@kerneis.info \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@gmail.com \
/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).