mirror of https://gitee.com/openkylin/qemu.git
block: honour BlockLimits in bdrv_co_discard
Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Peter Lieven <pl@kamp.de> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
c31cb70728
commit
6f14da5247
37
block.c
37
block.c
|
@ -4243,6 +4243,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)
|
||||
{
|
||||
|
@ -4264,7 +4269,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 = {
|
||||
|
|
Loading…
Reference in New Issue