summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohann Latocha2012-04-11 20:08:00 +0200
committerJohann Latocha2012-04-11 20:08:00 +0200
commit5deabafb9a7516fdedea80abe2432b38ecbdddfa (patch)
tree7ca09e7057e10719d9efa63f276d71b5bd392c16
parent[KERNEL] Support for kernel 2.6.32 (diff)
downloaddnbd3-5deabafb9a7516fdedea80abe2432b38ecbdddfa.tar.gz
dnbd3-5deabafb9a7516fdedea80abe2432b38ecbdddfa.tar.xz
dnbd3-5deabafb9a7516fdedea80abe2432b38ecbdddfa.zip
[SERVER] Cache improved
-rw-r--r--src/kernel/blk.c9
-rw-r--r--src/server/net.c63
2 files changed, 55 insertions, 17 deletions
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 921fa87..2b12b74 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -73,15 +73,6 @@ int dnbd3_blk_add_device(dnbd3_device_t *dev, int minor)
blk_queue_logical_block_size(blk_queue, DNBD3_BLOCK_SIZE);
blk_queue_physical_block_size(blk_queue, DNBD3_BLOCK_SIZE);
- blk_queue_max_hw_sectors(blk_queue, DNBD3_BLOCK_SIZE/KERNEL_SECTOR_SIZE);
- blk_queue_max_segment_size(blk_queue, DNBD3_BLOCK_SIZE);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
- blk_queue_max_segments(blk_queue, 1);
-#else
- blk_queue_max_phys_segments(blk_queue, 1);
- blk_queue_max_hw_segments(blk_queue, 1);
-#endif
-
disk->queue = blk_queue;
disk->private_data = dev;
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue);
diff --git a/src/server/net.c b/src/server/net.c
index 1d47e92..97a0619 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -49,6 +49,9 @@ void *dnbd3_handle_query(void *dnbd3_client)
uint64_t map_y;
char map_x, bit_mask;
+ uint64_t todo_size, todo_offset, cur_offset, last_offset = 0;
+ int dirty = 0;
+
while (recv(client->sock, &request, sizeof(dnbd3_request_t), MSG_WAITALL) > 0)
{
reply.cmd = request.cmd;
@@ -114,20 +117,64 @@ void *dnbd3_handle_query(void *dnbd3_client)
break;
}
- map_y = request.offset >> 15;
- map_x = (request.offset >> 12) & 7; // mod 8
- bit_mask = 0b00000001 << (map_x);
+ // caching is on
+ dirty = 0;
+ todo_size = 0;
+ todo_offset = request.offset;
+ cur_offset = request.offset;
+ last_offset = request.offset + request.size;
+
+ while(cur_offset < last_offset)
+ {
+ map_y = cur_offset >> 15;
+ map_x = (cur_offset >> 12) & 7; // mod 8
+ bit_mask = 0b00000001 << (map_x);
+
+ cur_offset += 4096;
+
+ if ((image->cache_map[map_y] & bit_mask) != 0) // cache hit
+ {
+ if (todo_size != 0) // fetch missing chunks
+ {
+ lseek(image_cache, todo_offset, SEEK_SET);
+ if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) < 0)
+ printf("ERROR: Sendfile failed (cache)\n");
+ todo_size = 0;
+ dirty = 1;
+ }
+ todo_offset = cur_offset;
+ }
+ else
+ {
+ todo_size += 4096;
+ }
+ }
- if ((image->cache_map[map_y] & bit_mask) == 0) // cache miss
+ // whole request was missing
+ if (todo_size != 0)
{
- uint64_t tmp = request.offset;
- lseek(image_cache, tmp, SEEK_SET);
- if (sendfile(image_cache, image_file, (off_t *) &tmp, request.size) < 0)
+ lseek(image_cache, todo_offset, SEEK_SET);
+ if (sendfile(image_cache, image_file, (off_t *) &todo_offset, todo_size) < 0)
printf("ERROR: Sendfile failed (cache)\n");
- image->cache_map[map_y] |= bit_mask; // set 1 in cache map
+ dirty = 1;
+ }
+
+ if (dirty)
+ {
+ // set 1 in cache map for whole request
+ cur_offset = request.offset;
+ while(cur_offset < last_offset)
+ {
+ map_y = cur_offset >> 15;
+ map_x = (cur_offset >> 12) & 7; // mod 8
+ bit_mask = 0b00000001 << (map_x);
+ image->cache_map[map_y] |= bit_mask;
+ cur_offset += 4096;
+ }
}
+ // send data to client
if (sendfile(client->sock, image_cache, (off_t *) &request.offset, request.size) < 0)
printf("ERROR: Sendfile failed (net)\n");