mirror of
https://github.com/qemu/qemu.git
synced 2024-11-23 10:53:37 +08:00
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:
parent
af057fe740
commit
d51e9fe505
96
block.c
96
block.c
@ -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 nb_sectors)
|
||||
{
|
||||
int max_discard;
|
||||
|
||||
if (!bs->drv) {
|
||||
return -ENOMEDIUM;
|
||||
} else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
|
||||
@ -4317,55 +4319,55 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bs->drv->bdrv_co_discard) {
|
||||
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 = {
|
||||
.coroutine = qemu_coroutine_self(),
|
||||
};
|
||||
|
||||
acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
|
||||
bdrv_co_io_em_complete, &co);
|
||||
if (acb == NULL) {
|
||||
return -EIO;
|
||||
} else {
|
||||
qemu_coroutine_yield();
|
||||
return co.ret;
|
||||
}
|
||||
} else {
|
||||
if (!bs->drv->bdrv_co_discard && !bs->drv->bdrv_aio_discard) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (bs->drv->bdrv_co_discard) {
|
||||
ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
|
||||
} else {
|
||||
BlockDriverAIOCB *acb;
|
||||
CoroutineIOCompletion co = {
|
||||
.coroutine = qemu_coroutine_self(),
|
||||
};
|
||||
|
||||
acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
|
||||
bdrv_co_io_em_complete, &co);
|
||||
if (acb == NULL) {
|
||||
return -EIO;
|
||||
} else {
|
||||
qemu_coroutine_yield();
|
||||
ret = co.ret;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
sector_num += num;
|
||||
nb_sectors -= num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
|
||||
|
Loading…
Reference in New Issue
Block a user