Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision 0ca7286a618557bd1d13cded4ccbe25d62752237)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision da68871a1ca8b07736e941032a954a3f19eadccc)
@@ -50,4 +50,5 @@
 #include <sys/types.h>
 #include <adt/hash_table.h>
+#include <adt/hash.h>
 #include <as.h>
 #include <libfs.h>
@@ -140,51 +141,36 @@
 hash_table_t nodes;
 
-#define NODES_KEY_DEV	0	
-#define NODES_KEY_INDEX	1
-
-/* Implementation of hash table interface for the nodes hash table. */
-static size_t nodes_key_hash(unsigned long key[])
-{
-	/* Based on Effective Java, 2nd Edition. */
-	size_t hash = 17;
-	hash = 37 * hash + key[NODES_KEY_DEV];
-	hash = 37 * hash + key[NODES_KEY_INDEX];
-	return hash;
-}
-
-static size_t nodes_hash(const link_t *item)
-{
-	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, nh_link);
-	
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = nodep->service_id,
-		[NODES_KEY_INDEX] = nodep->index
-	};
-	
-	return nodes_key_hash(key);
-}
-
-static bool nodes_match(unsigned long key[], size_t keys, const link_t *item)
-{
-	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
-	    nh_link);
-	
-	switch (keys) {
-	case 1:
-		return (nodep->service_id == key[NODES_KEY_DEV]);
-	case 2:	
-		return ((nodep->service_id == key[NODES_KEY_DEV]) &&
-		    (nodep->index == key[NODES_KEY_INDEX]));
-	default:
-		assert((keys == 1) || (keys == 2));
-	}
-
-	return 0;
-}
-
-static void nodes_remove_callback(link_t *item)
-{
-	tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t,
-	    nh_link);
+/* 
+ * Implementation of hash table interface for the nodes hash table. 
+ */
+
+typedef struct {
+	service_id_t service_id;
+	fs_index_t index;
+} node_key_t;
+
+static size_t nodes_key_hash(void *k)
+{
+	node_key_t *key = (node_key_t *)k;
+	return hash_combine(key->service_id, key->index);
+}
+
+static size_t nodes_hash(const ht_link_t *item)
+{
+	tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
+	return hash_combine(nodep->service_id, nodep->index);
+}
+
+static bool nodes_key_equal(void *key_arg, const ht_link_t *item)
+{
+	tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
+	node_key_t *key = (node_key_t *)key_arg;
+	
+	return key->service_id == node->service_id && key->index == node->index;
+}
+
+static void nodes_remove_callback(ht_link_t *item)
+{
+	tmpfs_node_t *nodep = hash_table_get_inst(item, tmpfs_node_t, nh_link);
 
 	while (!list_empty(&nodep->cs_list)) {
@@ -209,5 +195,5 @@
 	.hash = nodes_hash,
 	.key_hash = nodes_key_hash,
-	.match = nodes_match,
+	.key_equal = nodes_key_equal,
 	.equal = 0,
 	.remove_callback = nodes_remove_callback
@@ -223,5 +209,4 @@
 	nodep->size = 0;
 	nodep->data = NULL;
-	link_initialize(&nodep->nh_link);
 	list_initialize(&nodep->cs_list);
 }
@@ -236,5 +221,5 @@
 bool tmpfs_init(void)
 {
-	if (!hash_table_create(&nodes, 0, 2, &nodes_ops))
+	if (!hash_table_create(&nodes, 0, 0, &nodes_ops))
 		return false;
 	
@@ -254,17 +239,18 @@
 }
 
+static bool rm_service_id_nodes(ht_link_t *item, void *arg)
+{
+	service_id_t sid = *(service_id_t*)arg;
+	tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
+	
+	if (node->service_id == sid) {
+		hash_table_remove_item(&nodes, &node->nh_link);
+	}
+	return true;
+}
+
 static void tmpfs_instance_done(service_id_t service_id)
-{
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id
-	};
-	/*
-	 * Here we are making use of one special feature of our hash table
-	 * implementation, which allows to remove more items based on a partial
-	 * key match. In the following, we are going to remove all nodes
-	 * matching our device handle. The nodes_remove_callback() function will
-	 * take care of resource deallocation.
-	 */
-	hash_table_remove(&nodes, key, 1);
+{	
+	hash_table_apply(&nodes, rm_service_id_nodes, &service_id);
 }
 
@@ -288,12 +274,14 @@
 int tmpfs_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
 {
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id,
-		[NODES_KEY_INDEX] = index
+	node_key_t key = {
+		.service_id = service_id,
+		.index = index
 	};
-	link_t *lnk = hash_table_find(&nodes, key);
+	
+	ht_link_t *lnk = hash_table_find(&nodes, &key);
+	
 	if (lnk) {
 		tmpfs_node_t *nodep;
-		nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link);
+		nodep = hash_table_get_inst(lnk, tmpfs_node_t, nh_link);
 		*rfn = FS_NODE(nodep);
 	} else {
@@ -358,10 +346,6 @@
 	assert(!nodep->lnkcnt);
 	assert(list_empty(&nodep->cs_list));
-
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = nodep->service_id,
-		[NODES_KEY_INDEX] = nodep->index
-	};
-	hash_table_remove(&nodes, key, 2);
+	
+	hash_table_remove_item(&nodes, &nodep->nh_link);
 
 	/*
@@ -488,14 +472,14 @@
 	 * Lookup the respective TMPFS node.
 	 */
-	link_t *hlp;
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id,
-		[NODES_KEY_INDEX] = index
+	node_key_t key = {
+		.service_id = service_id,
+		.index = index
 	};
-	hlp = hash_table_find(&nodes, key);
+	
+	ht_link_t *hlp = hash_table_find(&nodes, &key);
 	if (!hlp)
 		return ENOENT;
-	tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
-	    nh_link);
+	
+	tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
 	
 	/*
@@ -550,14 +534,15 @@
 	 * Lookup the respective TMPFS node.
 	 */
-	link_t *hlp;
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id,
-		[NODES_KEY_INDEX] = index
+	node_key_t key = {
+		.service_id = service_id,
+		.index = index
 	};
-	hlp = hash_table_find(&nodes, key);
+	
+	ht_link_t *hlp = hash_table_find(&nodes, &key);
+	
 	if (!hlp)
 		return ENOENT;
-	tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
-	    nh_link);
+	
+	tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
 
 	/*
@@ -612,12 +597,14 @@
 	 * Lookup the respective TMPFS node.
 	 */
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id,
-		[NODES_KEY_INDEX] = index
+	node_key_t key = {
+		.service_id = service_id,
+		.index = index
 	};
-	link_t *hlp = hash_table_find(&nodes, key);
+	
+	ht_link_t *hlp = hash_table_find(&nodes, &key);
+	
 	if (!hlp)
 		return ENOENT;
-	tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
+	tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t, nh_link);
 	
 	if (size == nodep->size)
@@ -648,13 +635,13 @@
 static int tmpfs_destroy(service_id_t service_id, fs_index_t index)
 {
-	link_t *hlp;
-	unsigned long key[] = {
-		[NODES_KEY_DEV] = service_id,
-		[NODES_KEY_INDEX] = index
+	node_key_t key = {
+		.service_id = service_id,
+		.index = index
 	};
-	hlp = hash_table_find(&nodes, key);
+	
+	ht_link_t *hlp = hash_table_find(&nodes, &key);
 	if (!hlp)
 		return ENOENT;
-	tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
+	tmpfs_node_t *nodep = hash_table_get_inst(hlp, tmpfs_node_t,
 	    nh_link);
 	return tmpfs_destroy_node(FS_NODE(nodep));
