[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 18/22] parallels: Check unused clusters in parallels_check_lea
From: |
Alexander Ivanov |
Subject: |
[PATCH v5 18/22] parallels: Check unused clusters in parallels_check_leak() |
Date: |
Mon, 11 Mar 2024 19:18:46 +0100 |
Since we have a used bitmap, current leak check is useless. Add
parallels_check_unused_clusters() helper that checks if there are unused
clusters at the end of image and truncates them (if needed). Use it for
leak check and at image inactivation.
In leak check we need to recreate used bitmap because it will be used
during work. At image inactivation we can skip it.
Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
block/parallels.c | 106 +++++++++++++++++++++++++++++-----------------
1 file changed, 68 insertions(+), 38 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 5155b8ac48..fd80179642 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -773,57 +773,89 @@ parallels_check_outside_image(BlockDriverState *bs,
BdrvCheckResult *res,
return 0;
}
+static int64_t GRAPH_RDLOCK
+parallels_check_unused_clusters(BlockDriverState *bs, bool truncate)
+{
+ BDRVParallelsState *s = bs->opaque;
+ int64_t leak, file_size, end_off = 0;
+ int ret;
+
+ file_size = bdrv_getlength(bs->file->bs);
+ if (file_size < 0) {
+ return file_size;
+ }
+
+ if (s->used_bmap_size > 0) {
+ end_off = find_last_bit(s->used_bmap, s->used_bmap_size);
+ if (end_off == s->used_bmap_size) {
+ end_off = 0;
+ } else {
+ end_off = (end_off + 1) * s->cluster_size;
+ }
+ }
+
+ end_off += s->data_start * BDRV_SECTOR_SIZE;
+ leak = file_size - end_off;
+ if (leak < 0) {
+ return -EINVAL;
+ }
+ if (!truncate || leak == 0) {
+ return leak;
+ }
+
+ ret = bdrv_truncate(bs->file, end_off, true, PREALLOC_MODE_OFF, 0, NULL);
+ if (ret) {
+ return ret;
+ }
+
+ s->data_end = end_off / BDRV_SECTOR_SIZE;
+
+ return leak;
+}
+
static int coroutine_fn GRAPH_RDLOCK
parallels_check_leak(BlockDriverState *bs, BdrvCheckResult *res,
BdrvCheckMode fix, bool explicit)
{
BDRVParallelsState *s = bs->opaque;
- int64_t size, count;
+ int64_t leak, count, size;
int ret;
+ leak = parallels_check_unused_clusters(bs, fix & BDRV_FIX_LEAKS);
+ if (leak < 0) {
+ res->check_errors++;
+ return leak;
+ }
+ if (leak == 0) {
+ return 0;
+ }
+
+ parallels_free_used_bitmap(bs);
+ ret = parallels_fill_used_bitmap(bs);
+ if (ret < 0) {
+ res->check_errors++;
+ return ret;
+ }
+
size = bdrv_co_getlength(bs->file->bs);
if (size < 0) {
res->check_errors++;
return size;
}
- if (size <= res->image_end_offset) {
+ res->image_end_offset = size;
+
+ if (!explicit) {
return 0;
}
- count = DIV_ROUND_UP(size - res->image_end_offset, s->cluster_size);
- if (explicit) {
- fprintf(stderr,
- "%s space leaked at the end of the image %" PRId64 "\n",
- fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR",
- size - res->image_end_offset);
- res->leaks += count;
- }
+ count = DIV_ROUND_UP(leak, s->cluster_size);
+ fprintf(stderr,
+ "%s space leaked at the end of the image %" PRId64 "\n",
+ fix & BDRV_FIX_LEAKS ? "Repairing" : "ERROR", leak);
+ res->leaks += count;
+
if (fix & BDRV_FIX_LEAKS) {
- Error *local_err = NULL;
-
- /*
- * In order to really repair the image, we must shrink it.
- * That means we have to pass exact=true.
- */
- ret = bdrv_co_truncate(bs->file, res->image_end_offset, true,
- PREALLOC_MODE_OFF, 0, &local_err);
- if (ret < 0) {
- error_report_err(local_err);
- res->check_errors++;
- return ret;
- }
- s->data_end = res->image_end_offset >> BDRV_SECTOR_BITS;
-
- parallels_free_used_bitmap(bs);
- ret = parallels_fill_used_bitmap(bs);
- if (ret == -ENOMEM) {
- res->check_errors++;
- return ret;
- }
-
- if (explicit) {
- res->leaks_fixed += count;
- }
+ res->leaks_fixed += count;
}
return 0;
@@ -1475,9 +1507,7 @@ static int GRAPH_RDLOCK
parallels_inactivate(BlockDriverState *bs)
s->header->inuse = 0;
parallels_update_header(bs);
- /* errors are ignored, so we might as well pass exact=true */
- ret = bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS,
- true, PREALLOC_MODE_OFF, 0, NULL);
+ ret = parallels_check_unused_clusters(bs, true);
if (ret < 0) {
error_report("Failed to truncate image: %s", strerror(-ret));
}
--
2.40.1
- [PATCH v5 03/22] parallels: Make mark_used() a global function, (continued)
- [PATCH v5 03/22] parallels: Make mark_used() a global function, Alexander Ivanov, 2024/03/11
- [PATCH v5 07/22] parallels: Set data_end value in parallels_check_leak(), Alexander Ivanov, 2024/03/11
- [PATCH v5 05/22] parallels: Add parallels_mark_unused() helper, Alexander Ivanov, 2024/03/11
- [PATCH v5 20/22] tests: Add parallels images support to test 165, Alexander Ivanov, 2024/03/11
- [PATCH v5 21/22] tests: Turned on 256, 299, 304 and block-status-cache for parallels format, Alexander Ivanov, 2024/03/11
- [PATCH v5 01/22] parallels: Set s->used_bmap to NULL in parallels_free_used_bitmap(), Alexander Ivanov, 2024/03/11
- [PATCH v5 12/22] parallels: drop dirty bitmap data if the image was not properly closed, Alexander Ivanov, 2024/03/11
- [PATCH v5 15/22] parallels: Handle L1 entries equal to one, Alexander Ivanov, 2024/03/11
- [PATCH v5 14/22] parallels: Preserve extensions cluster for non-transient extensions, Alexander Ivanov, 2024/03/11
- [PATCH v5 08/22] parallels: Recreate used bitmap in parallels_check_leak(), Alexander Ivanov, 2024/03/11
- [PATCH v5 18/22] parallels: Check unused clusters in parallels_check_leak(),
Alexander Ivanov <=
- [PATCH v5 09/22] parallels: Add a note about used bitmap in parallels_check_duplicate(), Alexander Ivanov, 2024/03/11
- [PATCH v5 04/22] parallels: Limit search in parallels_mark_used to the last marked claster, Alexander Ivanov, 2024/03/11
- [PATCH v5 13/22] parallels: Let image extensions work in RW mode, Alexander Ivanov, 2024/03/11
- [PATCH v5 16/22] parallels: Make a loaded dirty bitmap persistent, Alexander Ivanov, 2024/03/11
- [PATCH v5 06/22] parallels: Move host clusters allocation to a separate function, Alexander Ivanov, 2024/03/11
- [PATCH v5 11/22] parallels: Add dirty bitmaps saving, Alexander Ivanov, 2024/03/11
- [PATCH v5 22/22] tests: Add parallels format support to image-fleecing, Alexander Ivanov, 2024/03/11
- [PATCH v5 10/22] parallels: Create used bitmap even if checks needed, Alexander Ivanov, 2024/03/11
- [PATCH v5 17/22] parallels: Reverse a conditional in parallels_check_leak() to reduce indents, Alexander Ivanov, 2024/03/11
- [PATCH v5 19/22] parallels: Remove unnecessary data_end field, Alexander Ivanov, 2024/03/11