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 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,55 +4319,55 @@ 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 ?
|
|
||||||
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 {
|
|
||||||
return 0;
|
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)
|
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user