Index: uspace/lib/libblock/libblock.c
===================================================================
--- uspace/lib/libblock/libblock.c	(revision 0c243b47a3b83c55eb04286f7246f90cbe615ad8)
+++ uspace/lib/libblock/libblock.c	(revision f1ba5d62689ce8c511830ed97b4cd78ee2ea8b24)
@@ -49,4 +49,5 @@
 #include <futex.h>
 #include <libadt/list.h>
+#include <libadt/hash_table.h>
 
 /** Lock protecting the device connection list */
@@ -54,4 +55,15 @@
 /** Device connection list head. */
 static LIST_INITIALIZE(dcl_head);
+
+#define CACHE_BUCKETS_LOG2		10
+#define CACHE_BUCKETS			(1 << CACHE_BUCKETS_LOG2)
+
+typedef struct {
+	futex_t lock;
+	size_t block_size;		/**< Block size. */
+	unsigned block_count;		/**< Total number of blocks. */
+	hash_table_t block_hash;
+	link_t free_head;
+} cache_t;
 
 typedef struct {
@@ -64,4 +76,5 @@
 	off_t bb_off;
 	size_t bb_size;
+	cache_t *cache;
 } devcon_t;
 
@@ -100,4 +113,5 @@
 	devcon->bb_off = 0;
 	devcon->bb_size = 0;
+	devcon->cache = NULL;
 
 	futex_down(&dcl_lock);
@@ -168,4 +182,10 @@
 	if (devcon->bb_buf)
 		free(devcon->bb_buf);
+
+	if (devcon->cache) {
+		hash_table_destroy(&devcon->cache->block_hash);
+		free(devcon->cache);
+	}
+
 	munmap(devcon->com_area, devcon->com_size);
 	ipc_hangup(devcon->dev_phone);
@@ -208,4 +228,52 @@
 	assert(devcon);
 	return devcon->bb_buf;
+}
+
+static hash_index_t cache_hash(unsigned long *key)
+{
+	return *key & (CACHE_BUCKETS - 1);
+}
+
+static int cache_compare(unsigned long *key, hash_count_t keys, link_t *item)
+{
+	block_t *b = hash_table_get_instance(item, block_t, hash_link);
+	return b->boff == *key;
+}
+
+static void cache_remove_callback(link_t *item)
+{
+}
+
+static hash_table_operations_t cache_ops = {
+	.hash = cache_hash,
+	.compare = cache_compare,
+	.remove_callback = cache_remove_callback
+};
+
+int block_cache_init(dev_handle_t dev_handle, size_t size, unsigned blocks)
+{
+	devcon_t *devcon = devcon_search(dev_handle);
+	cache_t *cache;
+	if (!devcon)
+		return ENOENT;
+	if (devcon->cache)
+		return EEXIST;
+	cache = malloc(sizeof(cache_t));
+	if (!cache)
+		return ENOMEM;
+	
+	futex_initialize(&cache->lock, 0);
+	list_initialize(&cache->free_head);
+	cache->block_size = size;
+	cache->block_count = blocks;
+
+	if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
+	    &cache_ops)) {
+		free(cache);
+		return ENOMEM;
+	}
+
+	devcon->cache = cache;
+	return EOK;
 }
 
Index: uspace/lib/libblock/libblock.h
===================================================================
--- uspace/lib/libblock/libblock.h	(revision 0c243b47a3b83c55eb04286f7246f90cbe615ad8)
+++ uspace/lib/libblock/libblock.h	(revision f1ba5d62689ce8c511830ed97b4cd78ee2ea8b24)
@@ -74,4 +74,6 @@
 extern void *block_bb_get(dev_handle_t);
 
+extern int block_cache_init(dev_handle_t, size_t, unsigned);
+
 extern block_t *block_get(dev_handle_t, off_t, size_t);
 extern void block_put(block_t *);
