diff mbox

[PULL,33/42] block: return BDRV_BLOCK_ZERO past end of backing file

Message ID 1378481953-23099-34-git-send-email-stefanha@redhat.com
State New
Headers show

Commit Message

Stefan Hajnoczi Sept. 6, 2013, 3:39 p.m. UTC
From: Paolo Bonzini <pbonzini@redhat.com>

If the sectors are unallocated and we are past the end of the
backing file, they will read as zero.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Peter Lieven Sept. 13, 2013, 7:33 a.m. UTC | #1
On 06.09.2013 17:39, Stefan Hajnoczi wrote:
> From: Paolo Bonzini <pbonzini@redhat.com>
>
> If the sectors are unallocated and we are past the end of the
> backing file, they will read as zero.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>   block.c | 12 ++++++++++--
>   1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/block.c b/block.c
> index aa9ec83..82bbd6c 100644
> --- a/block.c
> +++ b/block.c
> @@ -3102,8 +3102,16 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
>           return ret;
>       }
>   
> -    if (!(ret & BDRV_BLOCK_DATA) && bdrv_has_zero_init(bs)) {
> -        ret |= BDRV_BLOCK_ZERO;
> +    if (!(ret & BDRV_BLOCK_DATA)) {
> +        if (bdrv_has_zero_init(bs)) {
this should be bdi->discard_zeroes. bdrv_has_zero_init() does only give a valid result
right after bdrv_create(). i currently working on extending bdi. I can send a patch for this
if you agree.
> +            ret |= BDRV_BLOCK_ZERO;
> +        } else {
> +            BlockDriverState *bs2 = bs->backing_hd;

this segfaults if there is no backing_hd. found while testing get_block_status with iscsi.

paolo, is this the correct fix?

@@ -3110,7 +3157,7 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
      if (!(ret & BDRV_BLOCK_DATA)) {
          if (bdrv_has_zero_init(bs)) {
              ret |= BDRV_BLOCK_ZERO;
-        } else {
+        } else if (bs->backing_hd)  {
              BlockDriverState *bs2 = bs->backing_hd;
              int64_t length2 = bdrv_getlength(bs2);
              if (length2 >= 0 && sector_num >= (length2 >> BDRV_SECTOR_BITS)) {


> +            int64_t length2 = bdrv_getlength(bs2);
> +            if (length2 >= 0 && sector_num >= (length2 >> BDRV_SECTOR_BITS)) {
> +                ret |= BDRV_BLOCK_ZERO;
> +            }
> +        }
>       }
>       return ret;
>   }
Paolo Bonzini Sept. 13, 2013, 8:25 a.m. UTC | #2
Il 13/09/2013 09:33, Peter Lieven ha scritto:
> On 06.09.2013 17:39, Stefan Hajnoczi wrote:
>> From: Paolo Bonzini <pbonzini@redhat.com>
>>
>> If the sectors are unallocated and we are past the end of the
>> backing file, they will read as zero.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
>> ---
>>   block.c | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/block.c b/block.c
>> index aa9ec83..82bbd6c 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -3102,8 +3102,16 @@ static int64_t coroutine_fn
>> bdrv_co_get_block_status(BlockDriverState *bs,
>>           return ret;
>>       }
>>   -    if (!(ret & BDRV_BLOCK_DATA) && bdrv_has_zero_init(bs)) {
>> -        ret |= BDRV_BLOCK_ZERO;
>> +    if (!(ret & BDRV_BLOCK_DATA)) {
>> +        if (bdrv_has_zero_init(bs)) {
> this should be bdi->discard_zeroes. bdrv_has_zero_init() does only give
> a valid result
> right after bdrv_create(). i currently working on extending bdi. I can
> send a patch for this
> if you agree.

Yes, please.  Right now there is no bdi->discard_zeroes.

>> +            ret |= BDRV_BLOCK_ZERO;
>> +        } else {
>> +            BlockDriverState *bs2 = bs->backing_hd;
> 
> this segfaults if there is no backing_hd. found while testing
> get_block_status with iscsi.
> 
> paolo, is this the correct fix?

Yes, thanks.

Paolo

> @@ -3110,7 +3157,7 @@ static int64_t coroutine_fn
> bdrv_co_get_block_status(BlockDriverState *bs,
>      if (!(ret & BDRV_BLOCK_DATA)) {
>          if (bdrv_has_zero_init(bs)) {
>              ret |= BDRV_BLOCK_ZERO;
> -        } else {
> +        } else if (bs->backing_hd)  {
>              BlockDriverState *bs2 = bs->backing_hd;
>              int64_t length2 = bdrv_getlength(bs2);
>              if (length2 >= 0 && sector_num >= (length2 >>
> BDRV_SECTOR_BITS)) {
> 
> 
>> +            int64_t length2 = bdrv_getlength(bs2);
>> +            if (length2 >= 0 && sector_num >= (length2 >>
>> BDRV_SECTOR_BITS)) {
>> +                ret |= BDRV_BLOCK_ZERO;
>> +            }
>> +        }
>>       }
>>       return ret;
>>   }
>
Kevin Wolf Sept. 13, 2013, 3:20 p.m. UTC | #3
Am 13.09.2013 um 10:25 hat Paolo Bonzini geschrieben:
> Il 13/09/2013 09:33, Peter Lieven ha scritto:
> > On 06.09.2013 17:39, Stefan Hajnoczi wrote:
> >> From: Paolo Bonzini <pbonzini@redhat.com>
> >>
> >> If the sectors are unallocated and we are past the end of the
> >> backing file, they will read as zero.
> >>
> >> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> >> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> >> ---
> >>   block.c | 12 ++++++++++--
> >>   1 file changed, 10 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/block.c b/block.c
> >> index aa9ec83..82bbd6c 100644
> >> --- a/block.c
> >> +++ b/block.c
> >> @@ -3102,8 +3102,16 @@ static int64_t coroutine_fn
> >> bdrv_co_get_block_status(BlockDriverState *bs,
> >>           return ret;
> >>       }
> >>   -    if (!(ret & BDRV_BLOCK_DATA) && bdrv_has_zero_init(bs)) {
> >> -        ret |= BDRV_BLOCK_ZERO;
> >> +    if (!(ret & BDRV_BLOCK_DATA)) {
> >> +        if (bdrv_has_zero_init(bs)) {
> > this should be bdi->discard_zeroes. bdrv_has_zero_init() does only give
> > a valid result
> > right after bdrv_create(). i currently working on extending bdi. I can
> > send a patch for this
> > if you agree.
> 
> Yes, please.  Right now there is no bdi->discard_zeroes.

If we do this, it needs some function that behaves similar to
bdrv_has_zero_init(); in particular that it returns 0 if there is a
backing file.

Kevin
Peter Lieven Sept. 16, 2013, 5:45 a.m. UTC | #4
On 13.09.2013 17:20, Kevin Wolf wrote:
> Am 13.09.2013 um 10:25 hat Paolo Bonzini geschrieben:
>> Il 13/09/2013 09:33, Peter Lieven ha scritto:
>>> On 06.09.2013 17:39, Stefan Hajnoczi wrote:
>>>> From: Paolo Bonzini <pbonzini@redhat.com>
>>>>
>>>> If the sectors are unallocated and we are past the end of the
>>>> backing file, they will read as zero.
>>>>
>>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>>>> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
>>>> ---
>>>>    block.c | 12 ++++++++++--
>>>>    1 file changed, 10 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/block.c b/block.c
>>>> index aa9ec83..82bbd6c 100644
>>>> --- a/block.c
>>>> +++ b/block.c
>>>> @@ -3102,8 +3102,16 @@ static int64_t coroutine_fn
>>>> bdrv_co_get_block_status(BlockDriverState *bs,
>>>>            return ret;
>>>>        }
>>>>    -    if (!(ret & BDRV_BLOCK_DATA) && bdrv_has_zero_init(bs)) {
>>>> -        ret |= BDRV_BLOCK_ZERO;
>>>> +    if (!(ret & BDRV_BLOCK_DATA)) {
>>>> +        if (bdrv_has_zero_init(bs)) {
>>> this should be bdi->discard_zeroes. bdrv_has_zero_init() does only give
>>> a valid result
>>> right after bdrv_create(). i currently working on extending bdi. I can
>>> send a patch for this
>>> if you agree.
>> Yes, please.  Right now there is no bdi->discard_zeroes.
> If we do this, it needs some function that behaves similar to
> bdrv_has_zero_init(); in particular that it returns 0 if there is a
> backing file.
I will add bdrv_has_discard_zeroes. Would it be ok if it calls out to
bdrv_get_info to get the discard_zeroes information?

Peter
diff mbox

Patch

diff --git a/block.c b/block.c
index aa9ec83..82bbd6c 100644
--- a/block.c
+++ b/block.c
@@ -3102,8 +3102,16 @@  static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
         return ret;
     }
 
-    if (!(ret & BDRV_BLOCK_DATA) && bdrv_has_zero_init(bs)) {
-        ret |= BDRV_BLOCK_ZERO;
+    if (!(ret & BDRV_BLOCK_DATA)) {
+        if (bdrv_has_zero_init(bs)) {
+            ret |= BDRV_BLOCK_ZERO;
+        } else {
+            BlockDriverState *bs2 = bs->backing_hd;
+            int64_t length2 = bdrv_getlength(bs2);
+            if (length2 >= 0 && sector_num >= (length2 >> BDRV_SECTOR_BITS)) {
+                ret |= BDRV_BLOCK_ZERO;
+            }
+        }
     }
     return ret;
 }