Re: [Qemu-block] [PATCH v2 14/15] block: Align block status requests

2017-07-05 Thread Fam Zheng
On Wed, 07/05 07:01, Eric Blake wrote:
> On 07/04/2017 04:44 AM, Fam Zheng wrote:
> > On Mon, 07/03 17:14, Eric Blake wrote:
> >> Any device that has request_alignment greater than 512 should be
> >> unable to report status at a finer granularity; it may also be
> >> simpler for such devices to be guaranteed that the block layer
> >> has rounded things out to the granularity boundary (the way the
> >> block layer already rounds all other I/O out).  Besides, getting
> >> the code correct for super-sector alignment also benefits us
> >> for the fact that our public interface now has byte granularity,
> >> even though none of our drivers have byte-level callbacks.
> >>
> >> Add an assertion in blkdebug that proves that the block layer
> >> never requests status of unaligned sections, similar to what it
> >> does on other requests (while still keeping the generic helper
> >> in place for when future patches add a throttle driver).  Note
> >> note that iotest 177 already covers this (it would fail if you
> > 
> > Drop one "note"?
> 
> Indeed. There are studies on how people read that show that redundant
> words that cross a line boundaries are the most easy to mentally overlook.
> 
> 
> >> +/* Round out to request_alignment boundaries */
> >> +align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
> >> +aligned_offset = QEMU_ALIGN_DOWN(offset, align);
> >> +aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
> >> +
> >> +{
> > 
> > Not sure why using a {} block here?
> > 
> >> +int count; /* sectors */
> 
> Because it makes it easier (less indentation churn) to delete the code
> when series 4 later deletes the .bdrv_co_get_block_status sector-based
> callback in favor of the newer .bdrv_co_block_status byte-based (patch
> 16/15 which start series 4 turns it into an if statement, then a later
> patch deletes the entire conditional); it is also justifiable because it
> creates a tighter scope for 'int count' which is needed only on the
> boundary of sector-based operations when the rest of the function is
> byte-based (rather than declaring the helper variable up front).  I'll
> have to call it out more specifically in the commit message as intentional.

Thanks for explaining, with the syntax error fixed in the commit message:

Reviewed-by: Fam Zheng 



Re: [Qemu-block] [PATCH v2 14/15] block: Align block status requests

2017-07-05 Thread Eric Blake
On 07/04/2017 04:44 AM, Fam Zheng wrote:
> On Mon, 07/03 17:14, Eric Blake wrote:
>> Any device that has request_alignment greater than 512 should be
>> unable to report status at a finer granularity; it may also be
>> simpler for such devices to be guaranteed that the block layer
>> has rounded things out to the granularity boundary (the way the
>> block layer already rounds all other I/O out).  Besides, getting
>> the code correct for super-sector alignment also benefits us
>> for the fact that our public interface now has byte granularity,
>> even though none of our drivers have byte-level callbacks.
>>
>> Add an assertion in blkdebug that proves that the block layer
>> never requests status of unaligned sections, similar to what it
>> does on other requests (while still keeping the generic helper
>> in place for when future patches add a throttle driver).  Note
>> note that iotest 177 already covers this (it would fail if you
> 
> Drop one "note"?

Indeed. There are studies on how people read that show that redundant
words that cross a line boundaries are the most easy to mentally overlook.


>> +/* Round out to request_alignment boundaries */
>> +align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
>> +aligned_offset = QEMU_ALIGN_DOWN(offset, align);
>> +aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
>> +
>> +{
> 
> Not sure why using a {} block here?
> 
>> +int count; /* sectors */

Because it makes it easier (less indentation churn) to delete the code
when series 4 later deletes the .bdrv_co_get_block_status sector-based
callback in favor of the newer .bdrv_co_block_status byte-based (patch
16/15 which start series 4 turns it into an if statement, then a later
patch deletes the entire conditional); it is also justifiable because it
creates a tighter scope for 'int count' which is needed only on the
boundary of sector-based operations when the rest of the function is
byte-based (rather than declaring the helper variable up front).  I'll
have to call it out more specifically in the commit message as intentional.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-block] [PATCH v2 14/15] block: Align block status requests

2017-07-04 Thread Fam Zheng
On Mon, 07/03 17:14, Eric Blake wrote:
> Any device that has request_alignment greater than 512 should be
> unable to report status at a finer granularity; it may also be
> simpler for such devices to be guaranteed that the block layer
> has rounded things out to the granularity boundary (the way the
> block layer already rounds all other I/O out).  Besides, getting
> the code correct for super-sector alignment also benefits us
> for the fact that our public interface now has byte granularity,
> even though none of our drivers have byte-level callbacks.
> 
> Add an assertion in blkdebug that proves that the block layer
> never requests status of unaligned sections, similar to what it
> does on other requests (while still keeping the generic helper
> in place for when future patches add a throttle driver).  Note
> note that iotest 177 already covers this (it would fail if you

Drop one "note"?

> use just the blkdebug.c hunk without the io.c changes).
> Meanwhile, we can drop assertions in callers that no longer have
> to pass in sector-aligned addresses.
> 
> Signed-off-by: Eric Blake 
> 
> ---
> v2: new patch
> ---
>  include/block/block_int.h |  3 ++-
>  block/blkdebug.c  | 13 +++-
>  block/io.c| 53 
> ---
>  3 files changed, 50 insertions(+), 19 deletions(-)
> 
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index ffa22c7..5f6ba5d 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -173,7 +173,8 @@ struct BlockDriver {
>   * according to the current layer, and should not set
>   * BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW.  See block.h
>   * for the meaning of _DATA, _ZERO, and _OFFSET_VALID.  The block
> - * layer guarantees non-NULL pnum and file.
> + * layer guarantees input aligned to request_alignment, as well as
> + * non-NULL pnum and file.
>   */
>  int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
>  int64_t sector_num, int nb_sectors, int *pnum,
> diff --git a/block/blkdebug.c b/block/blkdebug.c
> index f1539db..67736b4 100644
> --- a/block/blkdebug.c
> +++ b/block/blkdebug.c
> @@ -641,6 +641,17 @@ static int coroutine_fn 
> blkdebug_co_pdiscard(BlockDriverState *bs,
>  return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
>  }
> 
> +static int64_t coroutine_fn blkdebug_co_get_block_status(
> +BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
> +BlockDriverState **file)
> +{
> +assert(QEMU_IS_ALIGNED(sector_num | nb_sectors,
> +   DIV_ROUND_UP(bs->bl.request_alignment,
> +BDRV_SECTOR_SIZE)));
> +return bdrv_co_get_block_status_from_file(bs, sector_num, nb_sectors,
> +  pnum, file);
> +}
> +
>  static void blkdebug_close(BlockDriverState *bs)
>  {
>  BDRVBlkdebugState *s = bs->opaque;
> @@ -915,7 +926,7 @@ static BlockDriver bdrv_blkdebug = {
>  .bdrv_co_flush_to_disk  = blkdebug_co_flush,
>  .bdrv_co_pwrite_zeroes  = blkdebug_co_pwrite_zeroes,
>  .bdrv_co_pdiscard   = blkdebug_co_pdiscard,
> -.bdrv_co_get_block_status = bdrv_co_get_block_status_from_file,
> +.bdrv_co_get_block_status = blkdebug_co_get_block_status,
> 
>  .bdrv_debug_event   = blkdebug_debug_event,
>  .bdrv_debug_breakpoint  = blkdebug_debug_breakpoint,
> diff --git a/block/io.c b/block/io.c
> index 91d3e99..5ed1ac7 100644
> --- a/block/io.c
> +++ b/block/io.c
> @@ -1746,7 +1746,8 @@ static int64_t coroutine_fn 
> bdrv_co_block_status(BlockDriverState *bs,
>  int64_t n; /* bytes */
>  int64_t ret, ret2;
>  BlockDriverState *local_file = NULL;
> -int count; /* sectors */
> +int64_t aligned_offset, aligned_bytes;
> +uint32_t align;
> 
>  assert(pnum);
>  total_size = bdrv_getlength(bs);
> @@ -1788,27 +1789,44 @@ static int64_t coroutine_fn 
> bdrv_co_block_status(BlockDriverState *bs,
>  }
> 
>  bdrv_inc_in_flight(bs);
> -/*
> - * TODO: Rather than require aligned offsets, we could instead
> - * round to the driver's request_alignment here, then touch up
> - * count afterwards back to the caller's expectations.
> - */
> -assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
> -ret = bs->drv->bdrv_co_get_block_status(bs, offset >> BDRV_SECTOR_BITS,
> -bytes >> BDRV_SECTOR_BITS, 
> &count,
> -&local_file);
> -if (ret < 0) {
> -*pnum = 0;
> -goto out;
> +
> +/* Round out to request_alignment boundaries */
> +align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
> +aligned_offset = QEMU_ALIGN_DOWN(offset, align);
> +aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;
> +
> +{

Not sure why using a {} block here?

> +int count; /*