From c518e2cf3c2b7fb08de973478118f18bfc9490cb Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Thu, 13 Nov 2014 04:40:19 +0100 Subject: [PATCH 16/48] block: New bdrv_nb_sectors() Message-id: <1415853625-15050-2-git-send-email-famz@redhat.com> Patchwork-id: 62344 O-Subject: [RHEL-7.1 qemu-kvm-rhev PATCH v3 1/7] block: New bdrv_nb_sectors() Bugzilla: 1132385 RH-Acked-by: Jeffrey Cody RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Max Reitz From: Markus Armbruster A call to retrieve the image size converts between bytes and sectors several times: * BlockDriver method bdrv_getlength() returns bytes. * refresh_total_sectors() converts to sectors, rounding up, and stores in total_sectors. * bdrv_getlength() converts total_sectors back to bytes (now rounded up to a multiple of the sector size). * Callers wanting sectors rather bytes convert it right back. Example: bdrv_get_geometry(). bdrv_nb_sectors() provides a way to omit the last two conversions. It's exactly bdrv_getlength() with the conversion to bytes omitted. It's functionally like bdrv_get_geometry() without its odd error handling. Reimplement bdrv_getlength() and bdrv_get_geometry() on top of bdrv_nb_sectors(). The next patches will convert some users of bdrv_getlength() to bdrv_nb_sectors(). Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Benoit Canet Signed-off-by: Stefan Hajnoczi (cherry picked from commit 65a9bb25d6b7a4bb41edb102fa0363d81800b417) Signed-off-by: Fam Zheng Signed-off-by: Miroslav Rezanina --- block.c | 29 +++++++++++++++++++---------- include/block/block.h | 1 + 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 8a82f8d..cdbdb6b 100644 --- a/block.c +++ b/block.c @@ -701,6 +701,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename, /** * Set the current 'total_sectors' value + * Return 0 on success, -errno on error. */ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint) { @@ -3536,11 +3537,12 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) } /** - * Length of a file in bytes. Return < 0 if error or unknown. + * Return number of sectors on success, -errno on error. */ -int64_t bdrv_getlength(BlockDriverState *bs) +int64_t bdrv_nb_sectors(BlockDriverState *bs) { BlockDriver *drv = bs->drv; + if (!drv) return -ENOMEDIUM; @@ -3550,19 +3552,26 @@ int64_t bdrv_getlength(BlockDriverState *bs) return ret; } } - return bs->total_sectors * BDRV_SECTOR_SIZE; + return bs->total_sectors; +} + +/** + * Return length in bytes on success, -errno on error. + * The length is always a multiple of BDRV_SECTOR_SIZE. + */ +int64_t bdrv_getlength(BlockDriverState *bs) +{ + int64_t ret = bdrv_nb_sectors(bs); + + return ret < 0 ? ret : ret * BDRV_SECTOR_SIZE; } /* return 0 as number of sectors if no device present or error */ void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr) { - int64_t length; - length = bdrv_getlength(bs); - if (length < 0) - length = 0; - else - length = length >> BDRV_SECTOR_BITS; - *nb_sectors_ptr = length; + int64_t nb_sectors = bdrv_nb_sectors(bs); + + *nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors; } void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error, diff --git a/include/block/block.h b/include/block/block.h index f08471d..d4c816d 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -275,6 +275,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); int bdrv_get_backing_file_depth(BlockDriverState *bs); int bdrv_truncate(BlockDriverState *bs, int64_t offset); +int64_t bdrv_nb_sectors(BlockDriverState *bs); int64_t bdrv_getlength(BlockDriverState *bs); int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); -- 1.8.3.1