Message ID | 1425977481-13317-19-git-send-email-den@openvz.org |
---|---|
State | New |
Headers | show |
On Tue, Mar 10, 2015 at 11:51:12AM +0300, Denis V. Lunev wrote: > The check is very simple at the moment. It calculates necessary stats > and fix only the following errors: > - space leak at the end of the image. This would happens due to > preallocation > - clusters outside the image are zeroed. Nothing else could be done here > > Signed-off-by: Denis V. Lunev <den@openvz.org> > CC: Roman Kagan <rkagan@parallels.com> > CC: Kevin Wolf <kwolf@redhat.com> > CC: Stefan Hajnoczi <stefanha@redhat.com> > --- > block/parallels.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 82 insertions(+) > > diff --git a/block/parallels.c b/block/parallels.c > index 65f6418..e5b475e 100644 > --- a/block/parallels.c > +++ b/block/parallels.c > @@ -228,6 +228,87 @@ fail: > return ret; > } > > + > +static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, > + BdrvCheckMode fix) > +{ > + BDRVParallelsState *s = bs->opaque; > + int64_t size, prev_off, high_off; > + int ret; > + uint32_t i; > + bool flush_bat = false; > + int cluster_size = s->tracks << BDRV_SECTOR_BITS; > + > + size = bdrv_getlength(bs->file); > + if (size < 0) { > + res->check_errors++; > + return size; > + } > + > + res->bfi.total_clusters = s->bat_size; > + res->bfi.compressed_clusters = 0; /* compression is not supported */ > + > + high_off = 0; > + prev_off = 0; > + for (i = 0; i < s->bat_size; i++) { > + int64_t off = bat2sect(s, i) << BDRV_SECTOR_BITS; > + if (off == 0) > + continue; If you don't update prev_off here you can get fragmentation stats wrong (dunno how important it is) > + > + /* cluster outside the image */ > + if (off > size) { > + fprintf(stderr, "%s cluster %u is outside image\n", > + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); > + res->corruptions++; > + if (fix & BDRV_FIX_ERRORS) { > + s->bat_bitmap[i] = 0; > + res->corruptions_fixed++; > + flush_bat = true; > + continue; > + } Ditto Roman.
On 10/03/15 17:24, Roman Kagan wrote: > On Tue, Mar 10, 2015 at 11:51:12AM +0300, Denis V. Lunev wrote: >> The check is very simple at the moment. It calculates necessary stats >> and fix only the following errors: >> - space leak at the end of the image. This would happens due to >> preallocation >> - clusters outside the image are zeroed. Nothing else could be done here >> >> Signed-off-by: Denis V. Lunev <den@openvz.org> >> CC: Roman Kagan <rkagan@parallels.com> >> CC: Kevin Wolf <kwolf@redhat.com> >> CC: Stefan Hajnoczi <stefanha@redhat.com> >> --- >> block/parallels.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 82 insertions(+) >> >> diff --git a/block/parallels.c b/block/parallels.c >> index 65f6418..e5b475e 100644 >> --- a/block/parallels.c >> +++ b/block/parallels.c >> @@ -228,6 +228,87 @@ fail: >> return ret; >> } >> >> + >> +static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, >> + BdrvCheckMode fix) >> +{ >> + BDRVParallelsState *s = bs->opaque; >> + int64_t size, prev_off, high_off; >> + int ret; >> + uint32_t i; >> + bool flush_bat = false; >> + int cluster_size = s->tracks << BDRV_SECTOR_BITS; >> + >> + size = bdrv_getlength(bs->file); >> + if (size < 0) { >> + res->check_errors++; >> + return size; >> + } >> + >> + res->bfi.total_clusters = s->bat_size; >> + res->bfi.compressed_clusters = 0; /* compression is not supported */ >> + >> + high_off = 0; >> + prev_off = 0; >> + for (i = 0; i < s->bat_size; i++) { >> + int64_t off = bat2sect(s, i) << BDRV_SECTOR_BITS; >> + if (off == 0) >> + continue; > If you don't update prev_off here you can get fragmentation stats wrong > (dunno how important it is) ok. by the way, I have missed braces here... >> + >> + /* cluster outside the image */ >> + if (off > size) { >> + fprintf(stderr, "%s cluster %u is outside image\n", >> + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); >> + res->corruptions++; >> + if (fix & BDRV_FIX_ERRORS) { >> + s->bat_bitmap[i] = 0; >> + res->corruptions_fixed++; >> + flush_bat = true; >> + continue; >> + } > Ditto > > Roman.
diff --git a/block/parallels.c b/block/parallels.c index 65f6418..e5b475e 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -228,6 +228,87 @@ fail: return ret; } + +static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res, + BdrvCheckMode fix) +{ + BDRVParallelsState *s = bs->opaque; + int64_t size, prev_off, high_off; + int ret; + uint32_t i; + bool flush_bat = false; + int cluster_size = s->tracks << BDRV_SECTOR_BITS; + + size = bdrv_getlength(bs->file); + if (size < 0) { + res->check_errors++; + return size; + } + + res->bfi.total_clusters = s->bat_size; + res->bfi.compressed_clusters = 0; /* compression is not supported */ + + high_off = 0; + prev_off = 0; + for (i = 0; i < s->bat_size; i++) { + int64_t off = bat2sect(s, i) << BDRV_SECTOR_BITS; + if (off == 0) + continue; + + /* cluster outside the image */ + if (off > size) { + fprintf(stderr, "%s cluster %u is outside image\n", + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); + res->corruptions++; + if (fix & BDRV_FIX_ERRORS) { + s->bat_bitmap[i] = 0; + res->corruptions_fixed++; + flush_bat = true; + continue; + } + } + + res->bfi.allocated_clusters++; + if (off > high_off) { + high_off = off; + } + + if (prev_off != 0 && (prev_off + cluster_size) != off) { + res->bfi.fragmented_clusters++; + } + prev_off = off; + } + + if (flush_bat) { + ret = bdrv_pwrite_sync(bs->file, 0, s->header, s->header_size); + if (ret < 0) { + res->check_errors++; + return ret; + } + } + + res->image_end_offset = high_off + cluster_size; + if (size > res->image_end_offset) { + int64_t count; + count = DIV_ROUND_UP(size - res->image_end_offset, cluster_size); + 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; + if (fix & BDRV_FIX_LEAKS) { + ret = bdrv_truncate(bs->file, res->image_end_offset); + if (ret < 0) { + res->check_errors++; + return ret; + } + res->leaks_fixed += count; + } + } + + return 0; +} + + static int parallels_create(const char *filename, QemuOpts *opts, Error **errp) { int64_t total_size, cl_size; @@ -429,6 +510,7 @@ static BlockDriver bdrv_parallels = { .bdrv_co_writev = parallels_co_writev, .bdrv_create = parallels_create, + .bdrv_check = parallels_check, .create_opts = ¶llels_create_opts, };
The check is very simple at the moment. It calculates necessary stats and fix only the following errors: - space leak at the end of the image. This would happens due to preallocation - clusters outside the image are zeroed. Nothing else could be done here Signed-off-by: Denis V. Lunev <den@openvz.org> CC: Roman Kagan <rkagan@parallels.com> CC: Kevin Wolf <kwolf@redhat.com> CC: Stefan Hajnoczi <stefanha@redhat.com> --- block/parallels.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+)