Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision 4573a79348e83cbae6141590afc45dce5aaecfca)
+++ uspace/srv/fs/fat/fat.h	(revision 2c4bbcde8f30256df2515ebfc870bfff18e933ed)
@@ -206,6 +206,4 @@
 	 */
 	fat_cluster_t		firstc;
-	/** FAT in-core node hash table link. */
-	link_t 			fin_link;
 	/** FAT in-core node free list link. */
 	link_t			ffn_link;
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 4573a79348e83cbae6141590afc45dce5aaecfca)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 2c4bbcde8f30256df2515ebfc870bfff18e933ed)
@@ -51,12 +51,6 @@
 #define BS_BLOCK		0
 
-#define FIN_KEY_DEV_HANDLE	0
-#define FIN_KEY_INDEX		1
-
-/** Hash table of FAT in-core nodes. */
-hash_table_t fin_hash;
-
-/** List of free FAT in-core nodes. */
-link_t ffn_head;
+/** List of free FAT nodes that still contain valid data. */
+LIST_INITIALIZE(ffn_head);
 
 #define FAT_NAME_LEN		8
@@ -126,5 +120,5 @@
 
 static block_t *
-_fat_block_get(dev_handle_t dev_handle, fat_cluster_t fc, off_t offset)
+_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)
 {
 	block_t *bb;
@@ -139,5 +133,5 @@
 	unsigned ssa;		/* size of the system area */
 	unsigned clusters;
-	fat_cluster_t clst = fc;
+	fat_cluster_t clst = firstc;
 	unsigned i;
 
@@ -155,5 +149,5 @@
 	ssa = rscnt + fatcnt * sf + rds;
 
-	if (fc == FAT_CLST_RES1) {
+	if (firstc == FAT_CLST_RES1) {
 		/* root directory special case */
 		assert(offset < rds);
@@ -188,5 +182,4 @@
 	node->idx = NULL;
 	node->type = 0;
-	link_initialize(&node->fin_link);
 	link_initialize(&node->ffn_link);
 	node->size = 0;
@@ -239,5 +232,5 @@
 }
 
-static void fat_sync_node(fat_node_t *node)
+static void fat_node_sync(fat_node_t *node)
 {
 	/* TODO */
@@ -273,7 +266,17 @@
 	assert(idx->pfc);
 
-	nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
-	if (!nodep)
-		return NULL;
+	if (!list_empty(&ffn_head)) {
+		/* Try to use a cached unused node structure. */
+		nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link);
+		if (nodep->dirty)
+			fat_node_sync(nodep);
+		list_remove(&nodep->ffn_link);
+		nodep->idx->nodep = NULL;
+	} else {
+		/* Try to allocate a new node structure. */
+		nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
+		if (!nodep)
+			return NULL;
+	}
 	fat_node_initialize(nodep);
 
@@ -281,11 +284,32 @@
 	dps = bps / sizeof(fat_dentry_t);
 
+	/* Read the block that contains the dentry of interest. */
 	b = _fat_block_get(dev_handle, idx->pfc,
 	    (idx->pdi * sizeof(fat_dentry_t)) / bps);
-
 	assert(b);
 
 	d = ((fat_dentry_t *)b->data) + (idx->pdi % dps);
-	/* XXX */
+	if (d->attr & FAT_ATTR_SUBDIR) {
+		/* 
+		 * The only directory which does not have this bit set is the
+		 * root directory itself. The root directory node is handled
+		 * and initialized elsewhere.
+		 */
+		nodep->type = FAT_DIRECTORY;
+	} else {
+		nodep->type = FAT_FILE;
+	}
+	nodep->firstc = uint16_t_le2host(d->firstc);
+	nodep->size = uint32_t_le2host(d->size);
+	nodep->lnkcnt = 1;
+	nodep->refcnt = 1;
+
+	block_put(b);
+
+	/* Link the idx structure with the node structure. */
+	nodep->idx = idx;
+	idx->nodep = nodep;
+
+	return nodep;
 }
 
@@ -441,5 +465,5 @@
 static void *fat_root_get(dev_handle_t dev_handle)
 {
-	return fat_node_get(dev_handle, 0);	/* TODO */
+	return NULL;	/* TODO */
 }
 
