Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision 033ef7d3ebd26f503a057f953c613adf78848e0f)
+++ uspace/srv/fs/fat/fat.h	(revision 0f57d0ea02e6cdbe99794e82287279b59c734cb5)
@@ -34,4 +34,5 @@
 #define FAT_FAT_H_
 
+#include "fat_fat.h"
 #include <ipc/ipc.h>
 #include <libfs.h>
@@ -44,4 +45,9 @@
 #define dprintf(...)	printf(__VA_ARGS__)
 #endif
+
+#define min(a, b)		((a) < (b) ? (a) : (b))
+
+#define BS_BLOCK		0
+#define BS_SIZE			512
 
 typedef struct {
@@ -116,5 +122,5 @@
 } __attribute__ ((packed)) fat_bs_t;
 
-typedef uint16_t fat_cluster_t;
+#define FAT_BS(b)		((fat_bs_t *)((b)->data))
 
 typedef enum {
@@ -192,4 +198,14 @@
 } fat_node_t;
 
+/* TODO move somewhere else */
+typedef struct block {
+	void *data;
+	size_t size;
+	bool dirty;
+} block_t;
+
+extern block_t *block_get(dev_handle_t, off_t, size_t);
+extern void block_put(block_t *);
+
 extern fs_reg_t fat_reg;
 
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision 033ef7d3ebd26f503a057f953c613adf78848e0f)
+++ uspace/srv/fs/fat/fat_fat.c	(revision 0f57d0ea02e6cdbe99794e82287279b59c734cb5)
@@ -36,4 +36,262 @@
  */
 
+#include "fat_fat.h"
+#include "fat_dentry.h"
+#include "fat.h"
+#include "../../vfs/vfs.h"
+#include <libfs.h>
+#include <errno.h>
+#include <byteorder.h>
+#include <align.h>
+#include <assert.h>
+
+block_t *
+_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)
+{
+	block_t *bb;
+	block_t *b;
+	unsigned bps;
+	unsigned spc;
+	unsigned rscnt;		/* block address of the first FAT */
+	unsigned fatcnt;
+	unsigned rde;
+	unsigned rds;		/* root directory size */
+	unsigned sf;
+	unsigned ssa;		/* size of the system area */
+	unsigned clusters;
+	fat_cluster_t clst = firstc;
+	unsigned i;
+
+	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
+	bps = uint16_t_le2host(FAT_BS(bb)->bps);
+	spc = FAT_BS(bb)->spc;
+	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
+	fatcnt = FAT_BS(bb)->fatcnt;
+	rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
+	sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
+	block_put(bb);
+
+	rds = (sizeof(fat_dentry_t) * rde) / bps;
+	rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
+	ssa = rscnt + fatcnt * sf + rds;
+
+	if (firstc == FAT_CLST_ROOT) {
+		/* root directory special case */
+		assert(offset < rds);
+		b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps);
+		return b;
+	}
+
+	clusters = offset / spc; 
+	for (i = 0; i < clusters; i++) {
+		unsigned fsec;	/* sector offset relative to FAT1 */
+		unsigned fidx;	/* FAT1 entry index */
+
+		assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
+		fsec = (clst * sizeof(fat_cluster_t)) / bps;
+		fidx = clst % (bps / sizeof(fat_cluster_t));
+		/* read FAT1 */
+		b = block_get(dev_handle, rscnt + fsec, bps);
+		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
+		assert(clst != FAT_CLST_BAD);
+		assert(clst < FAT_CLST_LAST1);
+		block_put(b);
+	}
+
+	b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
+	    offset % spc, bps);
+
+	return b;
+}
+
+/** Return number of blocks allocated to a file.
+ *
+ * @param dev_handle	Device handle of the device with the file.
+ * @param firstc	First cluster of the file.
+ *
+ * @return		Number of blocks allocated to the file.
+ */
+uint16_t 
+_fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc)
+{
+	block_t *bb;
+	block_t *b;
+	unsigned bps;
+	unsigned spc;
+	unsigned rscnt;		/* block address of the first FAT */
+	unsigned clusters = 0;
+	fat_cluster_t clst = firstc;
+
+	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
+	bps = uint16_t_le2host(FAT_BS(bb)->bps);
+	spc = FAT_BS(bb)->spc;
+	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
+	block_put(bb);
+
+	if (firstc == FAT_CLST_RES0) {
+		/* No space allocated to the file. */
+		return 0;
+	}
+
+	while (clst < FAT_CLST_LAST1) {
+		unsigned fsec;	/* sector offset relative to FAT1 */
+		unsigned fidx;	/* FAT1 entry index */
+
+		assert(clst >= FAT_CLST_FIRST);
+		fsec = (clst * sizeof(fat_cluster_t)) / bps;
+		fidx = clst % (bps / sizeof(fat_cluster_t));
+		/* read FAT1 */
+		b = block_get(dev_handle, rscnt + fsec, bps);
+		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
+		assert(clst != FAT_CLST_BAD);
+		block_put(b);
+		clusters++;
+	}
+
+	return clusters * spc;
+}
+
+uint16_t fat_bps_get(dev_handle_t dev_handle)
+{
+	block_t *bb;
+	uint16_t bps;
+	
+	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
+	assert(bb != NULL);
+	bps = uint16_t_le2host(FAT_BS(bb)->bps);
+	block_put(bb);
+
+	return bps;
+}
+
+/** Fill the gap between EOF and a new file position.
+ *
+ * @param nodep		FAT node with the gap.
+ * @param mcl		First cluster in an independent cluster chain that will
+ *			be later appended to the end of the node's own cluster
+ *			chain. If pos is still in the last allocated cluster,
+ *			this argument is ignored.
+ * @param pos		Position in the last node block.
+ */
+void fat_fill_gap(fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
+{
+	uint16_t bps;
+	unsigned spc;
+	block_t *bb, *b;
+	off_t o, boundary;
+
+	bb = block_get(nodep->idx->dev_handle, BS_BLOCK, BS_SIZE);
+	bps = uint16_t_le2host(FAT_BS(bb)->bps);
+	spc = FAT_BS(bb)->spc;
+	block_put(bb);
+	
+	boundary = ROUND_UP(nodep->size, bps * spc);
+
+	/* zero out already allocated space */
+	for (o = nodep->size - 1; o < pos && o < boundary;
+	    o = ALIGN_DOWN(o + bps, bps)) {
+		b = fat_block_get(nodep, o / bps);
+		memset(b->data + o % bps, 0, bps - o % bps);
+		b->dirty = true;		/* need to sync node */
+		block_put(b);
+	}
+	
+	if (o >= pos)
+		return;
+	
+	/* zero out the initial part of the new cluster chain */
+	for (o = boundary; o < pos; o += bps) {
+		b = _fat_block_get(nodep->idx->dev_handle, mcl,
+		    (o - boundary) / bps);
+		memset(b->data, 0, min(bps, pos - o));
+		b->dirty = true;		/* need to sync node */
+		block_put(b);
+	}
+}
+
+void
+fat_mark_cluster(dev_handle_t dev_handle, unsigned fatno, fat_cluster_t clst,
+    fat_cluster_t value)
+{
+	/* TODO */
+}
+
+void
+fat_alloc_shadow_clusters(dev_handle_t dev_handle, fat_cluster_t *lifo,
+    unsigned nclsts)
+{
+	/* TODO */
+}
+
+int
+fat_alloc_clusters(dev_handle_t dev_handle, unsigned nclsts, fat_cluster_t *mcl,
+    fat_cluster_t *lcl)
+{
+	uint16_t bps;
+	uint16_t rscnt;
+	uint16_t sf;
+	block_t *bb, *blk;
+	fat_cluster_t *lifo;	/* stack for storing free cluster numbers */ 
+	unsigned found = 0;	/* top of the free cluster number stack */
+	unsigned b, c, cl; 
+
+	lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
+	if (lifo)
+		return ENOMEM;
+	
+	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
+	bps = uint16_t_le2host(FAT_BS(bb)->bps);
+	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
+	sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
+	block_put(bb);
+	
+	/*
+	 * Search FAT1 for unused clusters.
+	 */
+	for (b = 0, cl = 0; b < sf; blk++) {
+		blk = block_get(dev_handle, rscnt + b, bps);
+		for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
+			fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
+			if (*clst == FAT_CLST_RES0) {
+				/*
+				 * The cluster is free. Put it into our stack
+				 * of found clusters and mark it as non-free.
+				 */
+				lifo[found] = cl;
+				if (found == 0)
+					*clst = FAT_CLST_LAST1;
+				else
+					*clst = lifo[found - 1];
+				blk->dirty = true;	/* need to sync block */
+				if (++found == nclsts) {
+					/* we are almost done */
+					block_put(blk);
+					/* update the shadow copies of FAT */
+					fat_alloc_shadow_clusters(dev_handle,
+					    lifo, nclsts);
+					*mcl = lifo[found - 1];
+					*lcl = lifo[0];
+					free(lifo);
+					return EOK;
+				}
+			}
+		}
+		block_put(blk);
+	}
+
+	/*
+	 * We could not find enough clusters. Now we need to free the clusters
+	 * we have allocated so far.
+	 */
+	while (found--)
+		fat_mark_cluster(dev_handle, FAT1, lifo[found], FAT_CLST_RES0);
+	
+	free(lifo);
+	return ENOSPC;
+}
+
+void fat_append_clusters(fat_node_t *nodep, fat_cluster_t mcl)
+{
+}
 
 /**
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision 033ef7d3ebd26f503a057f953c613adf78848e0f)
+++ uspace/srv/fs/fat/fat_fat.h	(revision 0f57d0ea02e6cdbe99794e82287279b59c734cb5)
@@ -34,4 +34,43 @@
 #define FAT_FAT_FAT_H_
 
+#include "../../vfs/vfs.h"
+#include <stdint.h>
+
+#define FAT1		0
+
+#define FAT_CLST_RES0	0x0000
+#define FAT_CLST_RES1	0x0001
+#define FAT_CLST_FIRST	0x0002
+#define FAT_CLST_BAD	0xfff7
+#define FAT_CLST_LAST1	0xfff8
+#define FAT_CLST_LAST8  0xffff
+
+/* internally used to mark root directory's parent */
+#define FAT_CLST_ROOTPAR	FAT_CLST_RES0
+/* internally used to mark root directory */
+#define FAT_CLST_ROOT		FAT_CLST_RES1
+
+
+/* forward declarations */
+struct block;
+struct fat_node;
+
+typedef uint16_t fat_cluster_t;
+
+#define fat_block_get(np, off) \
+    _fat_block_get((np)->idx->dev_handle, (np)->firstc, (off))
+    
+extern struct block *_fat_block_get(dev_handle_t, fat_cluster_t, off_t);
+extern uint16_t _fat_blcks_get(dev_handle_t, fat_cluster_t);
+extern uint16_t fat_bps_get(dev_handle_t);
+  
+extern void fat_append_clusters(struct fat_node *, fat_cluster_t);
+extern int fat_alloc_clusters(dev_handle_t, unsigned, fat_cluster_t *,
+    fat_cluster_t *);
+extern void fat_alloc_shadow_clusters(dev_handle_t, fat_cluster_t *, unsigned);
+extern void fat_mark_cluster(dev_handle_t, unsigned, fat_cluster_t,
+    fat_cluster_t);
+extern void fat_fill_gap(struct fat_node *, fat_cluster_t, off_t);
+
 #endif
 
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 033ef7d3ebd26f503a057f953c613adf78848e0f)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 0f57d0ea02e6cdbe99794e82287279b59c734cb5)
@@ -55,7 +55,4 @@
 #include <align.h>
 
-#define BS_BLOCK		0
-#define BS_SIZE			512
-
 /** Futex protecting the list of cached free FAT nodes. */
 static futex_t ffn_futex = FUTEX_INITIALIZER;
@@ -64,17 +61,8 @@
 static LIST_INITIALIZE(ffn_head);
 
-#define min(a, b)		((a) < (b) ? (a) : (b))
-
 static int dev_phone = -1;		/* FIXME */
 static void *dev_buffer = NULL;		/* FIXME */
 
-/* TODO move somewhere else */
-typedef struct {
-	void *data;
-	size_t size;
-	bool dirty;
-} block_t;
-
-static block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
+block_t *block_get(dev_handle_t dev_handle, off_t offset, size_t bs)
 {
 	/* FIXME */
@@ -108,134 +96,9 @@
 }
 
-static void block_put(block_t *block)
+void block_put(block_t *block)
 {
 	/* FIXME */
 	free(block->data);
 	free(block);
-}
-
-#define FAT1		0
-
-#define FAT_BS(b)		((fat_bs_t *)((b)->data))
-
-#define FAT_CLST_RES0	0x0000
-#define FAT_CLST_RES1	0x0001
-#define FAT_CLST_FIRST	0x0002
-#define FAT_CLST_BAD	0xfff7
-#define FAT_CLST_LAST1	0xfff8
-#define FAT_CLST_LAST8  0xffff
-
-/* internally used to mark root directory's parent */
-#define FAT_CLST_ROOTPAR	FAT_CLST_RES0
-/* internally used to mark root directory */
-#define FAT_CLST_ROOT		FAT_CLST_RES1
-
-#define fat_block_get(np, off) \
-    _fat_block_get((np)->idx->dev_handle, (np)->firstc, (off))
-
-static block_t *
-_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset)
-{
-	block_t *bb;
-	block_t *b;
-	unsigned bps;
-	unsigned spc;
-	unsigned rscnt;		/* block address of the first FAT */
-	unsigned fatcnt;
-	unsigned rde;
-	unsigned rds;		/* root directory size */
-	unsigned sf;
-	unsigned ssa;		/* size of the system area */
-	unsigned clusters;
-	fat_cluster_t clst = firstc;
-	unsigned i;
-
-	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
-	bps = uint16_t_le2host(FAT_BS(bb)->bps);
-	spc = FAT_BS(bb)->spc;
-	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
-	fatcnt = FAT_BS(bb)->fatcnt;
-	rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max);
-	sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
-	block_put(bb);
-
-	rds = (sizeof(fat_dentry_t) * rde) / bps;
-	rds += ((sizeof(fat_dentry_t) * rde) % bps != 0);
-	ssa = rscnt + fatcnt * sf + rds;
-
-	if (firstc == FAT_CLST_ROOT) {
-		/* root directory special case */
-		assert(offset < rds);
-		b = block_get(dev_handle, rscnt + fatcnt * sf + offset, bps);
-		return b;
-	}
-
-	clusters = offset / spc; 
-	for (i = 0; i < clusters; i++) {
-		unsigned fsec;	/* sector offset relative to FAT1 */
-		unsigned fidx;	/* FAT1 entry index */
-
-		assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD);
-		fsec = (clst * sizeof(fat_cluster_t)) / bps;
-		fidx = clst % (bps / sizeof(fat_cluster_t));
-		/* read FAT1 */
-		b = block_get(dev_handle, rscnt + fsec, bps);
-		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
-		assert(clst != FAT_CLST_BAD);
-		assert(clst < FAT_CLST_LAST1);
-		block_put(b);
-	}
-
-	b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc +
-	    offset % spc, bps);
-
-	return b;
-}
-
-/** Return number of blocks allocated to a file.
- *
- * @param dev_handle	Device handle of the device with the file.
- * @param firstc	First cluster of the file.
- *
- * @return		Number of blocks allocated to the file.
- */
-static uint16_t 
-_fat_blcks_get(dev_handle_t dev_handle, fat_cluster_t firstc)
-{
-	block_t *bb;
-	block_t *b;
-	unsigned bps;
-	unsigned spc;
-	unsigned rscnt;		/* block address of the first FAT */
-	unsigned clusters = 0;
-	fat_cluster_t clst = firstc;
-
-	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
-	bps = uint16_t_le2host(FAT_BS(bb)->bps);
-	spc = FAT_BS(bb)->spc;
-	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
-	block_put(bb);
-
-	if (firstc == FAT_CLST_RES0) {
-		/* No space allocated to the file. */
-		return 0;
-	}
-
-	while (clst < FAT_CLST_LAST1) {
-		unsigned fsec;	/* sector offset relative to FAT1 */
-		unsigned fidx;	/* FAT1 entry index */
-
-		assert(clst >= FAT_CLST_FIRST);
-		fsec = (clst * sizeof(fat_cluster_t)) / bps;
-		fidx = clst % (bps / sizeof(fat_cluster_t));
-		/* read FAT1 */
-		b = block_get(dev_handle, rscnt + fsec, bps);
-		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
-		assert(clst != FAT_CLST_BAD);
-		block_put(b);
-		clusters++;
-	}
-
-	return clusters * spc;
 }
 
@@ -250,17 +113,4 @@
 	node->refcnt = 0;
 	node->dirty = false;
-}
-
-static uint16_t fat_bps_get(dev_handle_t dev_handle)
-{
-	block_t *bb;
-	uint16_t bps;
-	
-	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
-	assert(bb != NULL);
-	bps = uint16_t_le2host(FAT_BS(bb)->bps);
-	block_put(bb);
-
-	return bps;
 }
 
@@ -787,136 +637,4 @@
 }
 
-/** Fill the gap between EOF and a new file position.
- *
- * @param nodep		FAT node with the gap.
- * @param mcl		First cluster in an independent cluster chain that will
- *			be later appended to the end of the node's own cluster
- *			chain. If pos is still in the last allocated cluster,
- *			this argument is ignored.
- * @param pos		Position in the last node block.
- */
-static void
-fat_fill_gap(fat_node_t *nodep, fat_cluster_t mcl, off_t pos)
-{
-	uint16_t bps;
-	unsigned spc;
-	block_t *bb, *b;
-	off_t o, boundary;
-
-	bb = block_get(nodep->idx->dev_handle, BS_BLOCK, BS_SIZE);
-	bps = uint16_t_le2host(FAT_BS(bb)->bps);
-	spc = FAT_BS(bb)->spc;
-	block_put(bb);
-	
-	boundary = ROUND_UP(nodep->size, bps * spc);
-
-	/* zero out already allocated space */
-	for (o = nodep->size - 1; o < pos && o < boundary;
-	    o = ALIGN_DOWN(o + bps, bps)) {
-		b = fat_block_get(nodep, o / bps);
-		memset(b->data + o % bps, 0, bps - o % bps);
-		b->dirty = true;		/* need to sync node */
-		block_put(b);
-	}
-	
-	if (o >= pos)
-		return;
-	
-	/* zero out the initial part of the new cluster chain */
-	for (o = boundary; o < pos; o += bps) {
-		b = _fat_block_get(nodep->idx->dev_handle, mcl,
-		    (o - boundary) / bps);
-		memset(b->data, 0, min(bps, pos - o));
-		b->dirty = true;		/* need to sync node */
-		block_put(b);
-	}
-}
-
-static void
-fat_mark_cluster(dev_handle_t dev_handle, unsigned fatno, fat_cluster_t clst,
-    fat_cluster_t value)
-{
-	/* TODO */
-}
-
-static void
-fat_alloc_shadow_clusters(dev_handle_t dev_handle, fat_cluster_t *lifo,
-    unsigned nclsts)
-{
-	/* TODO */
-}
-
-static int
-fat_alloc_clusters(dev_handle_t dev_handle, unsigned nclsts, fat_cluster_t *mcl,
-    fat_cluster_t *lcl)
-{
-	uint16_t bps;
-	uint16_t rscnt;
-	uint16_t sf;
-	block_t *bb, *blk;
-	fat_cluster_t *lifo;	/* stack for storing free cluster numbers */ 
-	unsigned found = 0;	/* top of the free cluster number stack */
-	unsigned b, c, cl; 
-
-	lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
-	if (lifo)
-		return ENOMEM;
-	
-	bb = block_get(dev_handle, BS_BLOCK, BS_SIZE);
-	bps = uint16_t_le2host(FAT_BS(bb)->bps);
-	rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt);
-	sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat);
-	block_put(bb);
-	
-	/*
-	 * Search FAT1 for unused clusters.
-	 */
-	for (b = 0, cl = 0; b < sf; blk++) {
-		blk = block_get(dev_handle, rscnt + b, bps);
-		for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) {
-			fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
-			if (*clst == FAT_CLST_RES0) {
-				/*
-				 * The cluster is free. Put it into our stack
-				 * of found clusters and mark it as non-free.
-				 */
-				lifo[found] = cl;
-				if (found == 0)
-					*clst = FAT_CLST_LAST1;
-				else
-					*clst = lifo[found - 1];
-				blk->dirty = true;	/* need to sync block */
-				if (++found == nclsts) {
-					/* we are almost done */
-					block_put(blk);
-					/* update the shadow copies of FAT */
-					fat_alloc_shadow_clusters(dev_handle,
-					    lifo, nclsts);
-					*mcl = lifo[found - 1];
-					*lcl = lifo[0];
-					free(lifo);
-					return EOK;
-				}
-			}
-		}
-		block_put(blk);
-	}
-
-	/*
-	 * We could not find enough clusters. Now we need to free the clusters
-	 * we have allocated so far.
-	 */
-	while (found--)
-		fat_mark_cluster(dev_handle, FAT1, lifo[found], FAT_CLST_RES0);
-	
-	free(lifo);
-	return ENOSPC;
-}
-
-static void
-fat_append_clusters(fat_node_t *nodep, fat_cluster_t mcl)
-{
-}
-
 void fat_write(ipc_callid_t rid, ipc_call_t *request)
 {
