diff mbox series

blockdev: fix missed target unref for drive-backup

Message ID 20190510215212.8413-1-jsnow@redhat.com (mailing list archive)
State New, archived
Headers show
Series blockdev: fix missed target unref for drive-backup | expand

Commit Message

John Snow May 10, 2019, 9:52 p.m. UTC
If the bitmap can't be used for whatever reason, we skip putting down
the reference. Fix that.

In practice, this means that if you attempt to gracefully exit QEMU
after a backup command being rejected, bdrv_close_all will fail and
tell you some unpleasant things via assert().

Reported-by: aihua liang <aliang@redhat.com>
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1703916
Signed-off-by: John Snow <jsnow@redhat.com>
---
 blockdev.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

Comments

Kevin Wolf May 13, 2019, 11:13 a.m. UTC | #1
Am 10.05.2019 um 23:52 hat John Snow geschrieben:
> If the bitmap can't be used for whatever reason, we skip putting down
> the reference. Fix that.
> 
> In practice, this means that if you attempt to gracefully exit QEMU
> after a backup command being rejected, bdrv_close_all will fail and
> tell you some unpleasant things via assert().
> 
> Reported-by: aihua liang <aliang@redhat.com>
> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1703916
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  blockdev.c | 12 +++++-------
>  1 file changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 79fbac8450..278ecdd122 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -3525,8 +3525,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>      if (set_backing_hd) {
>          bdrv_set_backing_hd(target_bs, source, &local_err);
>          if (local_err) {
> -            bdrv_unref(target_bs);
> -            goto out;
> +            goto unref;
>          }
>      }
>  
> @@ -3534,11 +3533,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>          bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
>          if (!bmap) {
>              error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
> -            bdrv_unref(target_bs);
> -            goto out;
> +            goto unref;
>          }
>          if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
> -            goto out;
> +            goto unref;
>          }
>      }
>      if (!backup->auto_finalize) {
> @@ -3552,12 +3550,12 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>                              backup->sync, bmap, backup->compress,
>                              backup->on_source_error, backup->on_target_error,
>                              job_flags, NULL, NULL, txn, &local_err);
> -    bdrv_unref(target_bs);
>      if (local_err != NULL) {
>          error_propagate(errp, local_err);
> -        goto out;

Please leave a 'goto unref' here so we can later add more code without
modifying unrelated error paths (or, more likely, forgetting to modify
them).

>      }
>  
> +unref:
> +    bdrv_unref(target_bs);
>  out:
>      aio_context_release(aio_context);
>      return job;

With this fixed:
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
John Snow May 13, 2019, 3:01 p.m. UTC | #2
On 5/13/19 7:13 AM, Kevin Wolf wrote:
> Am 10.05.2019 um 23:52 hat John Snow geschrieben:
>> If the bitmap can't be used for whatever reason, we skip putting down
>> the reference. Fix that.
>>
>> In practice, this means that if you attempt to gracefully exit QEMU
>> after a backup command being rejected, bdrv_close_all will fail and
>> tell you some unpleasant things via assert().
>>
>> Reported-by: aihua liang <aliang@redhat.com>
>> Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1703916
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  blockdev.c | 12 +++++-------
>>  1 file changed, 5 insertions(+), 7 deletions(-)
>>
>> diff --git a/blockdev.c b/blockdev.c
>> index 79fbac8450..278ecdd122 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -3525,8 +3525,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>>      if (set_backing_hd) {
>>          bdrv_set_backing_hd(target_bs, source, &local_err);
>>          if (local_err) {
>> -            bdrv_unref(target_bs);
>> -            goto out;
>> +            goto unref;
>>          }
>>      }
>>  
>> @@ -3534,11 +3533,10 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>>          bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
>>          if (!bmap) {
>>              error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
>> -            bdrv_unref(target_bs);
>> -            goto out;
>> +            goto unref;
>>          }
>>          if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
>> -            goto out;
>> +            goto unref;
>>          }
>>      }
>>      if (!backup->auto_finalize) {
>> @@ -3552,12 +3550,12 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
>>                              backup->sync, bmap, backup->compress,
>>                              backup->on_source_error, backup->on_target_error,
>>                              job_flags, NULL, NULL, txn, &local_err);
>> -    bdrv_unref(target_bs);
>>      if (local_err != NULL) {
>>          error_propagate(errp, local_err);
>> -        goto out;
> 
> Please leave a 'goto unref' here so we can later add more code without
> modifying unrelated error paths (or, more likely, forgetting to modify
> them).
> 

Oh, that makes sense.

>>      }
>>  
>> +unref:
>> +    bdrv_unref(target_bs);
>>  out:
>>      aio_context_release(aio_context);
>>      return job;
> 
> With this fixed:
> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
> 

Thanks!
diff mbox series

Patch

diff --git a/blockdev.c b/blockdev.c
index 79fbac8450..278ecdd122 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -3525,8 +3525,7 @@  static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
     if (set_backing_hd) {
         bdrv_set_backing_hd(target_bs, source, &local_err);
         if (local_err) {
-            bdrv_unref(target_bs);
-            goto out;
+            goto unref;
         }
     }
 
@@ -3534,11 +3533,10 @@  static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
         bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap);
         if (!bmap) {
             error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap);
-            bdrv_unref(target_bs);
-            goto out;
+            goto unref;
         }
         if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) {
-            goto out;
+            goto unref;
         }
     }
     if (!backup->auto_finalize) {
@@ -3552,12 +3550,12 @@  static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn,
                             backup->sync, bmap, backup->compress,
                             backup->on_source_error, backup->on_target_error,
                             job_flags, NULL, NULL, txn, &local_err);
-    bdrv_unref(target_bs);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
-        goto out;
     }
 
+unref:
+    bdrv_unref(target_bs);
 out:
     aio_context_release(aio_context);
     return job;