On 12/29/25 15:29, Denis V. Lunev wrote:
> On 12/19/25 19:08, Denis V. Lunev wrote:
>> qcow2_header_updated() is the final call during image close. This means
>> after this point we will have no IO operations on this file descriptor.
>> This assumption has been validated via 'strace' which clearly confirms
>> that this is very final write and there is no sync after this point.
>>
>> There is almost no problem when the image is residing in local
>> filesystem except that we will have image check if the chage will
>> not reach disk before powerloss, but with a network or distributed
>> filesystem we come to trouble. The change could be in flight and we
>> can miss this data on other node like during migration.
>>
>> The patch adds BDRV_REQ_FUA to the write request to do the trick.
>>
>> Signed-off-by: Denis V. Lunev <[email protected]>
>> CC: Kevin Wolf <[email protected]>
>> CC: Hanna Reitz <[email protected]>
>> ---
>>   block/qcow2.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/block/qcow2.c b/block/qcow2.c
>> index e29810d86a..abbc4e82ba 100644
>> --- a/block/qcow2.c
>> +++ b/block/qcow2.c
>> @@ -3252,7 +3252,7 @@ int qcow2_update_header(BlockDriverState *bs)
>>       }
>>   
>>       /* Write the new header */
>> -    ret = bdrv_pwrite(bs->file, 0, s->cluster_size, header, 0);
>> +    ret = bdrv_pwrite(bs->file, 0, s->cluster_size, header, BDRV_REQ_FUA);
>>       if (ret < 0) {
>>           goto fail;
>>       }
> (attempt #2, mailer has rotten the mail. sorry).
>
> Thanks a lot for Andrey Drobyshev who has attempted to review and
> test this patch.
>
> The patch is non-working due to broken BDRV_REQ_FUA processing in QEMU 
> code and this looks more severe than the original problem. bdrv_pwrite() 
> endups in bdrv_aligned_pwritev() which internally calls 
> bdrv_driver_pwritev() -> bdrv_co_flush() bdrv_co_write_req_finish() 
> Please note, that bdrv_co_flush() is in reality noop until bs->write_gen 
> is incremented, which happened only late inside 
> bdrv_co_write_req_finish(). This means that BDRV_REQ_FUA request will be 
> flushed only on the NEXT flush operation, which is definitely wrong. Den

(attempt #3, mailer has rotten the mail. sorry. Finally get it working)

Thanks a lot for Andrey Drobyshev who has attempted to review and
test this patch.

The patch is non-working due to broken BDRV_REQ_FUA processing in QEMU 
code and this looks more severe than the original problem.

bdrv_pwrite()  endups in bdrv_aligned_pwritev() which internally calls 
        bdrv_driver_pwritev() -> bdrv_co_flush()
        bdrv_co_write_req_finish() 
Please note, that bdrv_co_flush() is in reality noop until bs->write_gen 
is incremented, which happened only late inside bdrv_co_write_req_finish().

This means that BDRV_REQ_FUA request will be flushed only on the NEXT
flush operation, which is definitely wrong.

Den


Reply via email to