* [Qemu-devel] [PATCH 01/12] qcow2: remove a line of unnecessary code
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion Kevin Wolf
` (11 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Commit 3948d1d4 removed the pointer argument we filled in with l2_offset
but forgot to remove the unnecessary l2_offset assignment.
Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-cluster.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 4b3345b..9aee9fc 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -538,7 +538,6 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
if (l2_offset) {
qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));
}
- l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;
}
/* find the cluster offset for the given disk offset */
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 01/12] qcow2: remove a line of unnecessary code Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 16:43 ` Eric Blake
2012-06-07 7:13 ` Michael Tokarev
2012-06-04 11:13 ` [Qemu-devel] [PATCH 03/12] block: implement is_allocated for raw Kevin Wolf
` (10 subsequent siblings)
12 siblings, 2 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 812c93c..443c021 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -367,7 +367,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
}
for(i = 0; i < table_size; i++) {
- cpu_to_be64s(&new_table[i]);
+ be64_to_cpus(&new_table[i]);
}
/* Hook up the new refcount table in the qcow2 header */
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion
2012-06-04 11:13 ` [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion Kevin Wolf
@ 2012-06-04 16:43 ` Eric Blake
2012-06-04 17:23 ` Kevin Wolf
2012-06-07 7:13 ` Michael Tokarev
1 sibling, 1 reply; 42+ messages in thread
From: Eric Blake @ 2012-06-04 16:43 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel, anthony
[-- Attachment #1: Type: text/plain, Size: 997 bytes --]
On 06/04/2012 05:13 AM, Kevin Wolf wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Is it too late to s/convertion/conversion/ in the subject?
>
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
> block/qcow2-refcount.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index 812c93c..443c021 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -367,7 +367,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
> }
>
> for(i = 0; i < table_size; i++) {
> - cpu_to_be64s(&new_table[i]);
> + be64_to_cpus(&new_table[i]);
> }
>
> /* Hook up the new refcount table in the qcow2 header */
--
Eric Blake eblake@redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 620 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion
2012-06-04 16:43 ` Eric Blake
@ 2012-06-04 17:23 ` Kevin Wolf
0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 17:23 UTC (permalink / raw)
To: Eric Blake; +Cc: qemu-devel, anthony
Am 04.06.2012 18:43, schrieb Eric Blake:
> On 06/04/2012 05:13 AM, Kevin Wolf wrote:
>> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> Is it too late to s/convertion/conversion/ in the subject?
Depends on whether Anthony has already pulled to his local repo, I
guess. I've renamed it to "qcow2: fix endianness conversion" in my tree
now, we'll see which versions will get into master.
Kevin
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion
2012-06-04 11:13 ` [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion Kevin Wolf
2012-06-04 16:43 ` Eric Blake
@ 2012-06-07 7:13 ` Michael Tokarev
2012-06-08 8:27 ` Kevin Wolf
1 sibling, 1 reply; 42+ messages in thread
From: Michael Tokarev @ 2012-06-07 7:13 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel, anthony
On 04.06.2012 15:13, Kevin Wolf wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
> Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
It appears to be a good candidate for -stable, no?
Thanks,
/mjt
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion
2012-06-07 7:13 ` Michael Tokarev
@ 2012-06-08 8:27 ` Kevin Wolf
0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-08 8:27 UTC (permalink / raw)
To: Michael Tokarev; +Cc: qemu-devel, anthony
Am 07.06.2012 09:13, schrieb Michael Tokarev:
> On 04.06.2012 15:13, Kevin Wolf wrote:
>> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>>
>> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>> Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
>> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
>
> It appears to be a good candidate for -stable, no?
No, it's merely cosmetic. cpu_to_be64s() and be64_to_cpus() do the same,
they both swap the byte order if the host is little endian.
Kevin
^ permalink raw reply [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 03/12] block: implement is_allocated for raw
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 01/12] qcow2: remove a line of unnecessary code Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 02/12] qcow2: fix the byte endian convertion Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 04/12] stream: tweak usage of bdrv_co_is_allocated Kevin Wolf
` (9 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Paolo Bonzini <pbonzini@redhat.com>
Either FIEMAP, or SEEK_DATA+SEEK_HOLE can be used to implement the
is_allocated callback for raw files. On Linux ext4, btrfs and XFS
all support it.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/raw-posix.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++
block/raw.c | 8 ++++
2 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 03fcfcc..bf7700a 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -52,6 +52,10 @@
#include <sys/param.h>
#include <linux/cdrom.h>
#include <linux/fd.h>
+#include <linux/fs.h>
+#endif
+#ifdef CONFIG_FIEMAP
+#include <linux/fiemap.h>
#endif
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/disk.h>
@@ -583,6 +587,99 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
return result;
}
+/*
+ * Returns true iff the specified sector is present in the disk image. Drivers
+ * not implementing the functionality are assumed to not support backing files,
+ * hence all their sectors are reported as allocated.
+ *
+ * If 'sector_num' is beyond the end of the disk image the return value is 0
+ * and 'pnum' is set to 0.
+ *
+ * 'pnum' is set to the number of sectors (including and immediately following
+ * the specified sector) that are known to be in the same
+ * allocated/unallocated state.
+ *
+ * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
+ * beyond the end of the disk image it will be clamped.
+ */
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ BDRVRawState *s = bs->opaque;
+ off_t start, data, hole;
+ int ret;
+
+ ret = fd_open(bs);
+ if (ret < 0) {
+ return ret;
+ }
+
+ start = sector_num * BDRV_SECTOR_SIZE;
+#ifdef CONFIG_FIEMAP
+ struct {
+ struct fiemap fm;
+ struct fiemap_extent fe;
+ } f;
+ f.fm.fm_start = start;
+ f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
+ f.fm.fm_flags = 0;
+ f.fm.fm_extent_count = 1;
+ f.fm.fm_reserved = 0;
+ if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
+ /* Assume everything is allocated. */
+ *pnum = nb_sectors;
+ return 1;
+ }
+
+ if (f.fm.fm_mapped_extents == 0) {
+ /* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
+ * f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
+ */
+ off_t length = lseek(s->fd, 0, SEEK_END);
+ hole = f.fm.fm_start;
+ data = MIN(f.fm.fm_start + f.fm.fm_length, length);
+ } else {
+ data = f.fe.fe_logical;
+ hole = f.fe.fe_logical + f.fe.fe_length;
+ }
+#elif defined SEEK_HOLE && defined SEEK_DATA
+ hole = lseek(s->fd, start, SEEK_HOLE);
+ if (hole == -1) {
+ /* -ENXIO indicates that sector_num was past the end of the file.
+ * There is a virtual hole there. */
+ assert(errno != -ENXIO);
+
+ /* Most likely EINVAL. Assume everything is allocated. */
+ *pnum = nb_sectors;
+ return 1;
+ }
+
+ if (hole > start) {
+ data = start;
+ } else {
+ /* On a hole. We need another syscall to find its end. */
+ data = lseek(s->fd, start, SEEK_DATA);
+ if (data == -1) {
+ data = lseek(s->fd, 0, SEEK_END);
+ }
+ }
+#else
+ *pnum = nb_sectors;
+ return 1;
+#endif
+
+ if (data <= start) {
+ /* On a data extent, compute sectors to the end of the extent. */
+ *pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
+ return 1;
+ } else {
+ /* On a hole, compute sectors to the beginning of the next extent. */
+ *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
+ return 0;
+ }
+}
+
#ifdef CONFIG_XFS
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
{
@@ -634,6 +731,7 @@ static BlockDriver bdrv_file = {
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_co_discard = raw_co_discard,
+ .bdrv_co_is_allocated = raw_co_is_allocated,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
diff --git a/block/raw.c b/block/raw.c
index 7086e31..09d9b48 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -25,6 +25,13 @@ static void raw_close(BlockDriverState *bs)
{
}
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ return bdrv_co_is_allocated(bs->file, sector_num, nb_sectors, pnum);
+}
+
static int64_t raw_getlength(BlockDriverState *bs)
{
return bdrv_getlength(bs->file);
@@ -108,6 +115,7 @@ static BlockDriver bdrv_raw = {
.bdrv_co_readv = raw_co_readv,
.bdrv_co_writev = raw_co_writev,
+ .bdrv_co_is_allocated = raw_co_is_allocated,
.bdrv_co_discard = raw_co_discard,
.bdrv_probe = raw_probe,
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 04/12] stream: tweak usage of bdrv_co_is_allocated
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (2 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 03/12] block: implement is_allocated for raw Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 05/12] stream: move is_allocated_above to block.c Kevin Wolf
` (8 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Paolo Bonzini <pbonzini@redhat.com>
is_allocated_base has complex semantics that are not really usable
outside streaming. Split the check in two parts, where the allocated
state for the top bs is moved to the caller. The resulting function
is more generally useful.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/stream.c | 51 +++++++++++++++++++++++++--------------------------
1 files changed, 25 insertions(+), 26 deletions(-)
diff --git a/block/stream.c b/block/stream.c
index 8e58322..4490a25 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -101,45 +101,33 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
/*
* Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP]
*
- * Return true if the given sector is allocated in top.
- * Return false if the given sector is allocated in intermediate images.
- * Return true otherwise.
+ * Return true if the given sector is allocated in any image between
+ * BASE and TOP (inclusive). BASE can be NULL to check if the given
+ * sector is allocated in any image of the chain. Return false otherwise.
*
* 'pnum' is set to the number of sectors (including and immediately following
* the specified sector) that are known to be in the same
* allocated/unallocated state.
*
*/
-static int coroutine_fn is_allocated_base(BlockDriverState *top,
- BlockDriverState *base,
- int64_t sector_num,
- int nb_sectors, int *pnum)
+static int coroutine_fn is_allocated_above(BlockDriverState *top,
+ BlockDriverState *base,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
{
BlockDriverState *intermediate;
- int ret, n;
-
- ret = bdrv_co_is_allocated(top, sector_num, nb_sectors, &n);
- if (ret) {
- *pnum = n;
- return ret;
- }
-
- /*
- * Is the unallocated chunk [sector_num, n] also
- * unallocated between base and top?
- */
- intermediate = top->backing_hd;
+ int ret, n = nb_sectors;
+ intermediate = top;
while (intermediate != base) {
int pnum_inter;
-
ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
&pnum_inter);
if (ret < 0) {
return ret;
} else if (ret) {
*pnum = pnum_inter;
- return 0;
+ return 1;
}
/*
@@ -156,7 +144,7 @@ static int coroutine_fn is_allocated_base(BlockDriverState *top,
}
*pnum = n;
- return 1;
+ return 0;
}
static void coroutine_fn stream_run(void *opaque)
@@ -189,6 +177,7 @@ static void coroutine_fn stream_run(void *opaque)
for (sector_num = 0; sector_num < end; sector_num += n) {
uint64_t delay_ns = 0;
+ bool copy;
wait:
/* Note that even when no rate limit is applied we need to yield
@@ -199,10 +188,20 @@ wait:
break;
}
- ret = is_allocated_base(bs, base, sector_num,
- STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
+ ret = bdrv_co_is_allocated(bs, sector_num,
+ STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
+ if (ret == 1) {
+ /* Allocated in the top, no need to copy. */
+ copy = false;
+ } else {
+ /* Copy if allocated in the intermediate images. Limit to the
+ * known-unallocated area [sector_num, sector_num+n). */
+ ret = is_allocated_above(bs->backing_hd, base, sector_num, n, &n);
+ copy = (ret == 1);
+ }
+
trace_stream_one_iteration(s, sector_num, n, ret);
- if (ret == 0) {
+ if (ret >= 0 && copy) {
if (s->common.speed) {
delay_ns = ratelimit_calculate_delay(&s->limit, n);
if (delay_ns > 0) {
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 05/12] stream: move is_allocated_above to block.c
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (3 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 04/12] stream: tweak usage of bdrv_co_is_allocated Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 06/12] stream: move rate limiting to a separate header file Kevin Wolf
` (7 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
block.h | 4 ++++
block/stream.c | 53 ++---------------------------------------------------
3 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/block.c b/block.c
index 7547051..c07ff39 100644
--- a/block.c
+++ b/block.c
@@ -2569,6 +2569,55 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
return data.ret;
}
+/*
+ * Given an image chain: ... -> [BASE] -> [INTER1] -> [INTER2] -> [TOP]
+ *
+ * Return true if the given sector is allocated in any image between
+ * BASE and TOP (inclusive). BASE can be NULL to check if the given
+ * sector is allocated in any image of the chain. Return false otherwise.
+ *
+ * 'pnum' is set to the number of sectors (including and immediately following
+ * the specified sector) that are known to be in the same
+ * allocated/unallocated state.
+ *
+ */
+int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
+ BlockDriverState *base,
+ int64_t sector_num,
+ int nb_sectors, int *pnum)
+{
+ BlockDriverState *intermediate;
+ int ret, n = nb_sectors;
+
+ intermediate = top;
+ while (intermediate && intermediate != base) {
+ int pnum_inter;
+ ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
+ &pnum_inter);
+ if (ret < 0) {
+ return ret;
+ } else if (ret) {
+ *pnum = pnum_inter;
+ return 1;
+ }
+
+ /*
+ * [sector_num, nb_sectors] is unallocated on top but intermediate
+ * might have
+ *
+ * [sector_num+x, nr_sectors] allocated.
+ */
+ if (n > pnum_inter) {
+ n = pnum_inter;
+ }
+
+ intermediate = intermediate->backing_hd;
+ }
+
+ *pnum = n;
+ return 0;
+}
+
BlockInfoList *qmp_query_block(Error **errp)
{
BlockInfoList *head = NULL, *cur_item = NULL;
diff --git a/block.h b/block.h
index 7408acc..799cf48 100644
--- a/block.h
+++ b/block.h
@@ -165,6 +165,10 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num,
int nb_sectors);
int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum);
+int coroutine_fn bdrv_co_is_allocated_above(BlockDriverState *top,
+ BlockDriverState *base,
+ int64_t sector_num,
+ int nb_sectors, int *pnum);
BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
const char *backing_file);
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
diff --git a/block/stream.c b/block/stream.c
index 4490a25..811388a 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -98,55 +98,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
top->backing_hd = base;
}
-/*
- * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP]
- *
- * Return true if the given sector is allocated in any image between
- * BASE and TOP (inclusive). BASE can be NULL to check if the given
- * sector is allocated in any image of the chain. Return false otherwise.
- *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
- * allocated/unallocated state.
- *
- */
-static int coroutine_fn is_allocated_above(BlockDriverState *top,
- BlockDriverState *base,
- int64_t sector_num,
- int nb_sectors, int *pnum)
-{
- BlockDriverState *intermediate;
- int ret, n = nb_sectors;
-
- intermediate = top;
- while (intermediate != base) {
- int pnum_inter;
- ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
- &pnum_inter);
- if (ret < 0) {
- return ret;
- } else if (ret) {
- *pnum = pnum_inter;
- return 1;
- }
-
- /*
- * [sector_num, nb_sectors] is unallocated on top but intermediate
- * might have
- *
- * [sector_num+x, nr_sectors] allocated.
- */
- if (n > pnum_inter) {
- n = pnum_inter;
- }
-
- intermediate = intermediate->backing_hd;
- }
-
- *pnum = n;
- return 0;
-}
-
static void coroutine_fn stream_run(void *opaque)
{
StreamBlockJob *s = opaque;
@@ -196,10 +147,10 @@ wait:
} else {
/* Copy if allocated in the intermediate images. Limit to the
* known-unallocated area [sector_num, sector_num+n). */
- ret = is_allocated_above(bs->backing_hd, base, sector_num, n, &n);
+ ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
+ sector_num, n, &n);
copy = (ret == 1);
}
-
trace_stream_one_iteration(s, sector_num, n, ret);
if (ret >= 0 && copy) {
if (s->common.speed) {
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 06/12] stream: move rate limiting to a separate header file
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (4 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 05/12] stream: move is_allocated_above to block.c Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 07/12] Un-inline fdctrl_init_isa() Kevin Wolf
` (6 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Paolo Bonzini <pbonzini@redhat.com>
Make the code reusable.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/stream.c | 31 +---------------------------
include/qemu/ratelimit.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 29 deletions(-)
create mode 100644 include/qemu/ratelimit.h
diff --git a/block/stream.c b/block/stream.c
index 811388a..37c4652 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -13,6 +13,7 @@
#include "trace.h"
#include "block_int.h"
+#include "qemu/ratelimit.h"
enum {
/*
@@ -25,34 +26,6 @@ enum {
#define SLICE_TIME 100000000ULL /* ns */
-typedef struct {
- int64_t next_slice_time;
- uint64_t slice_quota;
- uint64_t dispatched;
-} RateLimit;
-
-static int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
-{
- int64_t now = qemu_get_clock_ns(rt_clock);
-
- if (limit->next_slice_time < now) {
- limit->next_slice_time = now + SLICE_TIME;
- limit->dispatched = 0;
- }
- if (limit->dispatched == 0 || limit->dispatched + n <= limit->slice_quota) {
- limit->dispatched += n;
- return 0;
- } else {
- limit->dispatched = n;
- return limit->next_slice_time - now;
- }
-}
-
-static void ratelimit_set_speed(RateLimit *limit, uint64_t speed)
-{
- limit->slice_quota = speed / (1000000000ULL / SLICE_TIME);
-}
-
typedef struct StreamBlockJob {
BlockJob common;
RateLimit limit;
@@ -198,7 +171,7 @@ static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
error_set(errp, QERR_INVALID_PARAMETER, "speed");
return;
}
- ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE);
+ ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
}
static BlockJobType stream_job_type = {
diff --git a/include/qemu/ratelimit.h b/include/qemu/ratelimit.h
new file mode 100644
index 0000000..c6ac281
--- /dev/null
+++ b/include/qemu/ratelimit.h
@@ -0,0 +1,48 @@
+/*
+ * Ratelimiting calculations
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_RATELIMIT_H
+#define QEMU_RATELIMIT_H 1
+
+typedef struct {
+ int64_t next_slice_time;
+ uint64_t slice_quota;
+ uint64_t slice_ns;
+ uint64_t dispatched;
+} RateLimit;
+
+static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
+{
+ int64_t now = qemu_get_clock_ns(rt_clock);
+
+ if (limit->next_slice_time < now) {
+ limit->next_slice_time = now + limit->slice_ns;
+ limit->dispatched = 0;
+ }
+ if (limit->dispatched == 0 || limit->dispatched + n <= limit->slice_quota) {
+ limit->dispatched += n;
+ return 0;
+ } else {
+ limit->dispatched = n;
+ return limit->next_slice_time - now;
+ }
+}
+
+static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
+ uint64_t slice_ns)
+{
+ limit->slice_ns = slice_ns;
+ limit->slice_quota = ((double)speed * 1000000000ULL) / slice_ns;
+}
+
+#endif
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 07/12] Un-inline fdctrl_init_isa()
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (5 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 06/12] stream: move rate limiting to a separate header file Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 08/12] qemu-img check -r for repairing images Kevin Wolf
` (5 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
hw/fdc.c | 20 ++++++++++++++++++++
hw/fdc.h | 24 ++----------------------
hw/ide/piix.c | 3 ++-
hw/isa.h | 2 --
hw/pc_sysfw.c | 1 +
qemu-common.h | 1 +
6 files changed, 26 insertions(+), 25 deletions(-)
diff --git a/hw/fdc.c b/hw/fdc.c
index 30d34e3..bfa4e68 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1888,6 +1888,26 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
return 0;
}
+ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
+{
+ ISADevice *dev;
+
+ dev = isa_try_create(bus, "isa-fdc");
+ if (!dev) {
+ return NULL;
+ }
+
+ if (fds[0]) {
+ qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
+ }
+ if (fds[1]) {
+ qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
+ }
+ qdev_init_nofail(&dev->qdev);
+
+ return dev;
+}
+
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base, DriveInfo **fds)
{
diff --git a/hw/fdc.h b/hw/fdc.h
index 55a8d73..1b32b17 100644
--- a/hw/fdc.h
+++ b/hw/fdc.h
@@ -1,32 +1,12 @@
#ifndef HW_FDC_H
#define HW_FDC_H
-#include "isa.h"
-#include "blockdev.h"
+#include "qemu-common.h"
/* fdc.c */
#define MAX_FD 2
-static inline ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
-{
- ISADevice *dev;
-
- dev = isa_try_create(bus, "isa-fdc");
- if (!dev) {
- return NULL;
- }
-
- if (fds[0]) {
- qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
- }
- if (fds[1]) {
- qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
- }
- qdev_init_nofail(&dev->qdev);
-
- return dev;
-}
-
+ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds);
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
target_phys_addr_t mmio_base, DriveInfo **fds);
void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index bcaa400..f5a74c2 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -22,11 +22,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+
#include <hw/hw.h>
#include <hw/pc.h>
#include <hw/pci.h>
#include <hw/isa.h>
-#include "block.h"
+#include "blockdev.h"
#include "sysemu.h"
#include "dma.h"
diff --git a/hw/isa.h b/hw/isa.h
index f7bc4b5..6c6fd7f 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -9,8 +9,6 @@
#define ISA_NUM_IRQS 16
-typedef struct ISADevice ISADevice;
-
#define TYPE_ISA_DEVICE "isa-device"
#define ISA_DEVICE(obj) \
OBJECT_CHECK(ISADevice, (obj), TYPE_ISA_DEVICE)
diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index f0d7c21..b45f0ac 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -23,6 +23,7 @@
* THE SOFTWARE.
*/
+#include "blockdev.h"
#include "sysbus.h"
#include "hw.h"
#include "pc.h"
diff --git a/qemu-common.h b/qemu-common.h
index 91e0562..8f87e41 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -239,6 +239,7 @@ typedef struct VLANState VLANState;
typedef struct VLANClientState VLANClientState;
typedef struct i2c_bus i2c_bus;
typedef struct ISABus ISABus;
+typedef struct ISADevice ISADevice;
typedef struct SMBusDevice SMBusDevice;
typedef struct PCIHostState PCIHostState;
typedef struct PCIExpressHost PCIExpressHost;
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 08/12] qemu-img check -r for repairing images
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (6 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 07/12] Un-inline fdctrl_init_isa() Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 09/12] qemu-img check: Print fixed clusters and recheck Kevin Wolf
` (4 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
The QED block driver already provides the functionality to not only
detect inconsistencies in images, but also fix them. However, this
functionality cannot be manually invoked with qemu-img, but the
check happens only automatically during bdrv_open().
This adds a -r switch to qemu-img check that allows manual invocation
of an image repair.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 4 ++--
block.h | 7 ++++++-
block/qcow2.c | 7 ++++++-
block/qed.c | 5 +++--
block/vdi.c | 7 ++++++-
block_int.h | 3 ++-
qemu-img-cmds.hx | 4 ++--
qemu-img.c | 25 ++++++++++++++++++++++---
qemu-img.texi | 7 ++++++-
9 files changed, 55 insertions(+), 14 deletions(-)
diff --git a/block.c b/block.c
index c07ff39..355ac86 100644
--- a/block.c
+++ b/block.c
@@ -1222,14 +1222,14 @@ bool bdrv_dev_is_medium_locked(BlockDriverState *bs)
* free of errors) or -errno when an internal error occurred. The results of the
* check are stored in res.
*/
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res)
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
{
if (bs->drv->bdrv_check == NULL) {
return -ENOTSUP;
}
memset(res, 0, sizeof(*res));
- return bs->drv->bdrv_check(bs, res);
+ return bs->drv->bdrv_check(bs, res, fix);
}
#define COMMIT_BUF_SECTORS 2048
diff --git a/block.h b/block.h
index 799cf48..61b7e8e 100644
--- a/block.h
+++ b/block.h
@@ -190,7 +190,12 @@ typedef struct BdrvCheckResult {
BlockFragInfo bfi;
} BdrvCheckResult;
-int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
+typedef enum {
+ BDRV_FIX_LEAKS = 1,
+ BDRV_FIX_ERRORS = 2,
+} BdrvCheckMode;
+
+int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
/* async block I/O */
typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
diff --git a/block/qcow2.c b/block/qcow2.c
index c2e49cd..7797015 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1470,8 +1470,13 @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
}
-static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result)
+static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
+ BdrvCheckMode fix)
{
+ if (fix) {
+ return -ENOTSUP;
+ }
+
return qcow2_check_refcounts(bs, result);
}
diff --git a/block/qed.c b/block/qed.c
index 30a31f9..ab59724 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1517,11 +1517,12 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
bdrv_qed_open(bs, bs->open_flags);
}
-static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result)
+static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
+ BdrvCheckMode fix)
{
BDRVQEDState *s = bs->opaque;
- return qed_check(s, result, false);
+ return qed_check(s, result, !!fix);
}
static QEMUOptionParameter qed_create_options[] = {
diff --git a/block/vdi.c b/block/vdi.c
index 119d3c7..57325d6 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -277,7 +277,8 @@ static void vdi_header_print(VdiHeader *header)
}
#endif
-static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
+static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix)
{
/* TODO: additional checks possible. */
BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
@@ -286,6 +287,10 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
uint32_t *bmap;
logout("\n");
+ if (fix) {
+ return -ENOTSUP;
+ }
+
bmap = g_malloc(s->header.blocks_in_image * sizeof(uint32_t));
memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t));
diff --git a/block_int.h b/block_int.h
index 3d4abc6..1fb5352 100644
--- a/block_int.h
+++ b/block_int.h
@@ -241,7 +241,8 @@ struct BlockDriver {
* Returns 0 for completed check, -errno for internal errors.
* The check results are stored in result.
*/
- int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result);
+ int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
+ BdrvCheckMode fix);
void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 49dce7c..39419a0 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -10,9 +10,9 @@ STEXI
ETEXI
DEF("check", img_check,
- "check [-f fmt] filename")
+ "check [-f fmt] [-r [leaks | all]] filename")
STEXI
-@item check [-f @var{fmt}] @var{filename}
+@item check [-f @var{fmt}] [-r [leaks | all]] @var{filename}
ETEXI
DEF("create", img_create,
diff --git a/qemu-img.c b/qemu-img.c
index c8a70ff..c45ff62 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -85,6 +85,12 @@ static void help(void)
" '-S' indicates the consecutive number of bytes that must contain only zeros\n"
" for qemu-img to create a sparse image during conversion\n"
"\n"
+ "Parameters to check subcommand:\n"
+ " '-r' tries to repair any inconsistencies that are found during the check.\n"
+ " '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
+ " kinds of errors, with a higher risk of choosing the wrong fix or\n"
+ " hiding corruption that has already occured.\n"
+ "\n"
"Parameters to snapshot subcommand:\n"
" 'snapshot' is the name of the snapshot to create, apply or delete\n"
" '-a' applies a snapshot (revert disk to saved state)\n"
@@ -372,10 +378,12 @@ static int img_check(int argc, char **argv)
const char *filename, *fmt;
BlockDriverState *bs;
BdrvCheckResult result;
+ int fix = 0;
+ int flags = BDRV_O_FLAGS;
fmt = NULL;
for(;;) {
- c = getopt(argc, argv, "f:h");
+ c = getopt(argc, argv, "f:hr:");
if (c == -1) {
break;
}
@@ -387,6 +395,17 @@ static int img_check(int argc, char **argv)
case 'f':
fmt = optarg;
break;
+ case 'r':
+ flags |= BDRV_O_RDWR;
+
+ if (!strcmp(optarg, "leaks")) {
+ fix = BDRV_FIX_LEAKS;
+ } else if (!strcmp(optarg, "all")) {
+ fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
+ } else {
+ help();
+ }
+ break;
}
}
if (optind >= argc) {
@@ -394,11 +413,11 @@ static int img_check(int argc, char **argv)
}
filename = argv[optind++];
- bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS);
+ bs = bdrv_new_open(filename, fmt, flags);
if (!bs) {
return 1;
}
- ret = bdrv_check(bs, &result);
+ ret = bdrv_check(bs, &result, fix);
if (ret == -ENOTSUP) {
error_report("This image format does not support checks");
diff --git a/qemu-img.texi b/qemu-img.texi
index 6fc3c28..5a7b2bb 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -70,10 +70,15 @@ lists all snapshots in the given image
Command description:
@table @option
-@item check [-f @var{fmt}] @var{filename}
+@item check [-f @var{fmt}] [-r [leaks | all]] @var{filename}
Perform a consistency check on the disk image @var{filename}.
+If @code{-r} is specified, qemu-img tries to repair any inconsistencies found
+during the check. @code{-r leaks} repairs only cluster leaks, whereas
+@code{-r all} fixes all kinds of errors, with a higher risk of choosing the
+wrong fix or hiding corruption that has already occured.
+
Only the formats @code{qcow2}, @code{qed} and @code{vdi} support
consistency checks.
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 09/12] qemu-img check: Print fixed clusters and recheck
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (7 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 08/12] qemu-img check -r for repairing images Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 10/12] qcow2: Support for fixing refcount inconsistencies Kevin Wolf
` (3 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
When any inconsistencies have been fixed, print the statistics and run
another check to make sure everything is correct now.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.h | 2 ++
block/qed-check.c | 2 ++
qemu-img.c | 10 ++++++++++
3 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/block.h b/block.h
index 61b7e8e..f8200eb 100644
--- a/block.h
+++ b/block.h
@@ -187,6 +187,8 @@ typedef struct BdrvCheckResult {
int corruptions;
int leaks;
int check_errors;
+ int corruptions_fixed;
+ int leaks_fixed;
BlockFragInfo bfi;
} BdrvCheckResult;
diff --git a/block/qed-check.c b/block/qed-check.c
index 94327ff..5edf607 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -87,6 +87,7 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
if (!qed_check_cluster_offset(s, offset)) {
if (check->fix) {
table->offsets[i] = 0;
+ check->result->corruptions_fixed++;
} else {
check->result->corruptions++;
}
@@ -127,6 +128,7 @@ static int qed_check_l1_table(QEDCheck *check, QEDTable *table)
/* Clear invalid offset */
if (check->fix) {
table->offsets[i] = 0;
+ check->result->corruptions_fixed++;
} else {
check->result->corruptions++;
}
diff --git a/qemu-img.c b/qemu-img.c
index c45ff62..9336c86 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -425,6 +425,16 @@ static int img_check(int argc, char **argv)
return 1;
}
+ if (result.corruptions_fixed || result.leaks_fixed) {
+ printf("The following inconsistencies were found and repaired:\n\n"
+ " %d leaked clusters\n"
+ " %d corruptions\n\n"
+ "Double checking the fixed image now...\n",
+ result.leaks_fixed,
+ result.corruptions_fixed);
+ ret = bdrv_check(bs, &result, 0);
+ }
+
if (!(result.corruptions || result.leaks || result.check_errors)) {
printf("No errors were found on the image.\n");
} else {
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 10/12] qcow2: Support for fixing refcount inconsistencies
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (8 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 09/12] qemu-img check: Print fixed clusters and recheck Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 11/12] rbd: hook up cache options Kevin Wolf
` (2 subsequent siblings)
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-refcount.c | 31 +++++++++++++++++++++++++++----
block/qcow2.c | 6 +-----
block/qcow2.h | 3 ++-
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 443c021..3544fcf 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1122,11 +1122,12 @@ fail:
* Returns 0 if no errors are found, the number of errors in case the image is
* detected as corrupted, and -errno when an internal error occurred.
*/
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
+int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix)
{
BDRVQcowState *s = bs->opaque;
- int64_t size;
- int nb_clusters, refcount1, refcount2, i;
+ int64_t size, i;
+ int nb_clusters, refcount1, refcount2;
QCowSnapshot *sn;
uint16_t *refcount_table;
int ret;
@@ -1205,9 +1206,31 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
refcount2 = refcount_table[i];
if (refcount1 != refcount2) {
+
+ /* Check if we're allowed to fix the mismatch */
+ int *num_fixed = NULL;
+ if (refcount1 > refcount2 && (fix & BDRV_FIX_LEAKS)) {
+ num_fixed = &res->leaks_fixed;
+ } else if (refcount1 < refcount2 && (fix & BDRV_FIX_ERRORS)) {
+ num_fixed = &res->corruptions_fixed;
+ }
+
fprintf(stderr, "%s cluster %d refcount=%d reference=%d\n",
- refcount1 < refcount2 ? "ERROR" : "Leaked",
+ num_fixed != NULL ? "Repairing" :
+ refcount1 < refcount2 ? "ERROR" :
+ "Leaked",
i, refcount1, refcount2);
+
+ if (num_fixed) {
+ ret = update_refcount(bs, i << s->cluster_bits, 1,
+ refcount2 - refcount1);
+ if (ret >= 0) {
+ (*num_fixed)++;
+ continue;
+ }
+ }
+
+ /* And if we couldn't, print an error */
if (refcount1 < refcount2) {
res->corruptions++;
} else {
diff --git a/block/qcow2.c b/block/qcow2.c
index 7797015..d66de58 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1473,11 +1473,7 @@ static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
{
- if (fix) {
- return -ENOTSUP;
- }
-
- return qcow2_check_refcounts(bs, result);
+ return qcow2_check_refcounts(bs, result, fix);
}
#if 0
diff --git a/block/qcow2.h b/block/qcow2.h
index 93567f6..c6e7237 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -261,7 +261,8 @@ void qcow2_free_any_clusters(BlockDriverState *bs,
int qcow2_update_snapshot_refcount(BlockDriverState *bs,
int64_t l1_table_offset, int l1_size, int addend);
-int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
+int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
+ BdrvCheckMode fix);
/* qcow2-cluster.c functions */
int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 11/12] rbd: hook up cache options
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (9 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 10/12] qcow2: Support for fixing refcount inconsistencies Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-04 11:13 ` [Qemu-devel] [PATCH 12/12] sheepdog: add coroutine_fn markers to coroutine functions Kevin Wolf
2012-06-07 1:17 ` [Qemu-devel] [PULL 00/12] Block patches Anthony Liguori
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: Josh Durgin <josh.durgin@inktank.com>
Writeback caching was added in Ceph 0.46, and writethrough will be in
0.47. These are controlled by general config options, so there's no
need to check for librbd version.
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/rbd.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/block/rbd.c b/block/rbd.c
index 1280d66..eebc334 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -476,6 +476,25 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
s->snap = g_strdup(snap_buf);
}
+ /*
+ * Fallback to more conservative semantics if setting cache
+ * options fails. Ignore errors from setting rbd_cache because the
+ * only possible error is that the option does not exist, and
+ * librbd defaults to no caching. If write through caching cannot
+ * be set up, fall back to no caching.
+ */
+ if (flags & BDRV_O_NOCACHE) {
+ rados_conf_set(s->cluster, "rbd_cache", "false");
+ } else {
+ rados_conf_set(s->cluster, "rbd_cache", "true");
+ if (!(flags & BDRV_O_CACHE_WB)) {
+ r = rados_conf_set(s->cluster, "rbd_cache_max_dirty", "0");
+ if (r < 0) {
+ rados_conf_set(s->cluster, "rbd_cache", "false");
+ }
+ }
+ }
+
if (strstr(conf, "conf=") == NULL) {
/* try default location, but ignore failure */
rados_conf_read_file(s->cluster, NULL);
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [Qemu-devel] [PATCH 12/12] sheepdog: add coroutine_fn markers to coroutine functions
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (10 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 11/12] rbd: hook up cache options Kevin Wolf
@ 2012-06-04 11:13 ` Kevin Wolf
2012-06-07 1:17 ` [Qemu-devel] [PULL 00/12] Block patches Anthony Liguori
12 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-04 11:13 UTC (permalink / raw)
To: anthony; +Cc: kwolf, qemu-devel
From: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/sheepdog.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/block/sheepdog.c b/block/sheepdog.c
index f46ca8f..8877f45 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -522,8 +522,8 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data,
return ret;
}
-static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
- unsigned int *wlen)
+static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
+ unsigned int *wlen)
{
int ret;
@@ -540,6 +540,7 @@ static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
return ret;
}
+
static int do_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
{
@@ -576,8 +577,8 @@ out:
return ret;
}
-static int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
- unsigned int *wlen, unsigned int *rlen)
+static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
+ unsigned int *wlen, unsigned int *rlen)
{
int ret;
--
1.7.6.5
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PULL 00/12] Block patches
2012-06-04 11:13 [Qemu-devel] [PULL 00/12] Block patches Kevin Wolf
` (11 preceding siblings ...)
2012-06-04 11:13 ` [Qemu-devel] [PATCH 12/12] sheepdog: add coroutine_fn markers to coroutine functions Kevin Wolf
@ 2012-06-07 1:17 ` Anthony Liguori
2012-06-08 9:48 ` Kevin Wolf
12 siblings, 1 reply; 42+ messages in thread
From: Anthony Liguori @ 2012-06-07 1:17 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 06/04/2012 07:13 PM, Kevin Wolf wrote:
> The following changes since commit 8cc9b43f7c5f826b39af4b012ad89bb55faac29c:
>
> target-microblaze: lwx/swx: first implementation (2012-06-04 10:19:46 +0200)
>
> are available in the git repository at:
> git://repo.or.cz/qemu/kevin.git for-anthony
Pulled. Thanks.
Regards,
Anthony Liguori
>
> Josh Durgin (1):
> rbd: hook up cache options
>
> Kevin Wolf (3):
> qemu-img check -r for repairing images
> qemu-img check: Print fixed clusters and recheck
> qcow2: Support for fixing refcount inconsistencies
>
> MORITA Kazutaka (1):
> sheepdog: add coroutine_fn markers to coroutine functions
>
> Markus Armbruster (1):
> Un-inline fdctrl_init_isa()
>
> Paolo Bonzini (4):
> block: implement is_allocated for raw
> stream: tweak usage of bdrv_co_is_allocated
> stream: move is_allocated_above to block.c
> stream: move rate limiting to a separate header file
>
> Zhi Yong Wu (2):
> qcow2: remove a line of unnecessary code
> qcow2: fix the byte endian convertion
>
> block.c | 53 +++++++++++++++++++++-
> block.h | 13 +++++-
> block/qcow2-cluster.c | 1 -
> block/qcow2-refcount.c | 33 ++++++++++++--
> block/qcow2.c | 5 +-
> block/qcow2.h | 3 +-
> block/qed-check.c | 2 +
> block/qed.c | 5 +-
> block/raw-posix.c | 98 +++++++++++++++++++++++++++++++++++++++++
> block/raw.c | 8 +++
> block/rbd.c | 19 ++++++++
> block/sheepdog.c | 9 ++--
> block/stream.c | 109 +++++++---------------------------------------
> block/vdi.c | 7 +++-
> block_int.h | 3 +-
> hw/fdc.c | 20 ++++++++
> hw/fdc.h | 24 +---------
> hw/ide/piix.c | 3 +-
> hw/isa.h | 2 -
> hw/pc_sysfw.c | 1 +
> include/qemu/ratelimit.h | 48 ++++++++++++++++++++
> qemu-common.h | 1 +
> qemu-img-cmds.hx | 4 +-
> qemu-img.c | 35 +++++++++++++-
> qemu-img.texi | 7 +++-
> 25 files changed, 369 insertions(+), 144 deletions(-)
> create mode 100644 include/qemu/ratelimit.h
>
>
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PULL 00/12] Block patches
2012-06-07 1:17 ` [Qemu-devel] [PULL 00/12] Block patches Anthony Liguori
@ 2012-06-08 9:48 ` Kevin Wolf
2012-06-08 14:07 ` Anthony Liguori
0 siblings, 1 reply; 42+ messages in thread
From: Kevin Wolf @ 2012-06-08 9:48 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Am 07.06.2012 03:17, schrieb Anthony Liguori:
> On 06/04/2012 07:13 PM, Kevin Wolf wrote:
>> The following changes since commit 8cc9b43f7c5f826b39af4b012ad89bb55faac29c:
>>
>> target-microblaze: lwx/swx: first implementation (2012-06-04 10:19:46 +0200)
>>
>> are available in the git repository at:
>> git://repo.or.cz/qemu/kevin.git for-anthony
>
> Pulled. Thanks.
But not pushed?
Kevin
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PULL 00/12] Block patches
2012-06-08 9:48 ` Kevin Wolf
@ 2012-06-08 14:07 ` Anthony Liguori
2012-06-08 14:57 ` Kevin Wolf
0 siblings, 1 reply; 42+ messages in thread
From: Anthony Liguori @ 2012-06-08 14:07 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On 06/08/2012 05:48 PM, Kevin Wolf wrote:
> Am 07.06.2012 03:17, schrieb Anthony Liguori:
>> On 06/04/2012 07:13 PM, Kevin Wolf wrote:
>>> The following changes since commit 8cc9b43f7c5f826b39af4b012ad89bb55faac29c:
>>>
>>> target-microblaze: lwx/swx: first implementation (2012-06-04 10:19:46 +0200)
>>>
>>> are available in the git repository at:
>>> git://repo.or.cz/qemu/kevin.git for-anthony
>>
>> Pulled. Thanks.
>
> But not pushed?
I'm having a really hard time connecting to repo.or.cz here. Looks like I
mistook a timeout for success and mistakenly merged nothing.
I'm still having trouble getting to repo.or.cz. I'll be back in the States
Saturday evening so will process this pull Sunday or Monday.
Do you want to update the branch in the interim to fix the build issue?
Regards,
Anthony Liguori
>
> Kevin
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [Qemu-devel] [PULL 00/12] Block patches
2012-06-08 14:07 ` Anthony Liguori
@ 2012-06-08 14:57 ` Kevin Wolf
0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-06-08 14:57 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Am 08.06.2012 16:07, schrieb Anthony Liguori:
> On 06/08/2012 05:48 PM, Kevin Wolf wrote:
>> Am 07.06.2012 03:17, schrieb Anthony Liguori:
>>> On 06/04/2012 07:13 PM, Kevin Wolf wrote:
>>>> The following changes since commit 8cc9b43f7c5f826b39af4b012ad89bb55faac29c:
>>>>
>>>> target-microblaze: lwx/swx: first implementation (2012-06-04 10:19:46 +0200)
>>>>
>>>> are available in the git repository at:
>>>> git://repo.or.cz/qemu/kevin.git for-anthony
>>>
>>> Pulled. Thanks.
>>
>> But not pushed?
>
> I'm having a really hard time connecting to repo.or.cz here. Looks like I
> mistook a timeout for success and mistakenly merged nothing.
>
> I'm still having trouble getting to repo.or.cz. I'll be back in the States
> Saturday evening so will process this pull Sunday or Monday.
Hm, when repo.or.cz started behaving bad, I started to use things like
'while ! git fetch repo.or.cz; do sleep 1; done' (it would always
succeed after a few attempts), but recently it never needed more than
one attempt.
> Do you want to update the branch in the interim to fix the build issue?
Sure, updated it now.
Kevin
^ permalink raw reply [flat|nested] 42+ messages in thread