[v4,09/20] parallels: Switch to .bdrv_co_block_status()

Message ID 20171012185916.22776-10-eblake@redhat.com
State New
Headers show
Series
  • add byte-based block_status driver callbacks
Related show

Commit Message

Eric Blake Oct. 12, 2017, 6:59 p.m.
We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the parallels driver accordingly.  Note that
the internal function block_status() is still sector-based, because
it is still in use by other sector-based functions; but that's okay
because request_alignment is 512 as a result of those functions.
For now, no optimizations are added based on the mapping hint.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v4: rebase to interface tweak, R-b dropped
v3: no change
v2: rebase to mapping parameter; it is ignored, so R-b kept
---
 block/parallels.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

Comments

Vladimir Sementsov-Ogievskiy Nov. 30, 2017, 9:03 a.m. | #1
12.10.2017 21:59, Eric Blake wrote:
> We are gradually moving away from sector-based interfaces, towards
> byte-based.  Update the parallels driver accordingly.  Note that
> the internal function block_status() is still sector-based, because
> it is still in use by other sector-based functions; but that's okay
> because request_alignment is 512 as a result of those functions.
> For now, no optimizations are added based on the mapping hint.
>
> Signed-off-by: Eric Blake <eblake@redhat.com>
>
> ---
> v4: rebase to interface tweak, R-b dropped
> v3: no change
> v2: rebase to mapping parameter; it is ignored, so R-b kept
> ---
>   block/parallels.c | 22 +++++++++++++++-------
>   1 file changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/block/parallels.c b/block/parallels.c
> index 2b6c6e5709..4a086f29e9 100644
> --- a/block/parallels.c
> +++ b/block/parallels.c
> @@ -278,23 +278,31 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
>   }
>
>
> -static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
> -        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
> +static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
> +                                                  bool want_zero,
> +                                                  int64_t offset,
> +                                                  int64_t bytes,
> +                                                  int64_t *pnum,
> +                                                  int64_t *map,
> +                                                  BlockDriverState **file)
>   {
>       BDRVParallelsState *s = bs->opaque;
> -    int64_t offset;
> +    int count;
>
> +    assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
>       qemu_co_mutex_lock(&s->lock);
> -    offset = block_status(s, sector_num, nb_sectors, pnum);
> +    offset = block_status(s, offset >> BDRV_SECTOR_BITS,
> +                          bytes >> BDRV_SECTOR_BITS, &count);
>       qemu_co_mutex_unlock(&s->lock);
>
>       if (offset < 0) {

pnum=count*BDRV_SECTOR_SIZE and map=0 setting missed here.

>           return 0;
>       }
>
> +    *pnum = count * BDRV_SECTOR_SIZE;
> +    *map = offset;
>       *file = bs->file->bs;
> -    return (offset << BDRV_SECTOR_BITS) |
> -        BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
> +    return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
>   }
>
>   static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
> @@ -781,7 +789,7 @@ static BlockDriver bdrv_parallels = {
>       .bdrv_open		= parallels_open,
>       .bdrv_close		= parallels_close,
>       .bdrv_child_perm          = bdrv_format_default_perms,
> -    .bdrv_co_get_block_status = parallels_co_get_block_status,
> +    .bdrv_co_block_status     = parallels_co_block_status,
>       .bdrv_has_zero_init       = bdrv_has_zero_init_1,
>       .bdrv_co_flush_to_os      = parallels_co_flush_to_os,
>       .bdrv_co_readv  = parallels_co_readv,
Eric Blake Nov. 30, 2017, 10:12 p.m. | #2
On 11/30/2017 03:03 AM, Vladimir Sementsov-Ogievskiy wrote:
> 12.10.2017 21:59, Eric Blake wrote:
>> We are gradually moving away from sector-based interfaces, towards
>> byte-based.  Update the parallels driver accordingly.  Note that
>> the internal function block_status() is still sector-based, because
>> it is still in use by other sector-based functions; but that's okay
>> because request_alignment is 512 as a result of those functions.
>> For now, no optimizations are added based on the mapping hint.
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>
>> ---

>> +static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
>> +                                                  bool want_zero,
>> +                                                  int64_t offset,
>> +                                                  int64_t bytes,
>> +                                                  int64_t *pnum,
>> +                                                  int64_t *map,
>> +                                                  BlockDriverState 
>> **file)
>>   {
>>       BDRVParallelsState *s = bs->opaque;
>> -    int64_t offset;
>> +    int count;
>>
>> +    assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
>>       qemu_co_mutex_lock(&s->lock);
>> -    offset = block_status(s, sector_num, nb_sectors, pnum);
>> +    offset = block_status(s, offset >> BDRV_SECTOR_BITS,
>> +                          bytes >> BDRV_SECTOR_BITS, &count);
>>       qemu_co_mutex_unlock(&s->lock);
>>
>>       if (offset < 0) {
> 
> pnum=count*BDRV_SECTOR_SIZE and map=0 setting missed here.
> 
>>           return 0;
>>       }

Setting *map is only required when return value includes 
BDRV_BLOCK_OFFSET_VALID, so that one was not necessary.  But you do 
raise an interesting point about a pre-existing bug with pnum not being 
set.  Commit 298a1665a guarantees that *pnum is 0 (and not uninitialized 
garbage) - but that still violates the contract that we (want to) have 
that all drivers either make progress or return an error (setting pnum 
to 0 should only be done at EOF or on error).
Eric Blake Nov. 30, 2017, 10:18 p.m. | #3
On 11/30/2017 04:12 PM, Eric Blake wrote:

>>>       BDRVParallelsState *s = bs->opaque;
>>> -    int64_t offset;
>>> +    int count;
>>>
>>> +    assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
>>>       qemu_co_mutex_lock(&s->lock);
>>> -    offset = block_status(s, sector_num, nb_sectors, pnum);
>>> +    offset = block_status(s, offset >> BDRV_SECTOR_BITS,
>>> +                          bytes >> BDRV_SECTOR_BITS, &count);
>>>       qemu_co_mutex_unlock(&s->lock);
>>>
>>>       if (offset < 0) {
>>
>> pnum=count*BDRV_SECTOR_SIZE and map=0 setting missed here.
>>
>>>           return 0;
>>>       }
> 
> Setting *map is only required when return value includes 
> BDRV_BLOCK_OFFSET_VALID, so that one was not necessary.  But you do 
> raise an interesting point about a pre-existing bug with pnum not being 
> set.  Commit 298a1665a guarantees that *pnum is 0 (and not uninitialized 
> garbage) - but that still violates the contract that we (want to) have 
> that all drivers either make progress or return an error (setting pnum 
> to 0 should only be done at EOF or on error).

Oh. The pre-existing code DID set pnum to a non-zero value, as a side 
effect of block_status(); the new code fails to do so.  So it is not 
pre-existing; good catch!

Patch

diff --git a/block/parallels.c b/block/parallels.c
index 2b6c6e5709..4a086f29e9 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -278,23 +278,31 @@  static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
 }


-static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int coroutine_fn parallels_co_block_status(BlockDriverState *bs,
+                                                  bool want_zero,
+                                                  int64_t offset,
+                                                  int64_t bytes,
+                                                  int64_t *pnum,
+                                                  int64_t *map,
+                                                  BlockDriverState **file)
 {
     BDRVParallelsState *s = bs->opaque;
-    int64_t offset;
+    int count;

+    assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
     qemu_co_mutex_lock(&s->lock);
-    offset = block_status(s, sector_num, nb_sectors, pnum);
+    offset = block_status(s, offset >> BDRV_SECTOR_BITS,
+                          bytes >> BDRV_SECTOR_BITS, &count);
     qemu_co_mutex_unlock(&s->lock);

     if (offset < 0) {
         return 0;
     }

+    *pnum = count * BDRV_SECTOR_SIZE;
+    *map = offset;
     *file = bs->file->bs;
-    return (offset << BDRV_SECTOR_BITS) |
-        BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
+    return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
 }

 static coroutine_fn int parallels_co_writev(BlockDriverState *bs,
@@ -781,7 +789,7 @@  static BlockDriver bdrv_parallels = {
     .bdrv_open		= parallels_open,
     .bdrv_close		= parallels_close,
     .bdrv_child_perm          = bdrv_format_default_perms,
-    .bdrv_co_get_block_status = parallels_co_get_block_status,
+    .bdrv_co_block_status     = parallels_co_block_status,
     .bdrv_has_zero_init       = bdrv_has_zero_init_1,
     .bdrv_co_flush_to_os      = parallels_co_flush_to_os,
     .bdrv_co_readv  = parallels_co_readv,