Am 24.10.2013 um 12:06 hat Peter Lieven geschrieben:
> Reviewed-by: Eric Blake <ebl...@redhat.com>
> Signed-off-by: Peter Lieven <p...@kamp.de>
> ---
>  block.c |   37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/block.c b/block.c
> index 0c0b0ac..b28dd42 100644
> --- a/block.c
> +++ b/block.c
> @@ -4234,6 +4234,11 @@ static void coroutine_fn bdrv_discard_co_entry(void 
> *opaque)
>      rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, 
> rwco->nb_sectors);
>  }
>  
> +/* if no limit is specified in the BlockLimits use a default
> + * of 32768 512-byte sectors (16 MiB) per request.
> + */
> +#define MAX_DISCARD_DEFAULT 32768
> +
>  int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
>                                   int nb_sectors)
>  {
> @@ -4255,7 +4260,37 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, 
> int64_t sector_num,
>      }
>  
>      if (bs->drv->bdrv_co_discard) {
> -        return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
> +        int max_discard = bs->bl.max_discard ?
> +                          bs->bl.max_discard : MAX_DISCARD_DEFAULT;
> +
> +        while (nb_sectors > 0) {
> +            int ret;
> +            int num = nb_sectors;
> +
> +            /* align request */
> +            if (bs->bl.discard_alignment &&
> +                num >= bs->bl.discard_alignment &&
> +                sector_num % bs->bl.discard_alignment) {
> +                if (num > bs->bl.discard_alignment) {
> +                    num = bs->bl.discard_alignment;
> +                }
> +                num -= sector_num % bs->bl.discard_alignment;
> +            }
> +
> +            /* limit request size */
> +            if (num > max_discard) {
> +                num = max_discard;
> +            }
> +
> +            ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
> +            if (ret) {
> +                return ret;
> +            }
> +
> +            sector_num += num;
> +            nb_sectors -= num;
> +        }
> +        return 0;
>      } else if (bs->drv->bdrv_aio_discard) {
>          BlockDriverAIOCB *acb;
>          CoroutineIOCompletion co = {

You're only optimising drivers which have a .bdrv_co_discard()
implementation, but not those with .bdrv_aio_discard(). Not very nice,
and it would have been easy to avoid this by putting the loop around the
whole if statement instead of inside the 'then' branch.

Kevin

Reply via email to