[prev in list] [next in list] [prev in thread] [next in thread]
List: qemu-block
Subject: [Qemu-block] [PATCH RFC v2 08/22] block/pcache: implement pickup parts of the cache
From: Pavel Butsykin <pbutsykin () virtuozzo ! com>
Date: 2016-08-29 17:10:07
Message-ID: 20160829171021.4902-9-pbutsykin () virtuozzo ! com
[Download RAW message or body]
Implementation of obtaining fragments of the cache belonging to one area
of request. This will allow to handle the case when a request is partially
hits the cache.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com>
---
block/pcache.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 59 insertions(+), 1 deletion(-)
diff --git a/block/pcache.c b/block/pcache.c
index 7504db8..28bd056 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -143,6 +143,24 @@ static int pcache_key_cmp(const RbNodeKey *key1, const RbNodeKey *key2)
return 0;
}
+static BlockNode *pcache_node_prev(BlockNode* node, RbNodeKey *key)
+{
+ while (node) {
+ struct RbNode *prev_rb_node = rb_prev(&node->rb_node);
+ BlockNode *prev_node;
+ if (prev_rb_node == NULL) {
+ break;
+ }
+ prev_node = container_of(prev_rb_node, BlockNode, rb_node);
+ if (prev_node->sector_num + prev_node->nb_sectors <= key->num) {
+ break;
+ }
+ node = prev_node;
+ }
+
+ return node;
+}
+
static void *node_insert(struct RbRoot *root, BlockNode *node)
{
struct RbNode **new = &(root->rb_node), *parent = NULL;
@@ -152,7 +170,7 @@ static void *node_insert(struct RbRoot *root, BlockNode *node)
BlockNode *this = container_of(*new, BlockNode, rb_node);
int result = pcache_key_cmp(&node->key, &this->key);
if (result == 0) {
- return this;
+ return pcache_node_prev(this, &node->key);
}
parent = *new;
new = result < 0 ? &((*new)->rb_left) : &((*new)->rb_right);
@@ -258,6 +276,45 @@ static inline void prefetch_init_key(PrefCacheAIOCB *acb, RbNodeKey* key)
key->size = acb->nb_sectors;
}
+static void pcache_pickup_parts_of_cache(PrefCacheAIOCB *acb, PCNode *node,
+ uint64_t num, uint32_t size)
+{
+ uint32_t up_size;
+
+ do {
+ if (num < node->cm.sector_num) {
+ PCNode *new_node;
+ RbNodeKey lc_key = {
+ .num = num,
+ .size = node->cm.sector_num - num,
+ };
+ up_size = lc_key.size;
+
+ if (!pcache_node_find_and_create(acb, &lc_key, &new_node)) {
+ node = new_node;
+ continue;
+ }
+ size -= up_size;
+ num += up_size;
+ }
+ /* XXX: node read */
+ up_size = MIN(node->cm.sector_num + node->cm.nb_sectors - num, size);
+
+ size -= up_size;
+ num += up_size;
+ if (size != 0) {
+ RbNodeKey lc_key = {
+ .num = num,
+ .size = size,
+ };
+ if (pcache_node_find_and_create(acb, &lc_key, &node)) {
+ size -= lc_key.size;
+ assert(size == 0);
+ }
+ }
+ } while (size);
+}
+
enum {
PREFETCH_NEW_NODE = 0,
PREFETCH_FULL_UP = 1,
@@ -281,6 +338,7 @@ static int32_t pcache_prefetch(PrefCacheAIOCB *acb)
{
return PREFETCH_FULL_UP;
}
+ pcache_pickup_parts_of_cache(acb, node, key.num, key.size);
return PREFETCH_PART_UP;
}
--
2.8.3
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic