diff mbox

[v1,11/18] block/pcache: cache invalidation on AIO write requests

Message ID 20161115063715.12561-12-pbutsykin@virtuozzo.com (mailing list archive)
State New, archived
Headers show

Commit Message

Pavel Butsykin Nov. 15, 2016, 6:37 a.m. UTC
In AIO write request completion we just drop all the intersecting nodes in the
cache, it's a simple way to keep the cache up-to-date.

Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
 block/pcache.c | 39 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 38 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/block/pcache.c b/block/pcache.c
index 1f3800d..27ee6dd 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -362,15 +362,52 @@  out:
     return acb.ret;
 }
 
+static void pcache_aio_write_cb(void *opaque, int ret)
+{
+    PCacheAIOCB *acb = opaque;
+    BDRVPCacheState *s = acb->bs->opaque;
+    uint64_t offset = acb->offset;
+    uint64_t bytes = acb->bytes;
+    uint64_t end_offs = offset + bytes;
+
+    if (ret < 0) {
+        goto out;
+    }
+
+    do {
+        PCacheNode *node = rbcache_search(s->cache, offset, bytes);
+        if (node == NULL) {
+            break;
+        }
+        assert(node->status == NODE_STATUS_COMPLETED ||
+               node->status == NODE_STATUS_INFLIGHT  ||
+               node->status == NODE_STATUS_REMOVE);
+
+        offset = node->common.offset + node->common.bytes;
+        bytes = end_offs - offset;
+
+        if (node->status == NODE_STATUS_COMPLETED) {
+            rbcache_remove(s->cache, &node->common);
+        }
+    } while (end_offs > offset);
+
+out:
+    acb->ret = ret;
+    qemu_coroutine_enter(acb->co);
+}
+
 static coroutine_fn int pcache_co_pwritev(BlockDriverState *bs, uint64_t offset,
                                           uint64_t bytes, QEMUIOVector *qiov,
                                           int flags)
 {
     PCacheAIOCB acb = {
         .co = qemu_coroutine_self(),
+        .bs = bs,
+        .offset = offset,
+        .bytes = bytes,
     };
 
-    bdrv_aio_pwritev(bs->file, offset, qiov, bytes, pcache_aio_cb, &acb);
+    bdrv_aio_pwritev(bs->file, offset, qiov, bytes, pcache_aio_write_cb, &acb);
 
     qemu_coroutine_yield();