[GEDI] [PATCH v6 07/11] block: use int64_t instead of int in driver write_zeroes handlers

Vladimir Sementsov-Ogievskiy vsementsov at virtuozzo.com
Thu Sep 23 21:50:41 UTC 2021


23.09.2021 23:33, Eric Blake wrote:
> On Fri, Sep 03, 2021 at 01:28:03PM +0300, Vladimir Sementsov-Ogievskiy wrote:
>> We are generally moving to int64_t for both offset and bytes parameters
>> on all io paths.
>>
>> Main motivation is realization of 64-bit write_zeroes operation for
>> fast zeroing large disk chunks, up to the whole disk.
>>
>> We chose signed type, to be consistent with off_t (which is signed) and
>> with possibility for signed return type (where negative value means
>> error).
>>
>> So, convert driver write_zeroes handlers bytes parameter to int64_t.
>>
>> The only caller of all updated function is bdrv_co_do_pwrite_zeroes().
>>
>> bdrv_co_do_pwrite_zeroes() itself is of course OK with widening of
>> callee parameter type. Also, bdrv_co_do_pwrite_zeroes()'s
>> max_write_zeroes is limited to INT_MAX. So, updated functions all are
>> safe, they will not get "bytes" larger than before.
>>
>> Still, let's look through all updated functions, and add assertions to
>> the ones which are actually unprepared to values larger than INT_MAX.
>> For these drivers also set explicit max_pwrite_zeroes limit.
>>
> [snip]
>>
>> At this point all block drivers are prepared to support 64bit
>> write-zero requests, or have explicitly set max_pwrite_zeroes.
> 
> The long commit message is essential, but the analysis looks sane.
> 
>>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov at virtuozzo.com>
>> ---
> 
>> +++ b/block/iscsi.c
> 
>> @@ -1250,11 +1250,21 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
>>       iscsi_co_init_iscsitask(iscsilun, &iTask);
>>   retry:
>>       if (use_16_for_ws) {
>> +        /*
>> +         * iscsi_writesame16_task num_blocks argument is uint32_t. We rely here
>> +         * on our max_pwrite_zeroes limit.
>> +         */
>> +        assert(nb_blocks < UINT32_MAX);
>>           iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, lba,
>>                                               iscsilun->zeroblock, iscsilun->block_size,
>>                                               nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
>>                                               0, 0, iscsi_co_generic_cb, &iTask);
> 
> Should this be <= instead of < ?
> 
>>       } else {
>> +        /*
>> +         * iscsi_writesame10_task num_blocks argument is uint16_t. We rely here
>> +         * on our max_pwrite_zeroes limit.
>> +         */
>> +        assert(nb_blocks < UINT16_MAX);
>>           iTask.task = iscsi_writesame10_task(iscsilun->iscsi, iscsilun->lun, lba,
>>                                               iscsilun->zeroblock, iscsilun->block_size,
>>                                               nb_blocks, 0, !!(flags & BDRV_REQ_MAY_UNMAP),
> 
> here too.  The 16-bit limit is where we're most likely to run into
> someone actually trying to zeroize that much at once.
> 
>> +++ b/block/nbd.c
>> @@ -1407,15 +1407,17 @@ static int nbd_client_co_pwritev(BlockDriverState *bs, int64_t offset,
>>   }
>>   
>>   static int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
>> -                                       int bytes, BdrvRequestFlags flags)
>> +                                       int64_t bytes, BdrvRequestFlags flags)
>>   {
>>       BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
>>       NBDRequest request = {
>>           .type = NBD_CMD_WRITE_ZEROES,
>>           .from = offset,
>> -        .len = bytes,
>> +        .len = bytes,  /* .len is uint32_t actually */
>>       };
>>   
>> +    assert(bytes < UINT32_MAX); /* relay on max_pwrite_zeroes */
> 
> And again.  Here, you happen to get by with < because we clamped
> bl.max_pwrite_zeroes at BDRV_REQUEST_MAX_BYTES, which is INT_MAX
> rounded down.  But I had to check; whereas using <= would be less
> worrisome, even if we never get a request that large.
> 
> If you agree with my analysis, I can make that change while preparing
> my pull request.

I agree, <= should be right thing, thanks!

> 
> Reviewed-by: Eric Blake <eblake at redhat.com>
> 


-- 
Best regards,
Vladimir


More information about the integration mailing list