diff mbox

[v2,10/18] block/pcache: cache invalidation on write requests

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

Commit Message

Pavel Butsykin Dec. 30, 2016, 2:31 p.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 | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/block/pcache.c b/block/pcache.c
index f30e9e7bfe..4007241d37 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -314,11 +314,41 @@  skip_large_request:
     return bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
 }
 
+static void pcache_invalidation(BlockDriverState *bs, uint64_t offset,
+                                uint64_t bytes)
+{
+    BDRVPCacheState *s = bs->opaque;
+    uint64_t chunk_offset = offset, chunk_bytes = bytes;
+    uint64_t end_offs = offset + bytes;
+
+    do {
+        PCacheNode *node = rbcache_search(s->cache, chunk_offset, chunk_bytes);
+        if (node == NULL) {
+            break;
+        }
+        assert(node->status == NODE_STATUS_COMPLETED ||
+               node->status == NODE_STATUS_INFLIGHT);
+
+        chunk_offset = node->common.offset + node->common.bytes;
+        chunk_bytes = end_offs - chunk_offset;
+
+        if (node->status & NODE_STATUS_COMPLETED) {
+            rbcache_remove(s->cache, &node->common);
+        }
+    } while (end_offs > chunk_offset);
+}
+
 static coroutine_fn int pcache_co_pwritev(BlockDriverState *bs, uint64_t offset,
                                           uint64_t bytes, QEMUIOVector *qiov,
                                           int flags)
 {
-    return bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+    int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
+    if (ret < 0) {
+        return ret;
+    }
+    pcache_invalidation(bs, offset, bytes);
+
+    return ret;
 }
 
 static void pcache_state_init(QemuOpts *opts, BDRVPCacheState *s)