block: generalize BlockLimits handling to cover bdrv_aio_discard too

bdrv_co_discard is only covering drivers which have a .bdrv_co_discard()
implementation, but not those with .bdrv_aio_discard(). Not very nice,
and easy to avoid.

Suggested-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Paolo Bonzini 2013-11-22 13:39:43 +01:00 committed by Stefan Hajnoczi
parent af057fe740
commit d51e9fe505

32
block.c
View File

@ -4302,6 +4302,8 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque)
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors) int nb_sectors)
{ {
int max_discard;
if (!bs->drv) { if (!bs->drv) {
return -ENOMEDIUM; return -ENOMEDIUM;
} else if (bdrv_check_request(bs, sector_num, nb_sectors)) { } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
@ -4317,10 +4319,11 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
return 0; return 0;
} }
if (bs->drv->bdrv_co_discard) { if (!bs->drv->bdrv_co_discard && !bs->drv->bdrv_aio_discard) {
int max_discard = bs->bl.max_discard ? return 0;
bs->bl.max_discard : MAX_DISCARD_DEFAULT; }
max_discard = bs->bl.max_discard ? bs->bl.max_discard : MAX_DISCARD_DEFAULT;
while (nb_sectors > 0) { while (nb_sectors > 0) {
int ret; int ret;
int num = nb_sectors; int num = nb_sectors;
@ -4340,16 +4343,9 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
num = max_discard; num = max_discard;
} }
if (bs->drv->bdrv_co_discard) {
ret = bs->drv->bdrv_co_discard(bs, sector_num, num); ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
if (ret) { } else {
return ret;
}
sector_num += num;
nb_sectors -= num;
}
return 0;
} else if (bs->drv->bdrv_aio_discard) {
BlockDriverAIOCB *acb; BlockDriverAIOCB *acb;
CoroutineIOCompletion co = { CoroutineIOCompletion co = {
.coroutine = qemu_coroutine_self(), .coroutine = qemu_coroutine_self(),
@ -4361,12 +4357,18 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
return -EIO; return -EIO;
} else { } else {
qemu_coroutine_yield(); qemu_coroutine_yield();
return co.ret; ret = co.ret;
}
}
if (ret) {
return ret;
}
sector_num += num;
nb_sectors -= num;
} }
} else {
return 0; return 0;
} }
}
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
{ {