[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/4] block: add bdrv_co_discard and bdrv_aio_discard
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 4/4] block: add bdrv_co_discard and bdrv_aio_discard support |
Date: |
Fri, 14 Oct 2011 10:41:32 +0200 |
This similarly adds support for coroutine and asynchronous discard.
Signed-off-by: Paolo Bonzini <address@hidden>
---
I was not sure if qcow2 could be changed to co_discard, though
I suspected yes.
block.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++---------
block.h | 3 ++
block/raw.c | 8 ++++--
block_int.h | 9 +++++-
trace-events | 1 +
5 files changed, 77 insertions(+), 16 deletions(-)
diff --git a/block.c b/block.c
index 0af9a89..7c60361 100644
--- a/block.c
+++ b/block.c
@@ -1768,17 +1768,6 @@ int bdrv_has_zero_init(BlockDriverState *bs)
return 1;
}
-int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
-{
- if (!bs->drv) {
- return -ENOMEDIUM;
- }
- if (!bs->drv->bdrv_discard) {
- return 0;
- }
- return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
-}
-
/*
* Returns true iff the specified sector is present in the disk image. Drivers
* not implementing the functionality are assumed to not support backing files,
@@ -2911,6 +2900,66 @@ int bdrv_flush(BlockDriverState *bs)
return rwco.ret;
}
+static void bdrv_discard_co_entry(void *opaque)
+{
+ RwCo *rwco = opaque;
+ BlockDriverState *bs = rwco->bs;
+ int64_t sector_num = rwco->sector_num;
+ int nb_sectors = rwco->nb_sectors;
+
+ if (!bs->drv) {
+ rwco->ret = -ENOMEDIUM;
+ } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
+ rwco->ret = -EIO;
+ } else if (bs->read_only) {
+ rwco->ret = -EROFS;
+ } else if (bs->drv->bdrv_co_discard) {
+ rwco->ret = bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
+ } 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) {
+ rwco->ret = -EIO;
+ } else {
+ qemu_coroutine_yield();
+ rwco->ret = co.ret;
+ }
+ } else if (bs->drv->bdrv_discard) {
+ rwco->ret = bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
+ } else {
+ rwco->ret = 0;
+ }
+}
+
+int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
+{
+ Coroutine *co;
+ RwCo rwco = {
+ .bs = bs,
+ .sector_num = sector_num,
+ .nb_sectors = nb_sectors,
+ .ret = NOT_DONE,
+ };
+
+ if (qemu_in_coroutine()) {
+ /* Fast-path if already in coroutine context */
+ bdrv_discard_co_entry(&rwco);
+ } else {
+ co = qemu_coroutine_create(bdrv_discard_co_entry);
+ qemu_coroutine_enter(co, &rwco);
+ while (rwco.ret == NOT_DONE) {
+ qemu_aio_wait();
+ }
+ }
+
+ return rwco.ret;
+}
+
/**************************************************************/
/* removable device support */
diff --git a/block.h b/block.h
index e77988e..4f4aa94 100644
--- a/block.h
+++ b/block.h
@@ -166,6 +166,9 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs,
int64_t sector_num,
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
+BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void
*opaque);
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
typedef struct BlockRequest {
diff --git a/block/raw.c b/block/raw.c
index 161c9cf..ff68514 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -45,7 +45,8 @@ static int raw_probe(const uint8_t *buf, int buf_size, const
char *filename)
return 1; /* everything can be opened as raw image */
}
-static int raw_discard(BlockDriverState *bs, int64_t sector_num, int
nb_sectors)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors)
{
return bdrv_discard(bs->file, sector_num, nb_sectors);
}
@@ -109,15 +110,16 @@ static BlockDriver bdrv_raw = {
.bdrv_open = raw_open,
.bdrv_close = raw_close,
+
.bdrv_co_readv = raw_co_readv,
.bdrv_co_writev = raw_co_writev,
.bdrv_co_flush = raw_co_flush,
+ .bdrv_co_discard = raw_co_discard,
+
.bdrv_probe = raw_probe,
.bdrv_getlength = raw_getlength,
.bdrv_truncate = raw_truncate,
- .bdrv_discard = raw_discard,
-
.bdrv_is_inserted = raw_is_inserted,
.bdrv_media_changed = raw_media_changed,
.bdrv_eject = raw_eject,
diff --git a/block_int.h b/block_int.h
index 9cb536d..384598f 100644
--- a/block_int.h
+++ b/block_int.h
@@ -63,6 +63,8 @@ struct BlockDriver {
void (*bdrv_close)(BlockDriverState *bs);
int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
int (*bdrv_flush)(BlockDriverState *bs);
+ int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors);
int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
@@ -76,14 +78,17 @@ struct BlockDriver {
BlockDriverCompletionFunc *cb, void *opaque);
BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
BlockDriverCompletionFunc *cb, void *opaque);
- int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors);
+ BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ BlockDriverCompletionFunc *cb, void *opaque);
int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
+ int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors);
int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
int num_reqs);
diff --git a/trace-events b/trace-events
index 63d8c8e..e6160ad 100644
--- a/trace-events
+++ b/trace-events
@@ -61,6 +61,7 @@ multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p
num_callbacks %d num_reqs %d"
bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
+bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque)
"bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs
%p sector_num %"PRId64" nb_sectors %d opaque %p"
bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque)
"bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
--
1.7.6
- [Qemu-devel] [PATCH 3/4] block: drop redundant bdrv_flush implementation, (continued)
- [Qemu-devel] [PATCH 3/4] block: drop redundant bdrv_flush implementation, Paolo Bonzini, 2011/10/14
- [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Paolo Bonzini, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Kevin Wolf, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Paolo Bonzini, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Kevin Wolf, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Paolo Bonzini, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Kevin Wolf, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Paolo Bonzini, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Stefan Hajnoczi, 2011/10/14
- Re: [Qemu-devel] [PATCH 2/4] block: unify flush implementations, Paolo Bonzini, 2011/10/14
[Qemu-devel] [PATCH 4/4] block: add bdrv_co_discard and bdrv_aio_discard support,
Paolo Bonzini <=