Index: uspace/srv/fs/mfs/mfs_ops.c
===================================================================
--- uspace/srv/fs/mfs/mfs_ops.c	(revision 9d58539899ea3bf36d74e87b391c0a986e338e26)
+++ uspace/srv/fs/mfs/mfs_ops.c	(revision 4e00f8748907db19e8c6b776b1d4c98f5e411035)
@@ -35,10 +35,7 @@
 #include <align.h>
 #include <adt/hash_table.h>
+#include <adt/hash.h>
 #include "mfs.h"
 
-#define OPEN_NODES_KEYS 2
-#define OPEN_NODES_SERVICE_KEY 0
-#define OPEN_NODES_INODE_KEY 1
-#define OPEN_NODES_BUCKETS 256
 
 static bool check_magic_number(uint16_t magic, bool *native,
@@ -61,8 +58,4 @@
 static int mfs_unlink(fs_node_t *, fs_node_t *, const char *name);
 static int mfs_destroy_node(fs_node_t *fn);
-static hash_index_t open_nodes_hash(unsigned long key[]);
-static int open_nodes_compare(unsigned long key[], hash_count_t keys,
-    link_t *item);
-static void open_nodes_remove_cb(link_t *link);
 static int mfs_node_get(fs_node_t **rfn, service_id_t service_id,
     fs_index_t index);
@@ -95,38 +88,40 @@
 
 /* Hash table interface for open nodes hash table */
-static hash_index_t
-open_nodes_hash(unsigned long key[])
-{
-	/* TODO: This is very simple and probably can be improved */
-	return key[OPEN_NODES_INODE_KEY] % OPEN_NODES_BUCKETS;
-}
-
-static int
-open_nodes_compare(unsigned long key[], hash_count_t keys,
-    link_t *item)
-{
-	struct mfs_node *mnode = hash_table_get_instance(item, struct mfs_node, link);
-	assert(keys > 0);
-	if (mnode->instance->service_id !=
-	    ((service_id_t) key[OPEN_NODES_SERVICE_KEY])) {
-		return false;
-	}
-	if (keys == 1) {
-		return true;
-	}
-	assert(keys == 2);
-	return (mnode->ino_i->index == key[OPEN_NODES_INODE_KEY]);
-}
-
-static void
-open_nodes_remove_cb(link_t *link)
-{
-	/* We don't use remove callback for this hash table */
-}
-
-static hash_table_operations_t open_nodes_ops = {
+
+typedef struct {
+	service_id_t service_id;
+	fs_index_t index;
+} node_key_t;
+
+static size_t
+open_nodes_key_hash(void *key)
+{
+	node_key_t *node_key = (node_key_t*)key;
+	return hash_combine(node_key->service_id, node_key->index);
+}
+
+static size_t
+open_nodes_hash(const ht_link_t *item)
+{
+	struct mfs_node *m = hash_table_get_inst(item, struct mfs_node, link);
+	return hash_combine(m->instance->service_id, m->ino_i->index);
+}
+
+static bool
+open_nodes_key_equal(void *key, const ht_link_t *item)
+{
+	node_key_t *node_key = (node_key_t*)key;
+	struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link);
+
+	return node_key->service_id == mnode->instance->service_id
+		&& node_key->index == mnode->ino_i->index;
+}
+
+static hash_table_ops_t open_nodes_ops = {
 	.hash = open_nodes_hash,
-	.compare = open_nodes_compare,
-	.remove_callback = open_nodes_remove_cb,
+	.key_hash = open_nodes_key_hash,
+	.key_equal = open_nodes_key_equal,
+	.equal = NULL,
+	.remove_callback = NULL,
 };
 
@@ -134,6 +129,5 @@
 mfs_global_init(void)
 {
-	if (!hash_table_create(&open_nodes, OPEN_NODES_BUCKETS,
-	    OPEN_NODES_KEYS, &open_nodes_ops)) {
+	if (!hash_table_create(&open_nodes, 0, 0, &open_nodes_ops)) {
 		return ENOMEM;
 	}
@@ -406,13 +400,6 @@
 	mnode->refcnt = 1;
 
-	link_initialize(&mnode->link);
-
-	unsigned long key[] = {
-		[OPEN_NODES_SERVICE_KEY] = inst->service_id,
-		[OPEN_NODES_INODE_KEY] = inum,
-	};
-
 	fibril_mutex_lock(&open_nodes_lock);
-	hash_table_insert(&open_nodes, key, &mnode->link);
+	hash_table_insert(&open_nodes, &mnode->link);
 	fibril_mutex_unlock(&open_nodes_lock);
 	inst->open_nodes_cnt++;
@@ -513,9 +500,5 @@
 	mnode->refcnt--;
 	if (mnode->refcnt == 0) {
-		unsigned long key[] = {
-			[OPEN_NODES_SERVICE_KEY] = mnode->instance->service_id,
-			[OPEN_NODES_INODE_KEY] = mnode->ino_i->index
-		};
-		hash_table_remove(&open_nodes, key, OPEN_NODES_KEYS);
+		hash_table_remove_item(&open_nodes, &mnode->link);
 		assert(mnode->instance->open_nodes_cnt > 0);
 		mnode->instance->open_nodes_cnt--;
@@ -576,12 +559,13 @@
 
 	/* Check if the node is not already open */
-	unsigned long key[] = {
-		[OPEN_NODES_SERVICE_KEY] = inst->service_id,
-		[OPEN_NODES_INODE_KEY] = index,
+	node_key_t key = {
+		.service_id = inst->service_id,
+		.index = index
 	};
-	link_t *already_open = hash_table_find(&open_nodes, key);
+	
+	ht_link_t *already_open = hash_table_find(&open_nodes, &key);
 
 	if (already_open) {
-		mnode = hash_table_get_instance(already_open, struct mfs_node, link);
+		mnode = hash_table_get_inst(already_open, struct mfs_node, link);
 		*rfn = mnode->fsnode;
 		mnode->refcnt++;
@@ -614,5 +598,4 @@
 	mnode->ino_i = ino_i;
 	mnode->refcnt = 1;
-	link_initialize(&mnode->link);
 
 	mnode->instance = inst;
@@ -621,5 +604,5 @@
 	*rfn = node;
 
-	hash_table_insert(&open_nodes, key, &mnode->link);
+	hash_table_insert(&open_nodes, &mnode->link);
 	inst->open_nodes_cnt++;
 
