Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 594303bc2c2613b4ab83c29adb62ad2b1a616d92)
+++ uspace/srv/fs/fat/fat_ops.c	(revision b6035ba00e0a19771a358284e5898b29f583e98f)
@@ -56,4 +56,7 @@
 #include <align.h>
 
+#define FAT_NODE(node)	((node) ? (fat_node_t *) (node)->data : NULL)
+#define FS_NODE(node)	((node) ? (node)->bp : NULL)
+
 /** Futex protecting the list of cached free FAT nodes. */
 static futex_t ffn_futex = FUTEX_INITIALIZER;
@@ -65,4 +68,5 @@
 {
 	futex_initialize(&node->lock, 1);
+	node->bp = NULL;
 	node->idx = NULL;
 	node->type = 0;
@@ -109,4 +113,5 @@
 static fat_node_t *fat_node_get_new(void)
 {
+	fs_node_t *fn;
 	fat_node_t *nodep;
 
@@ -130,13 +135,21 @@
 		futex_up(&nodep->lock);
 		futex_up(&idxp_tmp->lock);
+		fn = FS_NODE(nodep);
 	} else {
 skip_cache:
 		/* Try to allocate a new node structure. */
 		futex_up(&ffn_futex);
+		fn = (fs_node_t *)malloc(sizeof(fs_node_t));
+		if (!fn)
+			return NULL;
 		nodep = (fat_node_t *)malloc(sizeof(fat_node_t));
-		if (!nodep)
+		if (!nodep) {
+			free(fn);
 			return NULL;
+		}
 	}
 	fat_node_initialize(nodep);
+	fn->data = nodep;
+	nodep->bp = fn;
 	
 	return nodep;
@@ -147,5 +160,5 @@
  * @param idxp		Locked index structure.
  */
-static void *fat_node_get_core(fat_idx_t *idxp)
+static fat_node_t *fat_node_get_core(fat_idx_t *idxp)
 {
 	block_t *b;
@@ -224,19 +237,19 @@
  * Forward declarations of FAT libfs operations.
  */
-static void *fat_node_get(dev_handle_t, fs_index_t);
-static void fat_node_put(void *);
-static void *fat_create_node(dev_handle_t, int);
-static int fat_destroy_node(void *);
-static int fat_link(void *, void *, const char *);
-static int fat_unlink(void *, void *);
-static void *fat_match(void *, const char *);
-static fs_index_t fat_index_get(void *);
-static size_t fat_size_get(void *);
-static unsigned fat_lnkcnt_get(void *);
-static bool fat_has_children(void *);
-static void *fat_root_get(dev_handle_t);
+static fs_node_t *fat_node_get(dev_handle_t, fs_index_t);
+static void fat_node_put(fs_node_t *);
+static fs_node_t *fat_create_node(dev_handle_t, int);
+static int fat_destroy_node(fs_node_t *);
+static int fat_link(fs_node_t *, fs_node_t *, const char *);
+static int fat_unlink(fs_node_t *, fs_node_t *);
+static fs_node_t *fat_match(fs_node_t *, const char *);
+static fs_index_t fat_index_get(fs_node_t *);
+static size_t fat_size_get(fs_node_t *);
+static unsigned fat_lnkcnt_get(fs_node_t *);
+static bool fat_has_children(fs_node_t *);
+static fs_node_t *fat_root_get(dev_handle_t);
 static char fat_plb_get_char(unsigned);
-static bool fat_is_directory(void *);
-static bool fat_is_file(void *node);
+static bool fat_is_directory(fs_node_t *);
+static bool fat_is_file(fs_node_t *node);
 
 /*
@@ -245,7 +258,7 @@
 
 /** Instantiate a FAT in-core node. */
-void *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
-{
-	void *node;
+fs_node_t *fat_node_get(dev_handle_t dev_handle, fs_index_t index)
+{
+	fat_node_t *nodep;
 	fat_idx_t *idxp;
 
@@ -254,12 +267,12 @@
 		return NULL;
 	/* idxp->lock held */
-	node = fat_node_get_core(idxp);
+	nodep = fat_node_get_core(idxp);
 	futex_up(&idxp->lock);
-	return node;
-}
-
-void fat_node_put(void *node)
-{
-	fat_node_t *nodep = (fat_node_t *)node;
+	return FS_NODE(nodep);
+}
+
+void fat_node_put(fs_node_t *fn)
+{
+	fat_node_t *nodep = FAT_NODE(fn);
 	bool destroy = false;
 
@@ -281,9 +294,11 @@
 	}
 	futex_up(&nodep->lock);
-	if (destroy)
-		free(node);
-}
-
-void *fat_create_node(dev_handle_t dev_handle, int flags)
+	if (destroy) {
+		free(nodep->bp);
+		free(nodep);
+	}
+}
+
+fs_node_t *fat_create_node(dev_handle_t dev_handle, int flags)
 {
 	fat_idx_t *idxp;
@@ -311,5 +326,5 @@
 	if (!idxp) {
 		fat_free_clusters(bs, dev_handle, mcl);	
-		fat_node_put(nodep);
+		fat_node_put(FS_NODE(nodep));
 		return NULL;
 	}
@@ -346,10 +361,10 @@
 
 	futex_up(&idxp->lock);
-	return nodep;
-}
-
-int fat_destroy_node(void *node)
-{
-	fat_node_t *nodep = (fat_node_t *)node;
+	return FS_NODE(nodep);
+}
+
+int fat_destroy_node(fs_node_t *fn)
+{
+	fat_node_t *nodep = FAT_NODE(fn);
 	fat_bs_t *bs;
 
@@ -365,5 +380,5 @@
 	 * The node may not have any children.
 	 */
-	assert(fat_has_children(node) == false);
+	assert(fat_has_children(fn) == false);
 
 	bs = block_bb_get(nodep->idx->dev_handle);
@@ -375,12 +390,13 @@
 
 	fat_idx_destroy(nodep->idx);
+	free(nodep->bp);
 	free(nodep);
 	return EOK;
 }
 
-int fat_link(void *prnt, void *chld, const char *name)
-{
-	fat_node_t *parentp = (fat_node_t *)prnt;
-	fat_node_t *childp = (fat_node_t *)chld;
+int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
+{
+	fat_node_t *parentp = FAT_NODE(pfn);
+	fat_node_t *childp = FAT_NODE(cfn);
 	fat_dentry_t *d;
 	fat_bs_t *bs;
@@ -528,8 +544,8 @@
 }
 
-int fat_unlink(void *prnt, void *chld)
-{
-	fat_node_t *parentp = (fat_node_t *)prnt;
-	fat_node_t *childp = (fat_node_t *)chld;
+int fat_unlink(fs_node_t *pfn, fs_node_t *cfn)
+{
+	fat_node_t *parentp = FAT_NODE(pfn);
+	fat_node_t *childp = FAT_NODE(cfn);
 	fat_bs_t *bs;
 	fat_dentry_t *d;
@@ -568,8 +584,8 @@
 }
 
-void *fat_match(void *prnt, const char *component)
+fs_node_t *fat_match(fs_node_t *pfn, const char *component)
 {
 	fat_bs_t *bs;
-	fat_node_t *parentp = (fat_node_t *)prnt;
+	fat_node_t *parentp = FAT_NODE(pfn);
 	char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
 	unsigned i, j;
@@ -604,5 +620,5 @@
 			if (fat_dentry_namecmp(name, component) == 0) {
 				/* hit */
-				void *node;
+				fat_node_t *nodep;
 				/*
 				 * Assume tree hierarchy for locking.  We
@@ -623,8 +639,8 @@
 					return NULL;
 				}
-				node = fat_node_get_core(idx);
+				nodep = fat_node_get_core(idx);
 				futex_up(&idx->lock);
 				block_put(b);
-				return node;
+				return FS_NODE(nodep);
 			}
 		}
@@ -636,26 +652,23 @@
 }
 
-fs_index_t fat_index_get(void *node)
-{
-	fat_node_t *fnodep = (fat_node_t *)node;
-	if (!fnodep)
-		return 0;
-	return fnodep->idx->index;
-}
-
-size_t fat_size_get(void *node)
-{
-	return ((fat_node_t *)node)->size;
-}
-
-unsigned fat_lnkcnt_get(void *node)
-{
-	return ((fat_node_t *)node)->lnkcnt;
-}
-
-bool fat_has_children(void *node)
+fs_index_t fat_index_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->idx->index;
+}
+
+size_t fat_size_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->size;
+}
+
+unsigned fat_lnkcnt_get(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->lnkcnt;
+}
+
+bool fat_has_children(fs_node_t *fn)
 {
 	fat_bs_t *bs;
-	fat_node_t *nodep = (fat_node_t *)node;
+	fat_node_t *nodep = FAT_NODE(fn);
 	unsigned bps;
 	unsigned dps;
@@ -705,5 +718,5 @@
 }
 
-void *fat_root_get(dev_handle_t dev_handle)
+fs_node_t *fat_root_get(dev_handle_t dev_handle)
 {
 	return fat_node_get(dev_handle, 0);
@@ -715,12 +728,12 @@
 }
 
-bool fat_is_directory(void *node)
-{
-	return ((fat_node_t *)node)->type == FAT_DIRECTORY;
-}
-
-bool fat_is_file(void *node)
-{
-	return ((fat_node_t *)node)->type == FAT_FILE;
+bool fat_is_directory(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->type == FAT_DIRECTORY;
+}
+
+bool fat_is_file(fs_node_t *fn)
+{
+	return FAT_NODE(fn)->type == FAT_FILE;
 }
 
@@ -822,6 +835,6 @@
 
 	/* Initialize the root node. */
-	fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
-	if (!rootp) {
+	fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t));
+	if (!rfn) {
 		block_fini(dev_handle);
 		fat_idx_fini_by_dev_handle(dev_handle);
@@ -829,10 +842,19 @@
 		return;
 	}
+	fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
+	if (!rootp) {
+		free(rfn);
+		block_fini(dev_handle);
+		fat_idx_fini_by_dev_handle(dev_handle);
+		ipc_answer_0(rid, ENOMEM);
+		return;
+	}
 	fat_node_initialize(rootp);
 
 	fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0);
 	if (!ridxp) {
+		free(rfn);
+		free(rootp);
 		block_fini(dev_handle);
-		free(rootp);
 		fat_idx_fini_by_dev_handle(dev_handle);
 		ipc_answer_0(rid, ENOMEM);
@@ -849,4 +871,6 @@
 	rootp->idx = ridxp;
 	ridxp->nodep = rootp;
+	rootp->bp = rfn;
+	rfn->data = rootp;
 	
 	futex_up(&ridxp->lock);
@@ -870,5 +894,6 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	off_t pos = (off_t)IPC_GET_ARG3(*request);
-	fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
+	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fat_node_t *nodep;
 	fat_bs_t *bs;
 	uint16_t bps;
@@ -876,13 +901,14 @@
 	block_t *b;
 
-	if (!nodep) {
+	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
 		return;
 	}
+	nodep = FAT_NODE(fn);
 
 	ipc_callid_t callid;
 	size_t len;
 	if (!ipc_data_read_receive(&callid, &len)) {
-		fat_node_put(nodep);
+		fat_node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -955,5 +981,5 @@
 		}
 miss:
-		fat_node_put(nodep);
+		fat_node_put(fn);
 		ipc_answer_0(callid, ENOENT);
 		ipc_answer_1(rid, ENOENT, 0);
@@ -964,5 +990,5 @@
 	}
 
-	fat_node_put(nodep);
+	fat_node_put(fn);
 	ipc_answer_1(rid, EOK, (ipcarg_t)bytes);
 }
@@ -973,5 +999,6 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	off_t pos = (off_t)IPC_GET_ARG3(*request);
-	fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
+	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fat_node_t *nodep;
 	fat_bs_t *bs;
 	size_t bytes;
@@ -983,13 +1010,14 @@
 	int flags = BLOCK_FLAGS_NONE;
 	
-	if (!nodep) {
+	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
 		return;
 	}
+	nodep = FAT_NODE(fn);
 	
 	ipc_callid_t callid;
 	size_t len;
 	if (!ipc_data_write_receive(&callid, &len)) {
-		fat_node_put(nodep);
+		fat_node_put(fn);
 		ipc_answer_0(callid, EINVAL);
 		ipc_answer_0(rid, EINVAL);
@@ -1032,5 +1060,5 @@
 		}
 		ipc_answer_2(rid, EOK, bytes, nodep->size);	
-		fat_node_put(nodep);
+		fat_node_put(fn);
 		return;
 	} else {
@@ -1048,5 +1076,5 @@
 		if (status != EOK) {
 			/* could not allocate a chain of nclsts clusters */
-			fat_node_put(nodep);
+			fat_node_put(fn);
 			ipc_answer_0(callid, status);
 			ipc_answer_0(rid, status);
@@ -1069,5 +1097,5 @@
 		nodep->dirty = true;		/* need to sync node */
 		ipc_answer_2(rid, EOK, bytes, nodep->size);
-		fat_node_put(nodep);
+		fat_node_put(fn);
 		return;
 	}
@@ -1079,5 +1107,6 @@
 	fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
 	size_t size = (off_t)IPC_GET_ARG3(*request);
-	fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index);
+	fs_node_t *fn = fat_node_get(dev_handle, index);
+	fat_node_t *nodep;
 	fat_bs_t *bs;
 	uint16_t bps;
@@ -1086,8 +1115,9 @@
 	int rc;
 
-	if (!nodep) {
+	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
 		return;
 	}
+	nodep = FAT_NODE(fn);
 
 	bs = block_bb_get(dev_handle);
@@ -1127,5 +1157,5 @@
 		rc = EOK;	
 	}
-	fat_node_put(nodep);
+	fat_node_put(fn);
 	ipc_answer_0(rid, rc);
 	return;
@@ -1138,11 +1168,11 @@
 	int rc;
 
-	fat_node_t *nodep = fat_node_get(dev_handle, index);
-	if (!nodep) {
+	fs_node_t *fn = fat_node_get(dev_handle, index);
+	if (!fn) {
 		ipc_answer_0(rid, ENOENT);
 		return;
 	}
 
-	rc = fat_destroy_node(nodep);
+	rc = fat_destroy_node(fn);
 	ipc_answer_0(rid, rc);
 }
