[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 19/27] block/parallels: implement incorrect close de
From: |
Denis V. Lunev |
Subject: |
[Qemu-devel] [PATCH 19/27] block/parallels: implement incorrect close detection |
Date: |
Wed, 11 Mar 2015 13:28:13 +0300 |
The software driver must set inuse field in Parallels header to
0x746F6E59 when the image is opened in read-write mode. The presence of
this magic in the header on open forces image consistency check.
There is an unfortunate trick here. We can not check for inuse in
parallels_check as this will happen too late. It is possible to do
that for simple check, but during the fix this would always report
an error as the image was opened in BDRV_O_RDWR mode. Thus we save
the flag in BDRVParallelsState for this.
On the other hand, nothing should be done to clear inuse in
parallels_check. Generic close will do the job right.
Signed-off-by: Denis V. Lunev <address@hidden>
Reviewed-by: Roman Kagan <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Stefan Hajnoczi <address@hidden>
---
block/parallels.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/block/parallels.c b/block/parallels.c
index 0e5d4c3..bafc74b 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -36,6 +36,7 @@
#define HEADER_MAGIC "WithoutFreeSpace"
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
+#define HEADER_INUSE_MAGIC (0x746F6E59)
#define DEFAULT_CLUSTER_SIZE 1048576 /* 1 MiB */
@@ -59,6 +60,8 @@ typedef struct BDRVParallelsState {
ParallelsHeader *header;
uint32_t header_size;
+ bool header_unclean;
+
uint32_t *bat_bitmap;
unsigned int bat_size;
@@ -246,6 +249,17 @@ static int parallels_check(BlockDriverState *bs,
BdrvCheckResult *res,
return size;
}
+ if (s->header_unclean) {
+ fprintf(stderr, "%s image was not closed correctly\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
+ res->corruptions++;
+ if (fix & BDRV_FIX_ERRORS) {
+ /* parallels_close will do the job right */
+ res->corruptions_fixed++;
+ s->header_unclean = false;
+ }
+ }
+
res->bfi.total_clusters = s->bat_size;
res->bfi.compressed_clusters = 0; /* compression is not supported */
@@ -404,6 +418,17 @@ static int parallels_probe(const uint8_t *buf, int
buf_size,
return 0;
}
+static int parallels_update_header(BlockDriverState *bs)
+{
+ BDRVParallelsState *s = bs->opaque;
+ unsigned size = MAX(bdrv_opt_mem_align(bs->file), sizeof(ParallelsHeader));
+
+ if (size > s->header_size) {
+ size = s->header_size;
+ }
+ return bdrv_pwrite_sync(bs->file, 0, s->header, size);
+}
+
static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -468,6 +493,25 @@ static int parallels_open(BlockDriverState *bs, QDict
*options, int flags,
}
s->bat_bitmap = (uint32_t *)(s->header + 1);
+ if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
+ /* Image was not closed correctly. The check is mandatory */
+ s->header_unclean = true;
+ if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
+ error_setg(errp, "parallels: Image was not closed correctly; "
+ "cannot be opened read/write");
+ ret = -EACCES;
+ goto fail;
+ }
+ }
+
+ if (flags & BDRV_O_RDWR) {
+ s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC);
+ ret = parallels_update_header(bs);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
qemu_co_mutex_init(&s->lock);
return 0;
@@ -483,6 +527,12 @@ fail:
static void parallels_close(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
+
+ if (bs->open_flags & BDRV_O_RDWR) {
+ s->header->inuse = 0;
+ parallels_update_header(bs);
+ }
+
qemu_vfree(s->header);
}
--
1.9.1
- [Qemu-devel] [PATCH 02/27] block/parallels: rename parallels_header to ParallelsHeader, (continued)
- [Qemu-devel] [PATCH 02/27] block/parallels: rename parallels_header to ParallelsHeader, Denis V. Lunev, 2015/03/10
- [Qemu-devel] [PATCH v3 0/27] write/create for Parallels images with reasonable performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 22/27] block/parallels: improve image reading performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 05/27] block/parallels: add get_block_status, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 01/27] iotests, parallels: quote TEST_IMG in 076 test to be path-safe, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 03/27] block/parallels: switch to bdrv_read, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 24/27] block/parallels: delay writing to BAT till bdrv_co_flush_to_os, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 13/27] block/parallels: rename catalog_ names to bat_, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 10/27] block/parallels: support parallels image creation, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 27/27] block/parallels: improve image writing performance further, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 19/27] block/parallels: implement incorrect close detection,
Denis V. Lunev <=
- [Qemu-devel] [PATCH 11/27] iotests, parallels: test for newly created parallels image via qemu-img, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 15/27] block/parallels: keep BAT bitmap data in little endian in memory, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 18/27] block/parallels: implement parallels_check method of block driver, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 08/27] block/parallels: _co_writev callback for Parallels format, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 12/27] parallels: change copyright information in the image header, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 04/27] block/parallels: read up to cluster end in one go, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 14/27] block/parallels: create bat2sect helper, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 07/27] block/parallels: replace magic constants 4, 64 with proper sizeofs, Denis V. Lunev, 2015/03/11