[{"id":1775008,"web_url":"http://patchwork.ozlabs.org/comment/1775008/","msgid":"<8ded19fb-d0dc-d816-b045-07184bf77db3@redhat.com>","list_archive_url":null,"date":"2017-09-25T22:43:37","subject":"Re: [Qemu-devel] [PATCH v4 01/23] block: Allow NULL file for\n\tbdrv_get_block_status()","submitter":{"id":64343,"url":"http://patchwork.ozlabs.org/api/people/64343/","name":"John Snow","email":"jsnow@redhat.com"},"content":"On 09/13/2017 12:03 PM, Eric Blake wrote:\n> Not all callers care about which BDS owns the mapping for a given\n> range of the file.  This patch merely simplifies the callers by\n> consolidating the logic in the common call point, while guaranteeing\n> a non-NULL file to all the driver callbacks, for no semantic change.\n> The only caller that does not care about pnum is bdrv_is_allocated,\n> as invoked by vvfat; we can likewise add assertions that the rest\n> of the stack does not have to worry about a NULL pnum.\n> \n> Furthermore, this will also set the stage for a future cleanup: when\n> a caller does not care about which BDS owns an offset, it would be\n> nice to allow the driver to optimize things to not have to return\n> BDRV_BLOCK_OFFSET_VALID in the first place.  In the case of fragmented\n> allocation (for example, it's fairly easy to create a qcow2 image\n> where consecutive guest addresses are not at consecutive host\n> addresses), the current contract requires bdrv_get_block_status()\n> to clamp *pnum to the limit where host addresses are no longer\n> consecutive, but allowing a NULL file means that *pnum could be\n> set to the full length of known-allocated data.\n> \n> Signed-off-by: Eric Blake <eblake@redhat.com>\n> \n> ---\n> v4: only context changes\n> v3: rebase to recent changes (qcow2_measure), dropped R-b\n> v2: use local variable and final transfer, rather than assignment\n> of parameter to local\n> [previously in different series]:\n> v2: new patch, https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg05645.html\n> ---\n>  include/block/block_int.h | 10 ++++++----\n>  block/io.c                | 44 ++++++++++++++++++++++++++++----------------\n>  block/mirror.c            |  3 +--\n>  block/qcow2.c             |  8 ++------\n>  qemu-img.c                | 10 ++++------\n>  5 files changed, 41 insertions(+), 34 deletions(-)\n> \n> diff --git a/include/block/block_int.h b/include/block/block_int.h\n> index 55c5d573d4..7f71c585a0 100644\n> --- a/include/block/block_int.h\n> +++ b/include/block/block_int.h\n> @@ -202,10 +202,12 @@ struct BlockDriver {\n>          int64_t offset, int bytes);\n> \n>      /*\n> -     * Building block for bdrv_block_status[_above]. The driver should\n> -     * answer only according to the current layer, and should not\n> -     * set BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW.  See block.h\n> -     * for the meaning of _DATA, _ZERO, and _OFFSET_VALID.\n> +     * Building block for bdrv_block_status[_above] and\n> +     * bdrv_is_allocated[_above].  The driver should answer only\n> +     * according to the current layer, and should not set\n> +     * BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW.  See block.h\n> +     * for the meaning of _DATA, _ZERO, and _OFFSET_VALID.  The block\n> +     * layer guarantees non-NULL pnum and file.\n>       */\n>      int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,\n>          int64_t sector_num, int nb_sectors, int *pnum,\n> diff --git a/block/io.c b/block/io.c\n> index 8a0cd8835a..f250029395 100644\n> --- a/block/io.c\n> +++ b/block/io.c\n> @@ -695,7 +695,6 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)\n>  {\n>      int64_t target_sectors, ret, nb_sectors, sector_num = 0;\n>      BlockDriverState *bs = child->bs;\n> -    BlockDriverState *file;\n>      int n;\n> \n>      target_sectors = bdrv_nb_sectors(bs);\n> @@ -708,7 +707,7 @@ int bdrv_make_zero(BdrvChild *child, BdrvRequestFlags flags)\n>          if (nb_sectors <= 0) {\n>              return 0;\n>          }\n> -        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, &file);\n> +        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n, NULL);\n>          if (ret < 0) {\n>              error_report(\"error getting block status at sector %\" PRId64 \": %s\",\n>                           sector_num, strerror(-ret));\n> @@ -1755,8 +1754,9 @@ int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,\n>   * beyond the end of the disk image it will be clamped; if 'pnum' is set to\n>   * the end of the image, then the returned value will include BDRV_BLOCK_EOF.\n>   *\n> - * If returned value is positive and BDRV_BLOCK_OFFSET_VALID bit is set, 'file'\n> - * points to the BDS which the sector range is allocated in.\n> + * If returned value is positive, BDRV_BLOCK_OFFSET_VALID bit is set, and\n> + * 'file' is non-NULL, then '*file' points to the BDS which the sector range\n> + * is allocated in.\n>   */\n>  static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,\n>                                                       int64_t sector_num,\n> @@ -1766,15 +1766,22 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,\n>      int64_t total_sectors;\n>      int64_t n;\n>      int64_t ret, ret2;\n> +    BlockDriverState *local_file = NULL;\n> \n> -    *file = NULL;\n> +    assert(pnum);\n\nnice assert..\n\n>      total_sectors = bdrv_nb_sectors(bs);\n>      if (total_sectors < 0) {\n> +        if (file) {\n> +            *file = NULL;\n> +        }\n\nFunction reads slightly worse for the wear now with all of the return\nlogic handled at various places within, but unifying it might be even\nstranger, perhaps..\n\nLet's see if I hate this more:\n\nout:\nbdrv_dec_in_flight(bs);\n    bdrv_dec_in_flight(bs);\n    if (ret >= 0 && sector_num + *pnum == total_sectors) {\n        ret |= BDRV_BLOCK_EOF;\n    }\nearly_out:\n    if (file) {\n        *file = local_file;\n    }\n    return ret;\n\n\nand then earlier in the function, we can just:\n\nif (total_sectors < 0) {\n  ret = total_sectors;\n  goto early_out;\n}\n\n>          return total_sectors;\n>      }\n> \n>      if (sector_num >= total_sectors) {\n>          *pnum = 0;\n> +        if (file) {\n> +            *file = NULL;\n> +        }\n\nret = BDRV_BLOCK_EOF;\ngoto early_out;\n\n>          return BDRV_BLOCK_EOF;\n>      }\n> \n> @@ -1791,23 +1798,27 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,\n>          }\n>          if (bs->drv->protocol_name) {\n>              ret |= BDRV_BLOCK_OFFSET_VALID | (sector_num * BDRV_SECTOR_SIZE);\n> -            *file = bs;\n> +            if (file) {\n> +                *file = bs;\n> +            }\n\nlocal_file = bs;\n\n> +        } else if (file) {\n> +            *file = NULL;\n\nno longer needed\n\n>          }\n>          return ret;\n\nreplaced with:\n\ngoto early_out;\n\n>      }\n> \n>      bdrv_inc_in_flight(bs);\n>      ret = bs->drv->bdrv_co_get_block_status(bs, sector_num, nb_sectors, pnum,\n> -                                            file);\n> +                                            &local_file);\n>      if (ret < 0) {\n>          *pnum = 0;\n>          goto out;\n>      }\n> \n>      if (ret & BDRV_BLOCK_RAW) {\n> -        assert(ret & BDRV_BLOCK_OFFSET_VALID && *file);\n> -        ret = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,\n> -                                       *pnum, pnum, file);\n> +        assert(ret & BDRV_BLOCK_OFFSET_VALID && local_file);\n> +        ret = bdrv_co_get_block_status(local_file, ret >> BDRV_SECTOR_BITS,\n> +                                       *pnum, pnum, &local_file);\n>          goto out;\n>      }\n> \n> @@ -1825,14 +1836,13 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,\n>          }\n>      }\n> \n> -    if (*file && *file != bs &&\n> +    if (local_file && local_file != bs &&\n>          (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&\n>          (ret & BDRV_BLOCK_OFFSET_VALID)) {\n> -        BlockDriverState *file2;\n>          int file_pnum;\n> \n> -        ret2 = bdrv_co_get_block_status(*file, ret >> BDRV_SECTOR_BITS,\n> -                                        *pnum, &file_pnum, &file2);\n> +        ret2 = bdrv_co_get_block_status(local_file, ret >> BDRV_SECTOR_BITS,\n> +                                        *pnum, &file_pnum, NULL);\n>          if (ret2 >= 0) {\n>              /* Ignore errors.  This is just providing extra information, it\n>               * is useful but not necessary.\n> @@ -1854,6 +1864,9 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,\n>      }\n> \n>  out:\n> +    if (file) {\n> +        *file = local_file;\n> +    }\n>      bdrv_dec_in_flight(bs);\n>      if (ret >= 0 && sector_num + *pnum == total_sectors) {\n>          ret |= BDRV_BLOCK_EOF;\n> @@ -1957,7 +1970,6 @@ int64_t bdrv_get_block_status(BlockDriverState *bs,\n>  int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,\n>                                     int64_t bytes, int64_t *pnum)\n>  {\n> -    BlockDriverState *file;\n>      int64_t sector_num = offset >> BDRV_SECTOR_BITS;\n>      int nb_sectors = bytes >> BDRV_SECTOR_BITS;\n>      int64_t ret;\n> @@ -1966,7 +1978,7 @@ int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,\n>      assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));\n>      assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE) && bytes < INT_MAX);\n>      ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &psectors,\n> -                                &file);\n> +                                NULL);\n>      if (ret < 0) {\n>          return ret;\n>      }\n> diff --git a/block/mirror.c b/block/mirror.c\n> index 5cdaaed7be..032cfe91fa 100644\n> --- a/block/mirror.c\n> +++ b/block/mirror.c\n> @@ -390,7 +390,6 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)\n>          int io_sectors;\n>          unsigned int io_bytes;\n>          int64_t io_bytes_acct;\n> -        BlockDriverState *file;\n>          enum MirrorMethod {\n>              MIRROR_METHOD_COPY,\n>              MIRROR_METHOD_ZERO,\n> @@ -401,7 +400,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)\n>          ret = bdrv_get_block_status_above(source, NULL,\n>                                            offset >> BDRV_SECTOR_BITS,\n>                                            nb_chunks * sectors_per_chunk,\n> -                                          &io_sectors, &file);\n> +                                          &io_sectors, NULL);\n>          io_bytes = io_sectors * BDRV_SECTOR_SIZE;\n>          if (ret < 0) {\n>              io_bytes = MIN(nb_chunks * s->granularity, max_io_bytes);\n> diff --git a/block/qcow2.c b/block/qcow2.c\n> index 64dcd98a91..9a7b5cd41f 100644\n> --- a/block/qcow2.c\n> +++ b/block/qcow2.c\n> @@ -2975,7 +2975,6 @@ static bool is_zero_sectors(BlockDriverState *bs, int64_t start,\n>                              uint32_t count)\n>  {\n>      int nr;\n> -    BlockDriverState *file;\n>      int64_t res;\n> \n>      if (start + count > bs->total_sectors) {\n> @@ -2985,8 +2984,7 @@ static bool is_zero_sectors(BlockDriverState *bs, int64_t start,\n>      if (!count) {\n>          return true;\n>      }\n> -    res = bdrv_get_block_status_above(bs, NULL, start, count,\n> -                                      &nr, &file);\n> +    res = bdrv_get_block_status_above(bs, NULL, start, count, &nr, NULL);\n>      return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count;\n>  }\n> \n> @@ -3654,13 +3652,11 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,\n>                   offset += pnum * BDRV_SECTOR_SIZE) {\n>                  int nb_sectors = MIN(ssize - offset,\n>                                       BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE;\n> -                BlockDriverState *file;\n>                  int64_t ret;\n> \n>                  ret = bdrv_get_block_status_above(in_bs, NULL,\n>                                                    offset >> BDRV_SECTOR_BITS,\n> -                                                  nb_sectors,\n> -                                                  &pnum, &file);\n> +                                                  nb_sectors, &pnum, NULL);\n>                  if (ret < 0) {\n>                      error_setg_errno(&local_err, -ret,\n>                                       \"Unable to get block status\");\n> diff --git a/qemu-img.c b/qemu-img.c\n> index df984b11b9..0c12e1c240 100644\n> --- a/qemu-img.c\n> +++ b/qemu-img.c\n> @@ -1374,7 +1374,6 @@ static int img_compare(int argc, char **argv)\n> \n>      for (;;) {\n>          int64_t status1, status2;\n> -        BlockDriverState *file;\n> \n>          nb_sectors = sectors_to_process(total_sectors, sector_num);\n>          if (nb_sectors <= 0) {\n> @@ -1382,7 +1381,7 @@ static int img_compare(int argc, char **argv)\n>          }\n>          status1 = bdrv_get_block_status_above(bs1, NULL, sector_num,\n>                                                total_sectors1 - sector_num,\n> -                                              &pnum1, &file);\n> +                                              &pnum1, NULL);\n>          if (status1 < 0) {\n>              ret = 3;\n>              error_report(\"Sector allocation test failed for %s\", filename1);\n> @@ -1392,7 +1391,7 @@ static int img_compare(int argc, char **argv)\n> \n>          status2 = bdrv_get_block_status_above(bs2, NULL, sector_num,\n>                                                total_sectors2 - sector_num,\n> -                                              &pnum2, &file);\n> +                                              &pnum2, NULL);\n>          if (status2 < 0) {\n>              ret = 3;\n>              error_report(\"Sector allocation test failed for %s\", filename2);\n> @@ -1598,15 +1597,14 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)\n>      n = MIN(s->total_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS);\n> \n>      if (s->sector_next_status <= sector_num) {\n> -        BlockDriverState *file;\n>          if (s->target_has_backing) {\n>              ret = bdrv_get_block_status(blk_bs(s->src[src_cur]),\n>                                          sector_num - src_cur_offset,\n> -                                        n, &n, &file);\n> +                                        n, &n, NULL);\n>          } else {\n>              ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL,\n>                                                sector_num - src_cur_offset,\n> -                                              n, &n, &file);\n> +                                              n, &n, NULL);\n>          }\n>          if (ret < 0) {\n>              return ret;\n> \n\nIt's only shed paint, though:\n\nReviewed-by: John Snow <jsnow@redhat.com>\n\nI'm looking at the rest of the series now, so please stand by.","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)","ext-mx07.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com","ext-mx07.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=jsnow@redhat.com"],"Received":["from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3y1Jzp3RPDz9sRV\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 26 Sep 2017 08:44:22 +1000 (AEST)","from localhost ([::1]:44636 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dwc6u-0006z0-JW\n\tfor incoming@patchwork.ozlabs.org; Mon, 25 Sep 2017 18:44:20 -0400","from eggs.gnu.org ([2001:4830:134:3::10]:37104)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <jsnow@redhat.com>) id 1dwc6S-0006xm-Ah\n\tfor qemu-devel@nongnu.org; Mon, 25 Sep 2017 18:43:54 -0400","from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <jsnow@redhat.com>) id 1dwc6Q-0006rl-4r\n\tfor qemu-devel@nongnu.org; Mon, 25 Sep 2017 18:43:52 -0400","from mx1.redhat.com ([209.132.183.28]:49778)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <jsnow@redhat.com>)\n\tid 1dwc6K-0006qZ-AG; Mon, 25 Sep 2017 18:43:44 -0400","from smtp.corp.redhat.com\n\t(int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 26431C047B71;\n\tMon, 25 Sep 2017 22:43:43 +0000 (UTC)","from [10.18.17.130] (dhcp-17-130.bos.redhat.com [10.18.17.130])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 2A5CD67546;\n\tMon, 25 Sep 2017 22:43:37 +0000 (UTC)"],"DMARC-Filter":"OpenDMARC Filter v1.3.2 mx1.redhat.com 26431C047B71","To":"Eric Blake <eblake@redhat.com>, qemu-devel@nongnu.org","References":"<20170913160333.23622-1-eblake@redhat.com>\n\t<20170913160333.23622-2-eblake@redhat.com>","From":"John Snow <jsnow@redhat.com>","Message-ID":"<8ded19fb-d0dc-d816-b045-07184bf77db3@redhat.com>","Date":"Mon, 25 Sep 2017 18:43:37 -0400","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.3.0","MIME-Version":"1.0","In-Reply-To":"<20170913160333.23622-2-eblake@redhat.com>","Content-Type":"text/plain; charset=utf-8","Content-Language":"en-US","Content-Transfer-Encoding":"7bit","X-Scanned-By":"MIMEDefang 2.79 on 10.5.11.11","X-Greylist":"Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.31]);\n\tMon, 25 Sep 2017 22:43:43 +0000 (UTC)","X-detected-operating-system":"by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]","X-Received-From":"209.132.183.28","Subject":"Re: [Qemu-devel] [PATCH v4 01/23] block: Allow NULL file for\n\tbdrv_get_block_status()","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.21","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<http://lists.nongnu.org/archive/html/qemu-devel/>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Cc":"kwolf@redhat.com, famz@redhat.com, qemu-block@nongnu.org,\n\tJeff Cody <jcody@redhat.com>, Max Reitz <mreitz@redhat.com>,\n\tStefan Hajnoczi <stefanha@redhat.com>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"}},{"id":1776641,"web_url":"http://patchwork.ozlabs.org/comment/1776641/","msgid":"<fce419bf-ab25-bffc-6324-b67df444abaf@redhat.com>","list_archive_url":null,"date":"2017-09-27T21:46:14","subject":"Re: [Qemu-devel] [PATCH v4 01/23] block: Allow NULL file for\n\tbdrv_get_block_status()","submitter":{"id":6591,"url":"http://patchwork.ozlabs.org/api/people/6591/","name":"Eric Blake","email":"eblake@redhat.com"},"content":"On 09/25/2017 05:43 PM, John Snow wrote:\n> \n> \n> On 09/13/2017 12:03 PM, Eric Blake wrote:\n>> Not all callers care about which BDS owns the mapping for a given\n>> range of the file.  This patch merely simplifies the callers by\n>> consolidating the logic in the common call point, while guaranteeing\n>> a non-NULL file to all the driver callbacks, for no semantic change.\n>> The only caller that does not care about pnum is bdrv_is_allocated,\n>> as invoked by vvfat; we can likewise add assertions that the rest\n>> of the stack does not have to worry about a NULL pnum.\n>>\n>> Furthermore, this will also set the stage for a future cleanup: when\n>> a caller does not care about which BDS owns an offset, it would be\n>> nice to allow the driver to optimize things to not have to return\n>> BDRV_BLOCK_OFFSET_VALID in the first place.  In the case of fragmented\n>> allocation (for example, it's fairly easy to create a qcow2 image\n>> where consecutive guest addresses are not at consecutive host\n>> addresses), the current contract requires bdrv_get_block_status()\n>> to clamp *pnum to the limit where host addresses are no longer\n>> consecutive, but allowing a NULL file means that *pnum could be\n>> set to the full length of known-allocated data.\n>>\n> \n> Function reads slightly worse for the wear now with all of the return\n> logic handled at various places within, but unifying it might be even\n> stranger, perhaps..\n> \n> Let's see if I hate this more:\n> \n> out:\n> bdrv_dec_in_flight(bs);\n>     bdrv_dec_in_flight(bs);\n>     if (ret >= 0 && sector_num + *pnum == total_sectors) {\n>         ret |= BDRV_BLOCK_EOF;\n>     }\n> early_out:\n>     if (file) {\n>         *file = local_file;\n>     }\n>     return ret;\n> \n> \n> and then earlier in the function, we can just:\n> \n> if (total_sectors < 0) {\n>   ret = total_sectors;\n>   goto early_out;\n> }\n\nSeems reasonable enough, I'll work that in to v5, since there are other\nreasons to respin the series anyway.\n\n> \n> It's only shed paint, though:\n> \n> Reviewed-by: John Snow <jsnow@redhat.com>\n> \n> I'm looking at the rest of the series now, so please stand by.\n>","headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@bilbo.ozlabs.org","Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)","ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com","ext-mx04.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=eblake@redhat.com"],"Received":["from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3y2WdL6LXpz9ryT\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 28 Sep 2017 07:47:34 +1000 (AEST)","from localhost ([::1]:56470 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dxKB3-00033h-2G\n\tfor incoming@patchwork.ozlabs.org; Wed, 27 Sep 2017 17:47:33 -0400","from eggs.gnu.org ([2001:4830:134:3::10]:47744)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <eblake@redhat.com>) id 1dxKAX-00031O-54\n\tfor qemu-devel@nongnu.org; Wed, 27 Sep 2017 17:47:02 -0400","from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <eblake@redhat.com>) id 1dxKAV-0008Pd-Uz\n\tfor qemu-devel@nongnu.org; Wed, 27 Sep 2017 17:47:01 -0400","from mx1.redhat.com ([209.132.183.28]:55934)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <eblake@redhat.com>)\n\tid 1dxKAQ-0008MD-B0; Wed, 27 Sep 2017 17:46:54 -0400","from smtp.corp.redhat.com\n\t(int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 54E4A14C5B6;\n\tWed, 27 Sep 2017 21:46:53 +0000 (UTC)","from [10.10.124.97] (ovpn-124-97.rdu2.redhat.com [10.10.124.97])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id A709280E77;\n\tWed, 27 Sep 2017 21:46:15 +0000 (UTC)"],"DMARC-Filter":"OpenDMARC Filter v1.3.2 mx1.redhat.com 54E4A14C5B6","To":"John Snow <jsnow@redhat.com>, qemu-devel@nongnu.org","References":"<20170913160333.23622-1-eblake@redhat.com>\n\t<20170913160333.23622-2-eblake@redhat.com>\n\t<8ded19fb-d0dc-d816-b045-07184bf77db3@redhat.com>","From":"Eric Blake <eblake@redhat.com>","Openpgp":"url=http://people.redhat.com/eblake/eblake.gpg","Organization":"Red Hat, Inc.","Message-ID":"<fce419bf-ab25-bffc-6324-b67df444abaf@redhat.com>","Date":"Wed, 27 Sep 2017 16:46:14 -0500","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tThunderbird/52.3.0","MIME-Version":"1.0","In-Reply-To":"<8ded19fb-d0dc-d816-b045-07184bf77db3@redhat.com>","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\";\n\tboundary=\"SxATl5241CbuK4vBn211jBuTEiNLgtUNe\"","X-Scanned-By":"MIMEDefang 2.79 on 10.5.11.12","X-Greylist":"Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.28]);\n\tWed, 27 Sep 2017 21:46:53 +0000 (UTC)","X-detected-operating-system":"by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]","X-Received-From":"209.132.183.28","X-Content-Filtered-By":"Mailman/MimeDel 2.1.21","Subject":"Re: [Qemu-devel] [PATCH v4 01/23] block: Allow NULL file for\n\tbdrv_get_block_status()","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.21","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<http://lists.nongnu.org/archive/html/qemu-devel/>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Cc":"kwolf@redhat.com, famz@redhat.com, qemu-block@nongnu.org,\n\tJeff Cody <jcody@redhat.com>, Max Reitz <mreitz@redhat.com>,\n\tStefan Hajnoczi <stefanha@redhat.com>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"}}]