Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ boot/Makefile.common	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -102,5 +102,4 @@
 	$(USPACE_PATH)/srv/fs/tmpfs/tmpfs \
 	$(USPACE_PATH)/srv/fs/fat/fat \
-	$(USPACE_PATH)/srv/fs/exfat/exfat \
 	$(USPACE_PATH)/srv/fs/ext2fs/ext2fs \
 	$(USPACE_PATH)/srv/taskmon/taskmon \
@@ -149,6 +148,4 @@
 	$(USPACE_PATH)/app/dload/dload \
 	$(USPACE_PATH)/app/edit/edit \
-	$(USPACE_PATH)/app/filecrc/filecrc \
-	$(USPACE_PATH)/app/filegen/filegen \
 	$(USPACE_PATH)/app/ext2info/ext2info \
 	$(USPACE_PATH)/app/kill/kill \
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/Makefile	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -39,6 +39,4 @@
 	app/devctl \
 	app/edit \
-	app/filecrc \
-	app/filegen \
 	app/ext2info \
 	app/getterm \
@@ -81,5 +79,4 @@
 	srv/bd/part/guid_part \
 	srv/bd/part/mbr_part \
-	srv/fs/exfat \
 	srv/fs/fat \
 	srv/fs/tmpfs \
Index: pace/app/filecrc/Makefile
===================================================================
--- uspace/app/filecrc/Makefile	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#
-# Copyright (c) 2010 Jiri Svoboda
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
-BINARY = filecrc
-
-SOURCES = \
-	filecrc.c \
-	crc32.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/filecrc/crc32.c
===================================================================
--- uspace/app/filecrc/crc32.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,117 +1,0 @@
-/*
- * Copyright (C) 2000 Bryan Call <bc@fodder.org>
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
- */
-
-#include <unistd.h>
-#include <errno.h>
-
-#include "crc32.h"
-
-#define BUFFERSIZE 16384	/* (16k) buffer size for reading from the file */
-
-static const uint32_t crctable[256] = {
-    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-
-int crc32(int fd, uint32_t * main_val)
-{
-    char buf[BUFFERSIZE];
-    char *p;
-    int nr;
-    uint32_t crc = ~0;
-
-    while (1) {
-		if ((nr = read(fd, buf, sizeof(buf))) < 0)
-			break;
-
-		if (nr == 0)
-			break;
-		for (p = buf; nr--; ++p)
-			crc = (crc >> 8) ^ crctable[(crc ^ *p) & 0xff];
-    }
-    if (nr < 0)
-	return 1;
-
-    *main_val = ~crc;
-    return 0;
-}
Index: pace/app/filecrc/crc32.h
===================================================================
--- uspace/app/filecrc/crc32.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,31 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <unistd.h>
-
-int crc32(int fd, uint32_t * main_val);
Index: pace/app/filecrc/filecrc.c
===================================================================
--- uspace/app/filecrc/filecrc.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,91 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup filecheck
- * @{
- */
-
-/**
- * @file	filecrc.c
- * @brief	Tool for calculating CRC32 checksum for a file(s)
- *
- */
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include "crc32.h"
-
-#define NAME	"filecrc"
-#define VERSION "0.0.2"
-
-static void print_help(void);
-
-
-int main(int argc, char **argv) {
-
-	if (argc < 2) {
-		print_help();
-		return 0;
-	}
-	
-	int i;
-	for (i = 1; argv[i] != NULL && i < argc; i++) {
-		uint32_t hash = 0;		
-		int fd = open(argv[i], O_RDONLY);
-		if (fd < 0) {
-			printf("Unable to open %s\n", argv[i]);
-			continue;
-		}
-		
-		if (crc32(fd, &hash) == 0) {
-			printf("%s : %x\n", argv[i], hash);
-		}
-		
-		close(fd);
-	}
-
-	return 0;
-}
-
-
-/* Displays help for filecrc */
-static void print_help(void)
-{
-	printf(
-	   "Usage:  %s <file1> [file2] [...]\n",
-	   NAME);
-}
-
-
-/**
- * @}
- */
Index: pace/app/filegen/Makefile
===================================================================
--- uspace/app/filegen/Makefile	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#
-# Copyright (c) 2010 Jiri Svoboda
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
-BINARY = filegen
-
-SOURCES = \
-	filegen.c \
-	crc32.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/app/filegen/crc32.c
===================================================================
--- uspace/app/filegen/crc32.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,100 +1,0 @@
-/*
- * Copyright (C) 2000 Bryan Call <bc@fodder.org>
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
- */
-
-#include <unistd.h>
-#include <errno.h>
-
-#include "crc32.h"
-
-static const uint32_t crctable[256] = {
-    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-
-void crc32(char *buf, size_t size, uint32_t * crc)
-{
-    char *p;
-
-	for (p = buf; size--; ++p)
-		*crc = (*crc >> 8) ^ crctable[(*crc ^ *p) & 0xff];
-}
Index: pace/app/filegen/crc32.h
===================================================================
--- uspace/app/filegen/crc32.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,31 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <unistd.h>
-
-void crc32(char *buf, size_t size, uint32_t * crc);
Index: pace/app/filegen/filegen.c
===================================================================
--- uspace/app/filegen/filegen.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,119 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup filecheck
- * @{
- */
-
-/**
- * @file	filecrc.c
- * @brief	Tool for generating file with random data
- *
- */
-
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/time.h>
-#include "crc32.h"
-
-#define NAME	"filegen"
-#define VERSION "0.0.1"
-
-#define BUFFERSIZE 256
-
-
-static void print_help(void);
-
-
-int main(int argc, char **argv) {
-	int rc;
-	uint64_t size = 0;
-	
-	if (argc < 3) {
-		print_help();
-		return 0;
-	}
-	
-	int fd = open(argv[1], O_WRONLY | O_CREAT);
-	if (fd < 0) {
-		printf("Unable to open %s for writing\n", argv[1]);
-		return 1;
-	}
-	
-	rc = str_uint64(argv[2], NULL, 10, true, &size);
-	if (rc != EOK) {
-		printf("Cannot convert size to number\n");
-		return 1;
-	}
-	
-	struct timeval tv;	
-	gettimeofday(&tv, NULL);
-	srandom(tv.tv_sec + tv.tv_usec / 100000);	
-
-	uint64_t i=0, pbuf=0;
-	uint32_t crc=~0;
-	char buf[BUFFERSIZE];
-	
-	while (i<size) {
-		pbuf=0;
-		while (i<size && pbuf<BUFFERSIZE) {
-			buf[pbuf] = rand() % 255;
-			i++;
-			pbuf++;
-		}
-		if (pbuf) {
-			crc32(buf, pbuf, &crc);
-			write(fd, buf, pbuf);
-		}
-	}
-	
-	close(fd);
-	crc = ~crc;
-	printf("%s : %x\n", argv[1], crc);
-
-	return 0;
-}
-
-
-/* Displays help for filegen */
-static void print_help(void)
-{
-	printf(
-	   "Usage:  %s <file> <size in bytes>\n",
-	   NAME);
-}
-
-
-/**
- * @}
- */
Index: uspace/app/mkfat/fat.h
===================================================================
--- uspace/app/mkfat/fat.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/app/mkfat/fat.h	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -38,14 +38,6 @@
 #define BS_BLOCK		0
 #define BS_SIZE			512
+
 #define DIRENT_SIZE		32
-
-#define FAT12_CLST_MAX    4085
-#define FAT16_CLST_MAX    65525
-
-#define FAT12	12
-#define FAT16	16
-#define FAT32	32
-
-#define FAT_SIZE(a) ((a==FAT12)? 1.5 : ( (a==FAT16)? 2 : 4  ) ) 
 
 typedef struct fat_bs {
Index: uspace/app/mkfat/mkfat.c
===================================================================
--- uspace/app/mkfat/mkfat.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/app/mkfat/mkfat.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -35,5 +35,5 @@
  * @brief	Tool for creating new FAT file systems.
  *
- * Currently we can create 12/16/32-bit FAT.
+ * Currently we can only create 16-bit FAT.
  */
 
@@ -55,37 +55,40 @@
 #define div_round_up(a, b) (((a) + (b) - 1) / (b))
 
-/** Default file-system parameters */
+/** Predefined file-system parameters */
 enum {
-	default_sector_size		= 512,
-	default_sectors_per_cluster	= 4,
-	default_fat_count		= 2,
-	default_reserved_clusters	= 2,
-	default_media_descriptor	= 0xF8 /**< fixed disk */
+	sector_size		= 512,
+	sectors_per_cluster	= 8,
+	fat_count		= 2,
+	reserved_clusters	= 2,
+	media_descriptor	= 0xF8 /**< fixed disk */
 };
 
 /** Configurable file-system parameters */
 typedef struct fat_cfg {
-	int fat_type; /* FAT12 = 12, FAT16 = 16, FAT32 = 32 */
-	size_t sector_size;
 	uint32_t total_sectors;
 	uint16_t root_ent_max;
-	uint32_t addt_res_sectors;
-	uint8_t sectors_per_cluster;
-
+	uint16_t addt_res_sectors;
+} fat_cfg_t;
+
+/** Derived file-system parameters */
+typedef struct fat_params {
+	struct fat_cfg cfg;
 	uint16_t reserved_sectors;
-	uint32_t rootdir_sectors;
+	uint16_t rootdir_sectors;
 	uint32_t fat_sectors;
-	uint32_t total_clusters;
-	uint8_t fat_count;
-} fat_cfg_t;
+	uint16_t total_clusters;
+} fat_params_t;
 
 static void syntax_print(void);
 
-static int fat_params_compute(struct fat_cfg *cfg);
-static int fat_blocks_write(struct fat_cfg const *cfg, service_id_t service_id);
-static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs);
+static int fat_params_compute(struct fat_cfg const *cfg,
+    struct fat_params *par);
+static int fat_blocks_write(struct fat_params const *par,
+    service_id_t service_id);
+static void fat_bootsec_create(struct fat_params const *par, struct fat_bs *bs);
 
 int main(int argc, char **argv)
 {
+	struct fat_params par;
 	struct fat_cfg cfg;
 
@@ -93,14 +96,11 @@
 	char *dev_path;
 	service_id_t service_id;
+	size_t block_size;
 	char *endptr;
 	aoff64_t dev_nblocks;
 
-	cfg.sector_size = default_sector_size;
-	cfg.sectors_per_cluster = default_sectors_per_cluster;
-	cfg.fat_count = default_fat_count;
 	cfg.total_sectors = 0;
 	cfg.addt_res_sectors = 0;
 	cfg.root_ent_max = 128;
-	cfg.fat_type = FAT16;
 
 	if (argc < 2) {
@@ -111,4 +111,5 @@
 
 	--argc; ++argv;
+
 	if (str_cmp(*argv, "--size") == 0) {
 		--argc; ++argv;
@@ -129,22 +130,4 @@
 	}
 
-	if (str_cmp(*argv, "--type") == 0) {
-		--argc; ++argv;
-		if (*argv == NULL) {
-			printf(NAME ": Error, argument missing.\n");
-			syntax_print();
-			return 1;
-		}
-
-		cfg.fat_type = strtol(*argv, &endptr, 10);
-		if (*endptr != '\0') {
-			printf(NAME ": Error, invalid argument.\n");
-			syntax_print();
-			return 1;
-		}
-
-		--argc; ++argv;
-	}
-
 	if (argc != 1) {
 		printf(NAME ": Error, unexpected argument.\n");
@@ -154,5 +137,4 @@
 
 	dev_path = *argv;
-	printf("Device: %s\n", dev_path);
 
 	rc = loc_service_get_id(dev_path, &service_id, 0);
@@ -168,5 +150,5 @@
 	}
 
-	rc = block_get_bsize(service_id, &cfg.sector_size);
+	rc = block_get_bsize(service_id, &block_size);
 	if (rc != EOK) {
 		printf(NAME ": Error determining device block size.\n");
@@ -183,6 +165,6 @@
 	}
 
-	if (cfg.fat_type == FAT12 && cfg.sector_size != 512) {
-		printf(NAME ": Error. Device block size is not 512 bytes for FAT12 file system.\n");
+	if (block_size != 512) {
+		printf(NAME ": Error. Device block size is not 512 bytes.\n");
 		return 2;
 	}
@@ -193,7 +175,7 @@
 	}
 
-	printf(NAME ": Creating FAT%d filesystem on device %s.\n", cfg.fat_type, dev_path);
-
-	rc = fat_params_compute(&cfg);
+	printf(NAME ": Creating FAT filesystem on device %s.\n", dev_path);
+
+	rc = fat_params_compute(&cfg, &par);
 	if (rc != EOK) {
 		printf(NAME ": Invalid file-system parameters.\n");
@@ -201,5 +183,5 @@
 	}
 
-	rc = fat_blocks_write(&cfg, service_id);
+	rc = fat_blocks_write(&par, service_id);
 	if (rc != EOK) {
 		printf(NAME ": Error writing device.\n");
@@ -215,5 +197,5 @@
 static void syntax_print(void)
 {
-	printf("syntax: mkfat32 [--size <sectors>] [--type 12|16|32] <device_name>\n");
+	printf("syntax: mkfat [--size <num_blocks>] <device_name>\n");
 }
 
@@ -223,5 +205,5 @@
  * file system params.
  */
-static int fat_params_compute(struct fat_cfg *cfg)
+static int fat_params_compute(struct fat_cfg const *cfg, struct fat_params *par)
 {
 	uint32_t fat_bytes;
@@ -229,33 +211,22 @@
 
 	/*
-     * Make a conservative guess on the FAT size needed for the file
-     * system. The optimum could be potentially smaller since we
-     * do not subtract size of the FAT itself when computing the
-     * size of the data region.
-     */
-
-	if (cfg->fat_type == FAT12)
-		cfg->sectors_per_cluster = 1;
-
-	cfg->reserved_sectors = 1 + cfg->addt_res_sectors;
-	if (cfg->fat_type != FAT32) {
-		cfg->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
-			cfg->sector_size);
-	}
-	else
-		cfg->rootdir_sectors = 0;
-	non_data_sectors_lb = cfg->reserved_sectors + cfg->rootdir_sectors;
-
-	cfg->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
-	    cfg->sectors_per_cluster);
-
-	if ((cfg->fat_type == FAT12 && cfg->total_clusters > FAT12_CLST_MAX) ||
-		(cfg->fat_type == FAT16 && (cfg->total_clusters <= FAT12_CLST_MAX ||
-		cfg->total_clusters > FAT16_CLST_MAX)) ||
-	    (cfg->fat_type == FAT32 && cfg->total_clusters <= FAT16_CLST_MAX))
-		return ENOSPC;
-
-	fat_bytes = (cfg->total_clusters + 2) * FAT_SIZE(cfg->fat_type);
-	cfg->fat_sectors = div_round_up(fat_bytes, cfg->sector_size);
+         * Make a conservative guess on the FAT size needed for the file
+         * system. The optimum could be potentially smaller since we
+         * do not subtract size of the FAT itself when computing the
+         * size of the data region.
+         */
+
+	par->reserved_sectors = 1 + cfg->addt_res_sectors;
+	par->rootdir_sectors = div_round_up(cfg->root_ent_max * DIRENT_SIZE,
+	    sector_size);
+	non_data_sectors_lb = par->reserved_sectors + par->rootdir_sectors;
+
+	par->total_clusters = div_round_up(cfg->total_sectors - non_data_sectors_lb,
+	    sectors_per_cluster);
+
+	fat_bytes = (par->total_clusters + 2) * 2;
+	par->fat_sectors = div_round_up(fat_bytes, sector_size);
+
+	par->cfg = *cfg;
 
 	return EOK;
@@ -263,5 +234,5 @@
 
 /** Create file system with the given parameters. */
-static int fat_blocks_write(struct fat_cfg const *cfg, service_id_t service_id)
+static int fat_blocks_write(struct fat_params const *par, service_id_t service_id)
 {
 	aoff64_t addr;
@@ -272,5 +243,5 @@
 	struct fat_bs bs;
 
-	fat_bootsec_create(cfg, &bs);
+	fat_bootsec_create(par, &bs);
 
 	rc = block_write_direct(service_id, BS_BLOCK, 1, &bs);
@@ -280,11 +251,10 @@
 	addr = BS_BLOCK + 1;
 
-	buffer = calloc(cfg->sector_size, 1);
+	buffer = calloc(sector_size, 1);
 	if (buffer == NULL)
 		return ENOMEM;
-	memset(buffer, 0, cfg->sector_size);
 
 	/* Reserved sectors */
-	for (i = 0; i < cfg->reserved_sectors - 1; ++i) {
+	for (i = 0; i < par->reserved_sectors - 1; ++i) {
 		rc = block_write_direct(service_id, addr, 1, buffer);
 		if (rc != EOK)
@@ -295,26 +265,14 @@
 
 	/* File allocation tables */
-	for (i = 0; i < cfg->fat_count; ++i) {
+	for (i = 0; i < fat_count; ++i) {
 		printf("Writing allocation table %d.\n", i + 1);
 
-		for (j = 0; j < cfg->fat_sectors; ++j) {
-			memset(buffer, 0, cfg->sector_size);
+		for (j = 0; j < par->fat_sectors; ++j) {
+			memset(buffer, 0, sector_size);
 			if (j == 0) {
-				buffer[0] = default_media_descriptor;
+				buffer[0] = media_descriptor;
 				buffer[1] = 0xFF;
 				buffer[2] = 0xFF;
-				if (cfg->fat_type == FAT16) {
-					buffer[3] = 0xFF;
-				} else if (cfg->fat_type == FAT32) {
-					buffer[3] = 0x0F;
-					buffer[4] = 0xFF;
-					buffer[5] = 0xFF;
-					buffer[6] = 0xFF;
-					buffer[7] = 0x0F;
-					buffer[8] = 0xF8;
-					buffer[9] = 0xFF;
-					buffer[10] = 0xFF;
-					buffer[11] = 0x0F;
-				}
+				buffer[3] = 0xFF;
 			}
 
@@ -327,24 +285,15 @@
 	}
 
+	printf("Writing root directory.\n");
+
+	memset(buffer, 0, sector_size);
+
 	/* Root directory */
-	printf("Writing root directory.\n");
-	memset(buffer, 0, cfg->sector_size);
-	if (cfg->fat_type != FAT32) {
-		size_t idx;
-		for (idx = 0; idx < cfg->rootdir_sectors; ++idx) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
-		}
-	} else {
-		for (i=0; i<cfg->sectors_per_cluster; i++) {
-			rc = block_write_direct(service_id, addr, 1, buffer);
-			if (rc != EOK)
-				return EIO;
-
-			++addr;
-		}	
+	for (i = 0; i < par->rootdir_sectors; ++i) {
+		rc = block_write_direct(service_id, addr, 1, buffer);
+		if (rc != EOK)
+			return EIO;
+
+		++addr;
 	}
 
@@ -355,5 +304,5 @@
 
 /** Construct boot sector with the given parameters. */
-static void fat_bootsec_create(struct fat_cfg const *cfg, struct fat_bs *bs)
+static void fat_bootsec_create(struct fat_params const *par, struct fat_bs *bs)
 {
 	memset(bs, 0, sizeof(*bs));
@@ -366,44 +315,34 @@
 
 	/* BIOS Parameter Block */
-	bs->bps = host2uint16_t_le(cfg->sector_size);
-	bs->spc = cfg->sectors_per_cluster;
-	bs->rscnt = host2uint16_t_le(cfg->reserved_sectors);
-	bs->fatcnt = cfg->fat_count;
-	bs->root_ent_max = host2uint16_t_le(cfg->root_ent_max);
-
-	if (cfg->total_sectors < 0x10000) {
-		bs->totsec16 = host2uint16_t_le(cfg->total_sectors);
-		bs->totsec32 = 0;
-	} else {
-		bs->totsec16 = 0;
-		bs->totsec32 = host2uint32_t_le(cfg->total_sectors);
-	}
-
-	bs->mdesc = default_media_descriptor;
+	bs->bps = host2uint16_t_le(sector_size);
+	bs->spc = sectors_per_cluster;
+	bs->rscnt = host2uint16_t_le(par->reserved_sectors);
+	bs->fatcnt = fat_count;
+	bs->root_ent_max = host2uint16_t_le(par->cfg.root_ent_max);
+
+	if (par->cfg.total_sectors < 0x10000)
+		bs->totsec16 = host2uint16_t_le(par->cfg.total_sectors);
+	else
+		bs->totsec16 = host2uint16_t_le(0);
+
+	bs->mdesc = media_descriptor;
+	bs->sec_per_fat = host2uint16_t_le(par->fat_sectors);
 	bs->sec_per_track = host2uint16_t_le(63);
-	bs->signature = host2uint16_t_be(0x55AA);
 	bs->headcnt = host2uint16_t_le(6);
 	bs->hidden_sec = host2uint32_t_le(0);
 
-	if (cfg->fat_type == FAT32) {
-		bs->sec_per_fat = 0;
-		bs->fat32.sectors_per_fat = host2uint32_t_le(cfg->fat_sectors);
-
-		bs->fat32.pdn = 0x80;
-		bs->fat32.ebs = 0x29;
-		bs->fat32.id = host2uint32_t_be(0x12345678);
-		bs->fat32.root_cluster = 2;
-
-		memcpy(bs->fat32.label, "HELENOS_NEW", 11);
-		memcpy(bs->fat32.type, "FAT32   ", 8);
-	} else {
-		bs->sec_per_fat = host2uint16_t_le(cfg->fat_sectors);
-		bs->pdn = 0x80;
-		bs->ebs = 0x29;
-		bs->id = host2uint32_t_be(0x12345678);
-
-		memcpy(bs->label, "HELENOS_NEW", 11);
-		memcpy(bs->type, "FAT   ", 8);
-	}
+	if (par->cfg.total_sectors >= 0x10000)
+		bs->totsec32 = host2uint32_t_le(par->cfg.total_sectors);
+	else
+		bs->totsec32 = host2uint32_t_le(0);
+
+	/* Extended BPB */
+	bs->pdn = 0x80;
+	bs->ebs = 0x29;
+	bs->id = host2uint32_t_be(0x12345678);
+
+	memcpy(bs->label, "HELENOS_NEW", 11);
+	memcpy(bs->type, "FAT16   ", 8);
+	bs->signature = host2uint16_t_be(0x55AA);
 }
 
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/lib/c/generic/str.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -3,5 +3,4 @@
  * Copyright (c) 2008 Jiri Svoboda
  * Copyright (c) 2011 Martin Sucha
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -368,16 +367,4 @@
 }
 
-/** Check whether wide string is plain ASCII.
- *
- * @return True if wide string is plain ASCII.
- *
- */
-bool wstr_is_ascii(const wchar_t *wstr)
-{
-	while (*wstr && ascii_check(*wstr))
-		wstr++;
-	return *wstr == 0;
-}
-
 /** Check whether character is valid
  *
@@ -632,10 +619,7 @@
  * @param size	Size of the destination buffer.
  * @param src	Source wide string.
- *
- * @return EOK, if success, negative otherwise.
- */
-int wstr_to_str(char *dest, size_t size, const wchar_t *src)
-{
-	int rc;
+ */
+void wstr_to_str(char *dest, size_t size, const wchar_t *src)
+{
 	wchar_t ch;
 	size_t src_idx;
@@ -649,90 +633,10 @@
 
 	while ((ch = src[src_idx++]) != 0) {
-		rc = chr_encode(ch, dest, &dest_off, size - 1);
-		if (rc != EOK)
+		if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
 			break;
 	}
 
 	dest[dest_off] = '\0';
-	return rc;
-}
-
-/** Convert UTF16 string to string.
- *
- * Convert utf16 string @a src to string. The output is written to the buffer
- * specified by @a dest and @a size. @a size must be non-zero and the string
- * written will always be well-formed. Surrogate pairs also supported.
- *
- * @param dest	Destination buffer.
- * @param size	Size of the destination buffer.
- * @param src	Source utf16 string.
- *
- * @return EOK, if success, negative otherwise.
- */
-int utf16_to_str(char *dest, size_t size, const uint16_t *src)
-{
-	size_t idx=0, dest_off=0;
-	wchar_t ch;
-	int rc = EOK;
-
-	/* There must be space for a null terminator in the buffer. */
-	assert(size > 0);
-
-	while (src[idx]) {
-		if ((src[idx] & 0xfc00) == 0xd800) {
-			if (src[idx+1] && (src[idx+1] & 0xfc00) == 0xdc00) {
-				ch = 0x10000;
-				ch += (src[idx] & 0x03FF) << 10;
-				ch += (src[idx+1] & 0x03FF);
-				idx += 2;
-			}
-			else
-				break;
-		} else {
-			ch = src[idx];
-			idx++;
-		}
-		rc = chr_encode(ch, dest, &dest_off, size-1);
-		if (rc != EOK)
-			break;
-	}
-	dest[dest_off] = '\0';
-	return rc;
-}
-
-int str_to_utf16(uint16_t *dest, size_t size, const char *src)
-{
-	int rc=EOK;
-	size_t offset=0;
-	size_t idx=0;
-	wchar_t c;
-
-	assert(size > 0);
-	
-	while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) {
-		if (c > 0x10000) {
-			if (idx+2 >= size-1) {
-				rc=EOVERFLOW;
-				break;
-			}
-			c = (c - 0x10000);
-			dest[idx] = 0xD800 | (c >> 10);
-			dest[idx+1] = 0xDC00 | (c & 0x3FF);
-			idx++;
-		} else {
-			 dest[idx] = c;
-		}
-
-		idx++;
-		if (idx >= size-1) {
-			rc=EOVERFLOW;
-			break;
-		}
-	}
-
-	dest[idx] = '\0';
-	return rc;
-}
-
+}
 
 /** Convert wide string to new string.
@@ -794,10 +698,7 @@
  * @param dlen	Length of destination buffer (number of wchars).
  * @param src	Source string.
- *
- * @return EOK, if success, negative otherwise.
- */
-int str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
-{
-	int rc=EOK;
+ */
+void str_to_wstr(wchar_t *dest, size_t dlen, const char *src)
+{
 	size_t offset;
 	size_t di;
@@ -810,8 +711,6 @@
 
 	do {
-		if (di >= dlen - 1) {
-			rc = EOVERFLOW;
+		if (di >= dlen - 1)
 			break;
-		}
 
 		c = str_decode(src, &offset, STR_NO_LIMIT);
@@ -820,5 +719,4 @@
 
 	dest[dlen - 1] = '\0';
-	return rc;
 }
 
@@ -885,39 +783,4 @@
 	
 	return (char *) res;
-}
-
-/** Find first occurence of character in wide string.
- *
- * @param wstr String to search.
- * @param ch  Character to look for.
- *
- * @return Pointer to character in @a wstr or NULL if not found.
- */
-wchar_t *wstr_chr(const wchar_t *wstr, wchar_t ch)
-{
-	while (*wstr && *wstr != ch)
-		wstr++;
-	if (*wstr)
-		return (wchar_t *) wstr;
-	else
-		return NULL;
-}
-
-/** Find last occurence of character in wide string.
- *
- * @param wstr String to search.
- * @param ch  Character to look for.
- *
- * @return Pointer to character in @a wstr or NULL if not found.
- */
-wchar_t *wstr_rchr(const wchar_t *wstr, wchar_t ch)
-{
-	const wchar_t *res = NULL;
-	while (*wstr) {
-		if (*wstr == ch)
-			res = wstr;
-		wstr++;
-	}
-	return (wchar_t *) res;
 }
 
@@ -1174,34 +1037,4 @@
 }
 
-void str_reverse(char* begin, char* end) 
-{
-    char aux;
-    while(end>begin)
-        aux=*end, *end--=*begin, *begin++=aux;
-}
-
-int size_t_str(size_t value, int base, char* str, size_t size) 
-{
-    static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-    char* wstr=str;
-	
-	if (size == 0) 
-		return EINVAL;
-    if (base<2 || base>35) {
-        *str='\0';
-        return EINVAL;
-    }
-
-    do {
-        *wstr++ = num[value % base];
-		if (--size == 0)
-			return EOVERFLOW;
-    } while(value /= base);
-    *wstr='\0';
-
-    // Reverse string
-    str_reverse(str,wstr-1);
-	return EOK;
-}
 
 /** Convert initial part of string to unsigned long according to given base.
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/lib/c/include/str.h	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2005 Martin Decky
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -72,5 +71,4 @@
 extern bool ascii_check(wchar_t ch);
 extern bool chr_check(wchar_t ch);
-extern bool wstr_is_ascii(const wchar_t *wstr);
 
 extern int str_cmp(const char *s1, const char *s2);
@@ -81,16 +79,12 @@
 extern void str_append(char *dest, size_t size, const char *src);
 
-extern int wstr_to_str(char *dest, size_t size, const wchar_t *src);
 extern int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n);
+extern void wstr_to_str(char *dest, size_t size, const wchar_t *src);
 extern char *wstr_to_astr(const wchar_t *src);
+extern void str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
 extern wchar_t *str_to_awstr(const char *src);
-extern int str_to_wstr(wchar_t *dest, size_t dlen, const char *src);
-extern int utf16_to_str(char *dest, size_t size, const uint16_t *src);
-extern int str_to_utf16(uint16_t *dest, size_t size, const char *src);
 
 extern char *str_chr(const char *str, wchar_t ch);
 extern char *str_rchr(const char *str, wchar_t ch);
-extern wchar_t *wstr_chr(const wchar_t *wstr, wchar_t ch);
-extern wchar_t *wstr_rchr(const wchar_t *wstr, wchar_t ch);
 
 extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
@@ -99,7 +93,4 @@
 extern char *str_dup(const char *);
 extern char *str_ndup(const char *, size_t max_size);
-
-extern void str_reverse(char* begin, char* end);
-extern int size_t_str(size_t value, int base, char* str, size_t size);
 
 extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *);
Index: pace/srv/fs/exfat/Makefile
===================================================================
--- uspace/srv/fs/exfat/Makefile	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,44 +1,0 @@
-#
-# Copyright (c) 2005 Martin Decky
-# Copyright (c) 2007 Jakub Jermar
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# - Redistributions of source code must retain the above copyright
-#   notice, this list of conditions and the following disclaimer.
-# - Redistributions in binary form must reproduce the above copyright
-#   notice, this list of conditions and the following disclaimer in the
-#   documentation and/or other materials provided with the distribution.
-# - The name of the author may not be used to endorse or promote products
-#   derived from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-USPACE_PREFIX = ../../..
-LIBS = $(LIBBLOCK_PREFIX)/libblock.a $(LIBFS_PREFIX)/libfs.a
-EXTRA_CFLAGS += -I$(LIBBLOCK_PREFIX) -I$(LIBFS_PREFIX)
-BINARY = exfat
-
-SOURCES = \
-	exfat.c \
-	exfat_fat.c \
-	exfat_bitmap.c \
-	exfat_ops.c \
-	exfat_idx.c \
-	exfat_dentry.c \
-	exfat_directory.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: pace/srv/fs/exfat/exfat.c
===================================================================
--- uspace/srv/fs/exfat/exfat.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,95 +1,0 @@
-/*
- * Copyright (c) 2006 Martin Decky
- * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-/**
- * @file	exfat.c
- * @brief	FAT file system driver for HelenOS.
- */
-
-#include "exfat.h"
-#include <ipc/services.h>
-#include <ns.h>
-#include <async.h>
-#include <errno.h>
-#include <unistd.h>
-#include <task.h>
-#include <stdio.h>
-#include <libfs.h>
-#include "../../vfs/vfs.h"
-
-#define NAME	"exfat"
-
-vfs_info_t exfat_vfs_info = {
-	.name = NAME,
-	.concurrent_read_write = false,
-	.write_retains_size = false,	
-};
-
-int main(int argc, char **argv)
-{
-	printf(NAME ": HelenOS exFAT file system server\n");
-
-	int rc = exfat_idx_init();
-	if (rc != EOK)
-		goto err;
-
-	async_sess_t *vfs_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
-	    SERVICE_VFS, 0, 0);
-	if (!vfs_sess) {
-		printf(NAME ": failed to connect to VFS\n");
-		return -1;
-	}
-	
-	rc = fs_register(vfs_sess, &exfat_vfs_info, &exfat_ops, &exfat_libfs_ops);
-	if (rc != EOK) {
-		exfat_idx_fini();
-		goto err;
-	}
-	
-	printf(NAME ": Accepting connections\n");
-	task_retval(0);
-	async_manager();
-
-	/* not reached */
-	return 0;
-
-err:
-	printf(NAME ": Failed to register file system (%d)\n", rc);
-	return rc;
-}
-
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat.h
===================================================================
--- uspace/srv/fs/exfat/exfat.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,194 +1,0 @@
-/*
- * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-#ifndef EXFAT_EXFAT_H_
-#define EXFAT_EXFAT_H_
-
-#include "exfat_fat.h"
-#include <fibril_synch.h>
-#include <libfs.h>
-#include <atomic.h>
-#include <sys/types.h>
-#include <bool.h>
-#include "../../vfs/vfs.h"
-
-#ifndef dprintf
-#define dprintf(...)	printf(__VA_ARGS__)
-#endif
-
-#define BS_BLOCK		0
-#define BS_SIZE			512
-
-#define BPS(bs)			((uint32_t) (1 << (bs->bytes_per_sector)))
-#define SPC(bs)			((uint32_t)(1 << (bs->sec_per_cluster)))
-#define BPC(bs)			((uint32_t)(BPS(bs)*SPC(bs)))
-#define VOL_FS(bs)		uint64_t_le2host(bs->volume_start)
-#define VOL_CNT(bs)		uint64_t_le2host(bs->volume_count)
-#define FAT_FS(bs)		uint32_t_le2host(bs->fat_sector_start)
-#define FAT_CNT(bs)		uint32_t_le2host(bs->fat_sector_count)
-#define DATA_FS(bs)		uint32_t_le2host(bs->data_start_sector)
-#define DATA_CNT(bs)	uint32_t_le2host(bs->data_clusters)
-#define ROOT_FC(bs)		uint32_t_le2host(bs->rootdir_cluster)
-#define VOL_FLAGS(bs)	uint16_t_le2host(bs->volume_flags)
-
-#define EXFAT_NODE(node)	((node) ? (exfat_node_t *) (node)->data : NULL)
-#define FS_NODE(node)	((node) ? (node)->bp : NULL)
-#define DPS(bs) (BPS((bs)) / sizeof(exfat_dentry_t))
-
-typedef struct exfat_bs {
-	uint8_t jump[3];				/* 0x00 jmp and nop instructions */
-	uint8_t oem_name[8];			/* 0x03 "EXFAT   " */
-	uint8_t	__reserved[53];			/* 0x0B always 0 */
-	uint64_t volume_start;			/* 0x40 partition first sector */
-	uint64_t volume_count;			/* 0x48 partition sectors count */
-	uint32_t fat_sector_start;		/* 0x50 FAT first sector */
-	uint32_t fat_sector_count;		/* 0x54 FAT sectors count */
-	uint32_t data_start_sector;		/* 0x58 Data region first cluster sector */
-	uint32_t data_clusters;			/* 0x5C total clusters count */
-	uint32_t rootdir_cluster;		/* 0x60 first cluster of the root dir */
-	uint32_t volume_serial;			/* 0x64 volume serial number */
-	struct {						/* 0x68 FS version */
-		uint8_t minor;
-		uint8_t major;
-	} __attribute__ ((packed)) version;
-	uint16_t volume_flags;			/* 0x6A volume state flags */
-	uint8_t bytes_per_sector;		/* 0x6C sector size as (1 << n) */
-	uint8_t sec_per_cluster;		/* 0x6D sectors per cluster as (1 << n) */
-	uint8_t fat_count;				/* 0x6E always 1 */
-	uint8_t drive_no;				/* 0x6F always 0x80 */
-	uint8_t allocated_percent;		/* 0x70 percentage of allocated space */
-	uint8_t _reserved2[7];			/* 0x71 reserved */
-	uint8_t bootcode[390];			/* Boot code */
-	uint16_t signature;				/* the value of 0xAA55 */
-} __attribute__((__packed__)) exfat_bs_t;
-
-typedef enum {
-	EXFAT_UNKNOW,
-	EXFAT_DIRECTORY,
-	EXFAT_FILE,
-	EXFAT_BITMAP,
-	EXFAT_UCTABLE
-} exfat_node_type_t;
-
-struct exfat_node;
-struct exfat_idx_t;
-
-typedef struct {
-	/** Used indices (position) hash table link. */
-	link_t		uph_link;
-	/** Used indices (index) hash table link. */
-	link_t		uih_link;
-
-	fibril_mutex_t	lock;
-	service_id_t	service_id;
-	fs_index_t	index;
-
-	/* Does parent node fragmented or not? */
-	bool parent_fragmented;
-	/**
-	 * Parent node's first cluster.
-	 * Zero is used if this node is not linked, in which case nodep must
-	 * contain a pointer to the in-core node structure.
-	 * One is used when the parent is the root directory.
-	 */
-	exfat_cluster_t	pfc;
-	/** Directory entry index within the parent node. */
-	unsigned	pdi;
-	/** Pointer to in-core node instance. */
-	struct exfat_node	*nodep;
-} exfat_idx_t;
-
-/** exFAT in-core node. */
-typedef struct exfat_node {
-	/** Back pointer to the FS node. */
-	fs_node_t		*bp;
-	
-	fibril_mutex_t		lock;
-	exfat_node_type_t	type;
-	exfat_idx_t			*idx;
-	/**
-	 *  Node's first cluster.
-	 *  Zero is used for zero-length nodes.
-	 *  One is used to mark root directory.
-	 */
-	exfat_cluster_t		firstc;
-	/** exFAT in-core node free list link. */
-	link_t			ffn_link;
-	aoff64_t		size;
-	unsigned		lnkcnt;
-	unsigned		refcnt;
-	bool			dirty;
-	/* Should we do walk-on-FAT or not */
-	bool			fragmented;
-
-	/*
-	 * Cache of the node's last and "current" cluster to avoid some
-	 * unnecessary FAT walks.
-	 */
-	/* Node's last cluster in FAT. */
-	bool		lastc_cached_valid;
-	exfat_cluster_t	lastc_cached_value;
-	/* Node's "current" cluster, i.e. where the last I/O took place. */
-	bool		currc_cached_valid;
-	aoff64_t	currc_cached_bn;
-	exfat_cluster_t	currc_cached_value;
-} exfat_node_t;
-
-
-extern vfs_out_ops_t exfat_ops;
-extern libfs_ops_t exfat_libfs_ops;
-
-extern int exfat_idx_get_new(exfat_idx_t **, service_id_t);
-extern exfat_idx_t *exfat_idx_get_by_pos(service_id_t, exfat_cluster_t, unsigned);
-extern exfat_idx_t *exfat_idx_get_by_index(service_id_t, fs_index_t);
-extern void exfat_idx_destroy(exfat_idx_t *);
-extern void exfat_idx_hashin(exfat_idx_t *);
-extern void exfat_idx_hashout(exfat_idx_t *);
-
-extern int exfat_idx_init(void);
-extern void exfat_idx_fini(void);
-extern int exfat_idx_init_by_service_id(service_id_t);
-extern void exfat_idx_fini_by_service_id(service_id_t);
-
-extern int exfat_node_expand(service_id_t service_id, exfat_node_t *nodep,
-    exfat_cluster_t clusters);
-extern int exfat_node_put(fs_node_t *);
-extern int exfat_bitmap_get(fs_node_t **, service_id_t);
-extern int exfat_uctable_get(fs_node_t **, service_id_t);
-
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_bitmap.c
===================================================================
--- uspace/srv/fs/exfat/exfat_bitmap.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,274 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */
-
-/**
- * @file	exfat_bitmap.c
- * @brief	Functions that manipulate the Bitmap Table.
- */
-
-#include "exfat_bitmap.h"
-#include "../../vfs/vfs.h"
-#include <libfs.h>
-#include <libblock.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <align.h>
-#include <assert.h>
-#include <fibril_synch.h>
-#include <malloc.h>
-#include <mem.h>
-
-
-int bitmap_is_free(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t clst)
-{
-	fs_node_t *fn;
-	block_t *b=NULL;
-	exfat_node_t *bitmapp;
-	uint8_t *bitmap;
-	int rc;
-	bool alloc;
-
-	clst -= EXFAT_CLST_FIRST;
-	
-	rc = exfat_bitmap_get(&fn, service_id);
-	if (rc != EOK)
-		return rc;
-	bitmapp = EXFAT_NODE(fn);
-	
-	aoff64_t offset = clst / 8;
-	rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	bitmap = (uint8_t *)b->data;
-	alloc = bitmap[offset % BPS(bs)] & (1 << (clst % 8));
-
-	rc = block_put(b);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	rc = exfat_node_put(fn);
-	if (rc != EOK)
-		return rc;
-
-	if (alloc)
-		return ENOENT;
-
-	return EOK;
-}
-
-int bitmap_set_cluster(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t clst)
-{
-	fs_node_t *fn;
-	block_t *b=NULL;
-	exfat_node_t *bitmapp;
-	uint8_t *bitmap;
-	int rc;
-
-	clst -= EXFAT_CLST_FIRST;
-	
-	rc = exfat_bitmap_get(&fn, service_id);
-	if (rc != EOK)
-		return rc;
-	bitmapp = EXFAT_NODE(fn);
-	
-	aoff64_t offset = clst / 8;
-	rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	bitmap = (uint8_t *)b->data;
-	bitmap[offset % BPS(bs)] |= (1 << (clst % 8));
-
-	b->dirty = true;
-	rc = block_put(b);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	
-	return exfat_node_put(fn);
-}
-
-int bitmap_clear_cluster(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t clst)
-{
-	fs_node_t *fn;
-	block_t *b=NULL;
-	exfat_node_t *bitmapp;
-	uint8_t *bitmap;
-	int rc;
-
-	clst -= EXFAT_CLST_FIRST;
-	
-	rc = exfat_bitmap_get(&fn, service_id);
-	if (rc != EOK)
-		return rc;
-	bitmapp = EXFAT_NODE(fn);
-	
-	aoff64_t offset = clst / 8;
-	rc = exfat_block_get(&b, bs, bitmapp, offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	bitmap = (uint8_t *)b->data;
-	bitmap[offset % BPS(bs)] &= ~(1 << (clst % 8));
-
-	b->dirty = true;
-	rc = block_put(b);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-	
-	return exfat_node_put(fn);
-}
-
-int bitmap_set_clusters(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t count)
-{
-	int rc;
-	exfat_cluster_t clst;
-	clst = firstc;
-
-	while (clst < firstc+count ) {
-		rc = bitmap_set_cluster(bs, service_id, clst);
-		if (rc != EOK) {
-			if ((clst-firstc) > 0)
-				(void) bitmap_clear_clusters(bs, service_id, firstc, clst-firstc);
-			return rc;
-		}
-		clst++;
-	}
-	return EOK;
-}
-
-int bitmap_clear_clusters(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t count)
-{
-	int rc;
-	exfat_cluster_t clst;
-	clst = firstc;
-
-	while (clst < firstc+count ) {
-		rc = bitmap_clear_cluster(bs, service_id, clst);
-		if (rc != EOK)
-			return rc;
-		clst++;
-	}
-	return EOK;
-}
-
-int bitmap_alloc_clusters(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t *firstc, exfat_cluster_t count)
-{
-	exfat_cluster_t startc, endc;
-	startc = EXFAT_CLST_FIRST;
-
-	while (startc < DATA_CNT(bs)+2) {
-		endc = startc;
-		while (bitmap_is_free(bs, service_id, endc) == EOK) {
-			if ((endc - startc)+1 == count){
-				*firstc = startc;
-				return bitmap_set_clusters(bs, service_id, startc, count);
-			}
-			else
-				endc++;
-		}
-		startc = endc+1;
-	}
-	return ENOSPC;
-}
-
-
-int bitmap_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
-    exfat_cluster_t count)
-{
-	if (nodep->firstc == 0) {
-		return bitmap_alloc_clusters(bs, nodep->idx->service_id, 
-		    &nodep->firstc, count);
-	} else {
-		exfat_cluster_t lastc, clst;
-		lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
-
-		clst = lastc+1;
-		while (bitmap_is_free(bs, nodep->idx->service_id, clst) == EOK) {
-			if ((clst - lastc) == count){
-				return bitmap_set_clusters(bs, nodep->idx->service_id, 
-				    lastc+1, count);
-			}
-			else
-				clst++;
-		}
-		return ENOSPC;
-	}
-}
-
-
-int bitmap_free_clusters(exfat_bs_t *bs, exfat_node_t *nodep, 
-    exfat_cluster_t count)
-{
-	exfat_cluster_t lastc;
-	lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
-	lastc -= count;
-
-	return bitmap_clear_clusters(bs, nodep->idx->service_id, lastc+1, count);
-}
-
-
-int bitmap_replicate_clusters(exfat_bs_t *bs, exfat_node_t *nodep)
-{
-	int rc;
-	exfat_cluster_t lastc, clst;
-	service_id_t service_id = nodep->idx->service_id;
-	lastc = nodep->firstc + ROUND_UP(nodep->size, BPC(bs)) / BPC(bs) - 1;
-
-	for (clst = nodep->firstc; clst < lastc; clst++) {
-		rc = exfat_set_cluster(bs, service_id, clst, clst+1);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return exfat_set_cluster(bs, service_id, lastc, EXFAT_CLST_EOF);
-}
-
-
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_bitmap.h
===================================================================
--- uspace/srv/fs/exfat/exfat_bitmap.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,69 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */
-
-#ifndef EXFAT_EXFAT_BITMAP_H_
-#define EXFAT_EXFAT_BITMAP_H_
-
-#include <stdint.h>
-#include "exfat.h"
-#include "exfat_fat.h"
-
-/* forward declarations */
-struct exfat_node;
-struct exfat_bs;
-
-extern int bitmap_alloc_clusters(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t *firstc, exfat_cluster_t count);
-extern int bitmap_append_clusters(struct exfat_bs *bs, struct exfat_node *nodep, 
-    exfat_cluster_t count);
-extern int bitmap_free_clusters(struct exfat_bs *bs, struct exfat_node *nodep, 
-    exfat_cluster_t count);
-extern int bitmap_replicate_clusters(struct exfat_bs *bs, struct exfat_node *nodep); 
-
-extern int bitmap_is_free(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t clst);
-extern int bitmap_set_cluster(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t clst);
-extern int bitmap_clear_cluster(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t clst);
-
-extern int bitmap_set_clusters(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t count);
-extern int bitmap_clear_clusters(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t count);
-
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_dentry.c
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,125 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-/**
- * @file	exfat_dentry.c
- * @brief	Functions that work with exFAT directory entries.
- */
-
-#include "exfat_dentry.h"
-#include <ctype.h>
-#include <str.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <assert.h>
-
-exfat_dentry_clsf_t exfat_classify_dentry(const exfat_dentry_t *d)
-{
-	switch (d->type) {
-	case EXFAT_TYPE_VOLLABEL:
-		return EXFAT_DENTRY_VOLLABEL;
-	case EXFAT_TYPE_BITMAP:
-		return EXFAT_DENTRY_BITMAP;
-	case EXFAT_TYPE_UCTABLE:
-		return EXFAT_DENTRY_UCTABLE;
-	case EXFAT_TYPE_GUID:
-		return EXFAT_DENTRY_GUID;
-	case EXFAT_TYPE_FILE:
-		return EXFAT_DENTRY_FILE;
-	case EXFAT_TYPE_STREAM:
-		return EXFAT_DENTRY_STREAM;
-	case EXFAT_TYPE_NAME:
-		return EXFAT_DENTRY_NAME;
-	case EXFAT_TYPE_UNUSED:
-		return EXFAT_DENTRY_LAST;
-	default:
-		if (d->type & EXFAT_TYPE_USED)
-			return EXFAT_DENTRY_SKIP;
-		else
-			return EXFAT_DENTRY_FREE;
-	}
-}
-
-uint16_t exfat_name_hash(const uint16_t *name, const uint16_t *uctable, size_t chars)
-{
-	uint16_t hash = 0;
-	uint16_t ch;
-	while (*name) {
-		if (*name < chars)
-			ch = uint16_t_le2host(uctable[*name]);
-		else
-			ch = *name;
-		name++;
-
-		hash = ((hash << 15) | (hash >> 1)) + (ch & 0xff);
-		hash = ((hash << 15) | (hash >> 1)) + (ch >> 8);
-	}
-
-	return hash;
-}
-
-void exfat_dentry_get_name(const exfat_name_dentry_t *name, size_t size, uint16_t *dst, size_t *offset)
-{
-	size_t i=0; 
-	while(i<EXFAT_NAME_PART_LEN && *offset < size) {
-		dst[*offset] = uint16_t_le2host(name->name[i]);
-		i++;
-		(*offset)++;
-	}
-	dst[*offset] = '\0';
-}
-
-bool exfat_valid_char(wchar_t ch)
-{
-	/* TODO */
-	return true;
-}
-
-bool exfat_valid_name(const char *name)
-{
-	/* TODO */
-	return true;
-}
-
-size_t utf16_length(const uint16_t *wstr)
-{
-	size_t len = 0;
-	
-	while (*wstr++ != 0)
-		len++;
-	
-	return len;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/fs/exfat/exfat_dentry.h
===================================================================
--- uspace/srv/fs/exfat/exfat_dentry.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,170 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-#ifndef EXFAT_EXFAT_DENTRY_H_
-#define EXFAT_EXFAT_DENTRY_H_
-
-#include <stdint.h>
-#include <bool.h>
-
-#define EXFAT_FILENAME_LEN	255
-#define EXFAT_NAME_PART_LEN	15
-
-#define EXFAT_TYPE_UNUSED	0x00
-#define EXFAT_TYPE_USED		0x80
-#define EXFAT_TYPE_VOLLABEL	0x83
-#define EXFAT_TYPE_BITMAP	0x81
-#define EXFAT_TYPE_UCTABLE	0x82
-#define EXFAT_TYPE_GUID		0xA0
-#define EXFAT_TYPE_FILE		0x85
-#define EXFAT_TYPE_STREAM	0xC0
-#define EXFAT_TYPE_NAME		0xC1
-
-#define EXFAT_ATTR_RDONLY	0x01
-#define EXFAT_ATTR_HIDDEN	0x02
-#define EXFAT_ATTR_SYSTEM	0x04
-#define EXFAT_ATTR_SUBDIR	0x10
-#define EXFAT_ATTR_ARCHIVE	0x20
-
-
-/* All dentry structs should have 31 byte size */
-typedef struct {
-	uint8_t 	size;
-	uint16_t 	label[11];
-	uint8_t 	_reserved[8];
-} __attribute__ ((packed)) exfat_vollabel_dentry_t;
-
-typedef struct {
-	uint8_t 	flags;
-	uint8_t 	_reserved[18];
-	uint32_t 	firstc;
-	uint64_t 	size;
-} __attribute__ ((packed)) exfat_bitmap_dentry_t;
-
-typedef struct {
-	uint8_t 	_reserved1[3];
-	uint32_t 	checksum;
-	uint8_t 	_reserved2[12];
-	uint32_t 	firstc;
-	uint64_t 	size;
-} __attribute__ ((packed)) exfat_uctable_dentry_t;
-
-typedef struct {
-	uint8_t 	count; /* Always zero */ 
-	uint16_t 	checksum;
-	uint16_t 	flags;
-	uint8_t 	guid[16];
-	uint8_t 	_reserved[10];
-} __attribute__ ((packed)) exfat_guid_dentry_t;
-
-typedef struct {
-	uint8_t 	count;
-	uint16_t 	checksum;
-	uint16_t 	attr;
-	uint8_t 	_reserved1[2];
-	uint32_t 	ctime;
-	uint32_t 	mtime;
-	uint32_t 	atime;
-	uint8_t 	ctime_fine;
-	uint8_t 	mtime_fine;
-	uint8_t 	ctime_tz;
-	uint8_t 	mtime_tz;
-	uint8_t 	atime_tz;
-	uint8_t 	_reserved2[7];
-} __attribute__ ((packed)) exfat_file_dentry_t;
-
-typedef struct {
-	uint8_t 	flags;
-	uint8_t 	_reserved1[1];
-	uint8_t 	name_size;
-	uint16_t 	hash;
-	uint8_t 	_reserved2[2];
-	uint64_t 	valid_data_size;
-	uint8_t 	_reserved3[4];
-	uint32_t 	firstc;
-	uint64_t 	data_size;
-} __attribute__ ((packed)) exfat_stream_dentry_t;
-
-typedef struct {
-	uint8_t 	flags;
-	uint16_t 	name[EXFAT_NAME_PART_LEN];
-} __attribute__ ((packed)) exfat_name_dentry_t;
-
-
-typedef struct {
-	uint8_t type;
-	union {
-		exfat_vollabel_dentry_t	vollabel;
-		exfat_bitmap_dentry_t 	bitmap;
-		exfat_uctable_dentry_t 	uctable;
-		exfat_guid_dentry_t 	guid;
-		exfat_file_dentry_t 	file;
-		exfat_stream_dentry_t 	stream;
-		exfat_name_dentry_t 	name;
-	};
-} __attribute__ ((packed)) exfat_dentry_t;
-
-
-typedef enum {
-	EXFAT_DENTRY_SKIP,
-	EXFAT_DENTRY_LAST,
-	EXFAT_DENTRY_FREE,
-	EXFAT_DENTRY_VOLLABEL,
-	EXFAT_DENTRY_BITMAP,
-	EXFAT_DENTRY_UCTABLE,
-	EXFAT_DENTRY_GUID,
-	EXFAT_DENTRY_FILE,
-	EXFAT_DENTRY_STREAM,
-	EXFAT_DENTRY_NAME
-} exfat_dentry_clsf_t;
-
-
-extern exfat_dentry_clsf_t exfat_classify_dentry(const exfat_dentry_t *d);
-
-extern uint16_t exfat_name_hash(const uint16_t *name, const uint16_t *uctable, 
-    size_t chars);
-
-extern void exfat_dentry_get_name(const exfat_name_dentry_t *name, size_t size, 
-    uint16_t *dst, size_t *offset);
-
-
-extern bool exfat_valid_char(wchar_t ch);
-extern bool exfat_valid_name(const char *name);
-
-extern size_t utf16_length(const uint16_t *wstr);
-
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_directory.c
===================================================================
--- uspace/srv/fs/exfat/exfat_directory.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,511 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-/**
- * @file	exfat_directory.c
- * @brief	Functions that work with FAT directory.
- */
-
-#include "exfat.h"
-#include "exfat_directory.h"
-#include "exfat_fat.h"
-#include <libblock.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <mem.h>
-#include <malloc.h>
-#include <str.h>
-#include <align.h>
-
-void exfat_directory_init(exfat_directory_t *di)
-{
-	di->b = NULL;
-	di->nodep = NULL;
-	di->bs = NULL;
-	di->blocks = 0;
-	di->pos = 0;
-	di->bnum = 0;
-	di->last = false;
-	di->fragmented = false;
-	di->firstc = 0;
-}
-
-int exfat_directory_open(exfat_node_t *nodep, exfat_directory_t *di)
-{
-	exfat_directory_init(di);
-	di->nodep = nodep;	
-	if (di->nodep->type != EXFAT_DIRECTORY)
-		return EINVAL;
-	di->service_id = nodep->idx->service_id;
-	di->fragmented = nodep->fragmented;
-	di->firstc = nodep->firstc;
-
-	di->bs = block_bb_get(di->service_id);
-/*	di->blocks = nodep->size / BPS(di->bs); */
-	di->blocks = ROUND_UP(nodep->size, BPS(di->bs))/BPS(di->bs);
-	return EOK;
-}
-
-int exfat_directory_open_parent(exfat_directory_t *di, 
-    service_id_t service_id, exfat_cluster_t firstc, bool fragmented)
-{
-	exfat_directory_init(di);
-	di->service_id = service_id;
-	di->fragmented = fragmented;
-	di->firstc = firstc;
-	di->bs = block_bb_get(service_id);
-	di->blocks = 0;
-	return EOK;
-}
-
-int exfat_directory_close(exfat_directory_t *di)
-{
-	int rc=EOK;
-	
-	if (di->b)
-		rc = block_put(di->b);
-	
-	return rc;
-}
-
-static int exfat_directory_block_load(exfat_directory_t *di)
-{
-	uint32_t i;
-	int rc;
-
-	i = (di->pos * sizeof(exfat_dentry_t)) / BPS(di->bs);
-	if (di->nodep && (i >= di->blocks))
-		return ENOENT;
-
-	if (di->b && di->bnum != i) {
-		block_put(di->b);
-		di->b = NULL;
-	}
-	if (!di->b) {
-		if (di->nodep) {
-			rc = exfat_block_get(&di->b, di->bs, di->nodep, i, BLOCK_FLAGS_NONE);
-		} else {
-			rc = exfat_block_get_by_clst(&di->b, di->bs, di->service_id,
-			    di->fragmented, di->firstc, NULL, i, BLOCK_FLAGS_NONE);
-		}
-		if (rc != EOK) {
-			di->b = NULL;
-			return rc;
-		}
-		di->bnum = i;
-	}
-	return EOK;
-}
-
-int exfat_directory_next(exfat_directory_t *di)
-{
-	int rc;
-
-	di->pos += 1;
-	rc = exfat_directory_block_load(di);
-	if (rc!=EOK)
-		di->pos -= 1;
-	
-	return rc;
-}
-
-int exfat_directory_prev(exfat_directory_t *di)
-{
-	int rc=EOK;
-	
-	if (di->pos > 0) {
-		di->pos -= 1;
-		rc=exfat_directory_block_load(di);
-	}
-	else
-		return ENOENT;
-	
-	if (rc!=EOK)
-		di->pos += 1;
-	
-	return rc;
-}
-
-int exfat_directory_seek(exfat_directory_t *di, aoff64_t pos)
-{
-	aoff64_t _pos = di->pos;
-	int rc;
-
-	di->pos = pos;
-	rc = exfat_directory_block_load(di);
-	if (rc!=EOK)
-		di->pos = _pos;
-	
-	return rc;
-}
-
-int exfat_directory_get(exfat_directory_t *di, exfat_dentry_t **d)
-{
-	int rc;
-	
-	rc = exfat_directory_block_load(di);
-	if (rc == EOK) {
-		aoff64_t o = di->pos % (BPS(di->bs) / sizeof(exfat_dentry_t));
-		*d = ((exfat_dentry_t *)di->b->data) + o;
-	}
-	
-	return rc;
-}
-
-int exfat_directory_find(exfat_directory_t *di, exfat_dentry_clsf_t type, exfat_dentry_t **d)
-{
-	do {
-		if (exfat_directory_get(di, d) == EOK) {
-			if (exfat_classify_dentry(*d) == type)
-				return EOK;
-		} else
-			return ENOENT;
-	} while (exfat_directory_next(di) == EOK);
-	
-	return ENOENT;
-}
-
-int exfat_directory_find_continue(exfat_directory_t *di, exfat_dentry_clsf_t type, exfat_dentry_t **d)
-{
-	int rc;
-	rc = exfat_directory_next(di);
-	if (rc != EOK)
-		return rc;
-	return exfat_directory_find(di, type, d);
-}
-
-
-int exfat_directory_read_file(exfat_directory_t *di, char *name, size_t size, 
-    exfat_file_dentry_t *df, exfat_stream_dentry_t *ds)
-{
-	uint16_t wname[EXFAT_FILENAME_LEN+1];
-	exfat_dentry_t *d = NULL;
-	int rc, i;
-	size_t offset = 0;
-	aoff64_t start_pos = 0;
-	
-	rc = exfat_directory_find(di, EXFAT_DENTRY_FILE, &d);
-	if (rc != EOK)
-		return rc;
-	start_pos = di->pos;
-	*df = d->file;
-
-	rc = exfat_directory_next(di);
-	if (rc != EOK)
-		return rc;
-	rc = exfat_directory_get(di, &d); 
-	if (rc != EOK)
-		return rc;
-	if (exfat_classify_dentry(d) != EXFAT_DENTRY_STREAM)
-		return ENOENT;
-	*ds  = d->stream;
-	
-	if (ds->name_size > size)
-		return EOVERFLOW;
-
-	for (i=0; i<df->count-1; i++) {
-		rc = exfat_directory_next(di);
-		if (rc != EOK)
-			return rc;
-		rc = exfat_directory_get(di, &d); 
-		if (rc != EOK)
-			return rc;
-		if (exfat_classify_dentry(d) != EXFAT_DENTRY_NAME)
-			return ENOENT;
-		exfat_dentry_get_name(&d->name, ds->name_size, wname, &offset);
-	}
-	rc = utf16_to_str(name, size, wname);
-	if (rc != EOK)
-		return rc;
-
-	exfat_directory_seek(di, start_pos);
-	return EOK;
-}
-
-static uint16_t exfat_directory_set_checksum(const uint8_t *bytes, size_t count)
-{
-	uint16_t checksum = 0;
-	size_t idx;
-
-	for (idx = 0; idx < count; idx++) {
-		if (idx == 2 || idx == 3)
-			continue;
-		checksum = ((checksum << 15) | (checksum >> 1)) + (uint16_t)bytes[idx];
-	}
-	return checksum;
-}
-
-int exfat_directory_sync_file(exfat_directory_t *di, exfat_file_dentry_t *df, 
-    exfat_stream_dentry_t *ds)
-{
-	int rc, i, count;
-	exfat_dentry_t *array=NULL, *de;
-	aoff64_t pos = di->pos;
-
-	rc = exfat_directory_get(di, &de);
-	if (rc != EOK)
-		return rc;
-	count = de->file.count+1;
-	array = (exfat_dentry_t *) malloc(count*sizeof(exfat_dentry_t));
-	if (!array)
-		return ENOMEM;
-	for (i=0; i<count; i++) {
-		rc = exfat_directory_get(di, &de);
-		if (rc != EOK)
-			return rc;
-		array[i] = *de;
-		rc = exfat_directory_next(di);
-		if (rc!=EOK) {
-			free(array);
-			return rc;
-		}
-	}
-	rc = exfat_directory_seek(di, pos);
-	if (rc!=EOK) {
-		free(array);
-		return rc;
-	}
-
-	/* Sync */
-	array[0].file.attr = host2uint16_t_le(df->attr);
-	array[1].stream.firstc = host2uint32_t_le(ds->firstc);
-	array[1].stream.flags = ds->flags;
-	array[1].stream.valid_data_size = host2uint64_t_le(ds->valid_data_size);
-	array[1].stream.data_size = host2uint64_t_le(ds->data_size);
-	array[0].file.checksum = host2uint16_t_le(exfat_directory_set_checksum((uint8_t *)array,
-	    count*sizeof(exfat_dentry_t)));
-
-	/* Store */
-	for (i=0; i<count; i++) {
-		rc = exfat_directory_get(di, &de);
-		if (rc != EOK)
-			return rc;
-		*de = array[i];
-		di->b->dirty = true;
-		rc = exfat_directory_next(di);
-		if (rc!=EOK) {
-			free(array);
-			return rc;
-		}
-	}
-	free(array);
-
-	return EOK;
-}
-
-int exfat_directory_write_file(exfat_directory_t *di, const char *name)
-{
-	fs_node_t *fn;
-	exfat_node_t *uctablep;
-	uint16_t *uctable;
-	exfat_dentry_t df, ds, *de;
-	uint16_t wname[EXFAT_FILENAME_LEN+1];
-	int rc, i;
-	size_t uctable_chars, j;
-	aoff64_t pos;
-
-	rc = str_to_utf16(wname, EXFAT_FILENAME_LEN, name);
-	if (rc != EOK)
-		return rc;
-	rc = exfat_uctable_get(&fn, di->service_id);
-	if (rc != EOK)
-		return rc;
-	uctablep = EXFAT_NODE(fn);
-
-	uctable_chars = ALIGN_DOWN(uctablep->size, sizeof(uint16_t)) / sizeof(uint16_t); 
-	uctable = (uint16_t *) malloc(uctable_chars * sizeof(uint16_t));
-	rc = exfat_read_uctable(di->bs, uctablep, (uint8_t *)uctable);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		free(uctable);
-		return rc;
-	}
-
-	/* Fill stream entry */
-	ds.type = EXFAT_TYPE_STREAM;
-	ds.stream.flags = 0;
-	ds.stream.valid_data_size = 0;
-	ds.stream.data_size = 0;
-	ds.stream.name_size = utf16_length(wname);
-	ds.stream.hash = host2uint16_t_le(exfat_name_hash(wname, uctable, 
-	    uctable_chars));
-
-	/* Fill file entry */
-	df.type = EXFAT_TYPE_FILE;
-	df.file.attr = 0;
-	df.file.count = ROUND_UP(ds.stream.name_size, EXFAT_NAME_PART_LEN) / 
-	    EXFAT_NAME_PART_LEN + 1;
-	df.file.checksum = 0;
-
-	free(uctable);
-	rc = exfat_node_put(fn);
-	if (rc != EOK)
-		return rc;
-
-	/* Looking for set of free entries */
-	rc = exfat_directory_lookup_free(di, df.file.count+1);
-	if (rc != EOK)
-		return rc;
-	pos = di->pos;
-
-	/* Write file entry */
-	rc = exfat_directory_get(di, &de);
-	if (rc != EOK)
-		return rc;
-	*de = df;
-	di->b->dirty = true;
-	rc = exfat_directory_next(di);
-	if (rc != EOK)
-		return rc;
-
-	/* Write stream entry */
-	rc = exfat_directory_get(di, &de);
-	if (rc != EOK)
-		return rc;
-	*de = ds;
-	di->b->dirty = true;
-
-	/* Write file name */
-	size_t chars = EXFAT_NAME_PART_LEN;
-	uint16_t *sname = wname;
-
-	for (i=0; i<ds.stream.name_size; i++)
-		wname[i] = host2uint16_t_le(wname[i]);
-
-	for (i=0; i < df.file.count-1; i++) {
-		rc = exfat_directory_next(di);
-		if (rc != EOK)
-			return rc;
-
-		if (i == df.file.count-2)
-			chars = ds.stream.name_size - EXFAT_NAME_PART_LEN*(df.file.count-2);
-		rc = exfat_directory_get(di, &de);
-		if (rc != EOK)
-			return rc;
-		de->type = EXFAT_TYPE_NAME;
-		/* test */
-		for (j=0; j<chars; j++){
-			de->name.name[j] = *sname;
-			sname++;
-		}
-
-		di->b->dirty = true;
-		sname += chars;
-	}
-	
-	return exfat_directory_seek(di, pos);
-}
-
-int exfat_directory_erase_file(exfat_directory_t *di, aoff64_t pos)
-{
-	int rc, count;
-	exfat_dentry_t *de;
-
-	rc = exfat_directory_get(di, &de);
-	if (rc != EOK)
-		return rc;
-	count = de->file.count+1;
-	
-	while (count) {
-		rc = exfat_directory_get(di, &de);
-		if (rc != EOK)
-			return rc;
-		de->type &= (~EXFAT_TYPE_USED);
-		di->b->dirty = true;
-
-		rc = exfat_directory_next(di);
-		if (rc!=EOK)
-			return rc;
-		count--;
-	}
-	return EOK;
-}
-
-int exfat_directory_expand(exfat_directory_t *di)
-{
-	int rc;
-
-	if (!di->nodep)
-		return ENOSPC;
-
-	rc = exfat_node_expand(di->nodep->idx->service_id, di->nodep, 1);
-	if (rc != EOK)
-		return rc;
-
-	di->fragmented = di->nodep->fragmented;
-	di->nodep->size += BPC(di->bs);
-	di->nodep->dirty = true;		/* need to sync node */
-	di->blocks = di->nodep->size / BPS(di->bs);
-	
-	return EOK;
-}
-
-int exfat_directory_lookup_free(exfat_directory_t *di, size_t count)
-{
-	int rc;
-	exfat_dentry_t *d;
-	size_t found;
-	aoff64_t pos;
-
-	rc = exfat_directory_seek(di, 0);
-	if (rc != EOK)
-		return rc;
-
-	do {
-		found = 0;
-		pos = 0;
-		do {
-			if (exfat_directory_get(di, &d) == EOK) {
-				switch (exfat_classify_dentry(d)) {
-				case EXFAT_DENTRY_LAST:
-				case EXFAT_DENTRY_FREE:
-					if (found==0) pos = di->pos;
-					found++;
-					if (found == count) {
-						exfat_directory_seek(di, pos);
-						return EOK;
-					}
-					break;
-				default:
-					found = 0;
-					break;
-				}
-			}
-		} while (exfat_directory_next(di) == EOK);	
-	} while (exfat_directory_expand(di) == EOK);
-	return ENOSPC;
-}
-
-
-/**
- * @}
- */ 
Index: pace/srv/fs/exfat/exfat_directory.h
===================================================================
--- uspace/srv/fs/exfat/exfat_directory.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,87 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-#ifndef EXFAT_EXFAT_DIRECTORY_H_
-#define EXFAT_EXFAT_DIRECTORY_H_
-
-#include <stdint.h>
-#include "exfat.h"
-#include "exfat_fat.h"
-#include "exfat_dentry.h"
-
-typedef struct {
-	/* Directory data */
-	exfat_bs_t *bs;
-	exfat_node_t *nodep;
-	service_id_t service_id;
-	uint32_t blocks;
-	uint32_t bnum;
-	aoff64_t pos;
-	block_t *b;
-	bool last;
-	bool fragmented;
-	exfat_cluster_t firstc;
-} exfat_directory_t;
-
-
-extern void exfat_directory_init(exfat_directory_t *di);
-extern int exfat_directory_open(exfat_node_t *nodep, exfat_directory_t *di);
-extern int exfat_directory_open_parent(exfat_directory_t *di, 
-    service_id_t service_id, exfat_cluster_t firstc, bool fragmented);
-extern int exfat_directory_close(exfat_directory_t *di);
-
-extern int exfat_directory_next(exfat_directory_t *di);
-extern int exfat_directory_prev(exfat_directory_t *di);
-extern int exfat_directory_seek(exfat_directory_t *di, aoff64_t pos);
-extern int exfat_directory_get(exfat_directory_t *di, exfat_dentry_t **de);
-extern int exfat_directory_find(exfat_directory_t *di, 
-    exfat_dentry_clsf_t type, exfat_dentry_t **d);
-extern int exfat_directory_find_continue(exfat_directory_t *di, 
-    exfat_dentry_clsf_t type, exfat_dentry_t **d);
-
-extern int exfat_directory_read_file(exfat_directory_t *di, char *name, 
-    size_t size, exfat_file_dentry_t *df, exfat_stream_dentry_t *ds);
-extern int exfat_directory_sync_file(exfat_directory_t *di, 
-    exfat_file_dentry_t *df, exfat_stream_dentry_t *ds);
-extern int exfat_directory_write_file(exfat_directory_t *di, const char *name);
-extern int exfat_directory_erase_file(exfat_directory_t *di, aoff64_t pos);
-
-extern int exfat_directory_expand(exfat_directory_t *di);
-extern int exfat_directory_lookup_free(exfat_directory_t *di, size_t count);
-extern int exfat_directory_print(exfat_directory_t *di);
-
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_fat.c
===================================================================
--- uspace/srv/fs/exfat/exfat_fat.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,546 +1,0 @@
-/*
- * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */
-
-/**
- * @file	exfat_fat.c
- * @brief	Functions that manipulate the File Allocation Table.
- */
-
-#include "exfat_fat.h"
-#include "exfat_bitmap.h"
-#include "exfat.h"
-#include "../../vfs/vfs.h"
-#include <libfs.h>
-#include <libblock.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <align.h>
-#include <assert.h>
-#include <fibril_synch.h>
-#include <malloc.h>
-#include <mem.h>
-
-
-/**
- * The fat_alloc_lock mutex protects all copies of the File Allocation Table
- * during allocation of clusters. The lock does not have to be held durring
- * deallocation of clusters.
- */
-static FIBRIL_MUTEX_INITIALIZE(exfat_alloc_lock);
-
-/** Walk the cluster chain.
- *
- * @param bs		Buffer holding the boot sector for the file.
- * @param service_id	Service ID of the device with the file.
- * @param firstc	First cluster to start the walk with.
- * @param lastc		If non-NULL, output argument hodling the last cluster
- *			number visited.
- * @param numc		If non-NULL, output argument holding the number of
- *			clusters seen during the walk.
- * @param max_clusters	Maximum number of clusters to visit.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-exfat_cluster_walk(exfat_bs_t *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t *lastc, uint32_t *numc,
-    uint32_t max_clusters)
-{
-	uint32_t clusters = 0;
-	exfat_cluster_t clst = firstc;
-	int rc;
-
-	if (firstc < EXFAT_CLST_FIRST) {
-		/* No space allocated to the file. */
-		if (lastc)
-			*lastc = firstc;
-		if (numc)
-			*numc = 0;
-		return EOK;
-	}
-
-	while (clst != EXFAT_CLST_EOF && clusters < max_clusters) {
-		assert(clst >= EXFAT_CLST_FIRST);
-		if (lastc)
-			*lastc = clst;	/* remember the last cluster number */
-
-		rc = exfat_get_cluster(bs, service_id, clst, &clst);
-		if (rc != EOK)
-			return rc;
-
-		assert(clst != EXFAT_CLST_BAD);
-		clusters++;
-	}
-
-	if (lastc && clst != EXFAT_CLST_EOF)
-		*lastc = clst;
-	if (numc)
-		*numc = clusters;
-
-	return EOK;
-}
-
-/** Read block from file located on a exFAT file system.
- *
- * @param block		Pointer to a block pointer for storing result.
- * @param bs		Buffer holding the boot sector of the file system.
- * @param nodep		FAT node.
- * @param bn		Block number.
- * @param flags		Flags passed to libblock.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-exfat_block_get(block_t **block, exfat_bs_t *bs, exfat_node_t *nodep,
-    aoff64_t bn, int flags)
-{
-	exfat_cluster_t firstc = nodep->firstc;
-	exfat_cluster_t currc;
-	aoff64_t relbn = bn;
-	int rc;
-
-	if (!nodep->size)
-		return ELIMIT;
-
-	if (nodep->fragmented) {
-		if (((((nodep->size - 1) / BPS(bs)) / SPC(bs)) == bn / SPC(bs)) &&
-			nodep->lastc_cached_valid) {
-				/*
-			* This is a request to read a block within the last cluster
-			* when fortunately we have the last cluster number cached.
-			*/
-			return block_get(block, nodep->idx->service_id, DATA_FS(bs) + 
-		        (nodep->lastc_cached_value-EXFAT_CLST_FIRST)*SPC(bs) + 
-			    (bn % SPC(bs)), flags);
-		}
-
-		if (nodep->currc_cached_valid && bn >= nodep->currc_cached_bn) {
-			/*
-			* We can start with the cluster cached by the previous call to
-			* fat_block_get().
-			*/
-			firstc = nodep->currc_cached_value;
-			relbn -= (nodep->currc_cached_bn / SPC(bs)) * SPC(bs);
-		}
-	}
-
-	rc = exfat_block_get_by_clst(block, bs, nodep->idx->service_id,
-	    nodep->fragmented, firstc, &currc, relbn, flags);
-	if (rc != EOK)
-		return rc;
-
-	/*
-	 * Update the "current" cluster cache.
-	 */
-	nodep->currc_cached_valid = true;
-	nodep->currc_cached_bn = bn;
-	nodep->currc_cached_value = currc;
-
-	return rc;
-}
-
-/** Read block from file located on a exFAT file system.
- *
- * @param block		Pointer to a block pointer for storing result.
- * @param bs		Buffer holding the boot sector of the file system.
- * @param service_id	Service ID of the file system.
- * @param fcl		First cluster used by the file. Can be zero if the file
- *			is empty.
- * @param clp		If not NULL, address where the cluster containing bn
- *			will be stored.
- *			stored
- * @param bn		Block number.
- * @param flags		Flags passed to libblock.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-exfat_block_get_by_clst(block_t **block, exfat_bs_t *bs, 
-    service_id_t service_id, bool fragmented, exfat_cluster_t fcl,
-    exfat_cluster_t *clp, aoff64_t bn, int flags)
-{
-	uint32_t clusters;
-	uint32_t max_clusters;
-	exfat_cluster_t c;
-	int rc;
-
-	if (fcl < EXFAT_CLST_FIRST || fcl > DATA_CNT(bs)+2)
-		return ELIMIT;
-
-	if (!fragmented) {
-		rc = block_get(block, service_id, DATA_FS(bs) + 
-		    (fcl-EXFAT_CLST_FIRST)*SPC(bs) + bn, flags);
-	} else {
-		max_clusters = bn / SPC(bs);
-		rc = exfat_cluster_walk(bs, service_id, fcl, &c, &clusters, max_clusters);
-		if (rc != EOK)
-			return rc;
-		assert(clusters == max_clusters);
-
-		rc = block_get(block, service_id, DATA_FS(bs) + 
-		    (c-EXFAT_CLST_FIRST)*SPC(bs) + (bn % SPC(bs)), flags);
-
-		if (clp)
-			*clp = c;
-	}
-
-	return rc;
-}
-
-
-/** Get cluster from the FAT.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param clst		Cluster which to get.
- * @param value		Output argument holding the value of the cluster.
- *
- * @return		EOK or a negative error code.
- */
-int
-exfat_get_cluster(exfat_bs_t *bs, service_id_t service_id,
-    exfat_cluster_t clst, exfat_cluster_t *value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-
-	offset = clst * sizeof(exfat_cluster_t);
-
-	rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	*value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs)));
-
-	rc = block_put(b);
-
-	return rc;
-}
-
-/** Set cluster in FAT.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param clst		Cluster which is to be set.
- * @param value		Value to set the cluster with.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-exfat_set_cluster(exfat_bs_t *bs, service_id_t service_id,
-    exfat_cluster_t clst, exfat_cluster_t value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-
-	offset = clst * sizeof(exfat_cluster_t);
-
-	rc = block_get(&b, service_id, FAT_FS(bs) + offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	*(uint32_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(value);
-
-	b->dirty = true;	/* need to sync block */
-	rc = block_put(b);
-	return rc;
-}
-
-/** Allocate clusters in FAT.
- *
- * This function will attempt to allocate the requested number of clusters in
- * the FAT.  The FAT will be altered so that the allocated
- * clusters form an independent chain (i.e. a chain which does not belong to any
- * file yet).
- *
- * @param bs		Buffer holding the boot sector of the file system.
- * @param service_id	Service ID of the file system.
- * @param nclsts	Number of clusters to allocate.
- * @param mcl		Output parameter where the first cluster in the chain
- *			will be returned.
- * @param lcl		Output parameter where the last cluster in the chain
- *			will be returned.
- *
- * @return		EOK on success, a negative error code otherwise.
- */
-int
-exfat_alloc_clusters(exfat_bs_t *bs, service_id_t service_id, unsigned nclsts,
-    exfat_cluster_t *mcl, exfat_cluster_t *lcl)
-{
-	exfat_cluster_t *lifo;    /* stack for storing free cluster numbers */
-	unsigned found = 0;     /* top of the free cluster number stack */
-	exfat_cluster_t clst;
-	int rc = EOK;
-
-	lifo = (exfat_cluster_t *) malloc(nclsts * sizeof(exfat_cluster_t));
-	if (!lifo)
-		return ENOMEM;
-
-	fibril_mutex_lock(&exfat_alloc_lock);
-	for (clst=EXFAT_CLST_FIRST; clst < DATA_CNT(bs)+2 && found < nclsts; clst++) {
-		/* Need to rewrite because of multiple exfat_bitmap_get calls */
-		if (bitmap_is_free(bs, service_id, clst)==EOK) {
-		   /*
-			* The cluster is free. Put it into our stack
-			* of found clusters and mark it as non-free.
-			*/
-			lifo[found] = clst;
-			rc = exfat_set_cluster(bs, service_id, clst,
-				(found == 0) ?  EXFAT_CLST_EOF : lifo[found - 1]);
-			if (rc != EOK)
-				break;
-			found++;
-			rc = bitmap_set_cluster(bs, service_id, clst);
-			if (rc != EOK)
-				break;
-
-		}
-	}
-
-	if (rc == EOK && found == nclsts) {
-		*mcl = lifo[found - 1];
-		*lcl = lifo[0];
-		free(lifo);
-		fibril_mutex_unlock(&exfat_alloc_lock);
-		return EOK;
-	}
-
-	/* If something wrong - free the clusters */
-	if (found > 0) {
-		while (found--) {
-			(void) bitmap_clear_cluster(bs, service_id, lifo[found]);
-			(void) exfat_set_cluster(bs, service_id, lifo[found], 0);
-		}
-	}
-
-	free(lifo);
-	fibril_mutex_unlock(&exfat_alloc_lock);
-	return ENOSPC;
-}
-
-/** Free clusters forming a cluster chain in FAT.
- *
- * @param bs		Buffer hodling the boot sector of the file system.
- * @param service_id	Service ID of the file system.
- * @param firstc	First cluster in the chain which is to be freed.
- *
- * @return		EOK on success or a negative return code.
- */
-int
-exfat_free_clusters(exfat_bs_t *bs, service_id_t service_id, exfat_cluster_t firstc)
-{
-	exfat_cluster_t nextc;
-	int rc;
-
-	/* Mark all clusters in the chain as free */
-	while (firstc != EXFAT_CLST_EOF) {
-		assert(firstc >= EXFAT_CLST_FIRST && firstc < EXFAT_CLST_BAD);
-		rc = exfat_get_cluster(bs, service_id, firstc, &nextc);
-		if (rc != EOK)
-			return rc;
-		rc = exfat_set_cluster(bs, service_id, firstc, 0);
-		if (rc != EOK)
-			return rc;
-		rc = bitmap_clear_cluster(bs, service_id, firstc);
-		if (rc != EOK)
-			return rc;
-		firstc = nextc;
-	}
-
-	return EOK;
-}
-
-/** Append a cluster chain to the last file cluster in FAT.
- *
- * @param bs		Buffer holding the boot sector of the file system.
- * @param nodep		Node representing the file.
- * @param mcl		First cluster of the cluster chain to append.
- * @param lcl		Last cluster of the cluster chain to append.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-exfat_append_clusters(exfat_bs_t *bs, exfat_node_t *nodep, exfat_cluster_t mcl,
-    exfat_cluster_t lcl)
-{
-	service_id_t service_id = nodep->idx->service_id;
-	exfat_cluster_t lastc;
-	int rc;
-
-	if (nodep->firstc == 0) {
-		/* No clusters allocated to the node yet. */
-		nodep->firstc = mcl;
-		nodep->dirty = true;	/* need to sync node */
-	} else {
-		if (nodep->lastc_cached_valid) {
-			lastc = nodep->lastc_cached_value;
-			nodep->lastc_cached_valid = false;
-		} else {
-			rc = exfat_cluster_walk(bs, service_id, nodep->firstc,
-			    &lastc, NULL, (uint16_t) -1);
-			if (rc != EOK)
-				return rc;
-		}
-
-		rc = exfat_set_cluster(bs, nodep->idx->service_id, lastc, mcl);
-		if (rc != EOK)
-			return rc;
-	}
-
-	nodep->lastc_cached_valid = true;
-	nodep->lastc_cached_value = lcl;
-
-	return EOK;
-}
-
-/** Chop off node clusters in FAT.
- *
- * @param bs		Buffer holding the boot sector of the file system.
- * @param nodep		FAT node where the chopping will take place.
- * @param lcl		Last cluster which will remain in the node. If this
- *			argument is FAT_CLST_RES0, then all clusters will
- *			be chopped off.
- *
- * @return		EOK on success or a negative return code.
- */
-int exfat_chop_clusters(exfat_bs_t *bs, exfat_node_t *nodep, exfat_cluster_t lcl)
-{
-	int rc;
-	service_id_t service_id = nodep->idx->service_id;
-
-	/*
-	 * Invalidate cached cluster numbers.
-	 */
-	nodep->lastc_cached_valid = false;
-	if (nodep->currc_cached_value != lcl)
-		nodep->currc_cached_valid = false;
-
-	if (lcl == 0) {
-		/* The node will have zero size and no clusters allocated. */
-		rc = exfat_free_clusters(bs, service_id, nodep->firstc);
-		if (rc != EOK)
-			return rc;
-		nodep->firstc = 0;
-		nodep->dirty = true;		/* need to sync node */
-	} else {
-		exfat_cluster_t nextc;
-
-		rc = exfat_get_cluster(bs, service_id, lcl, &nextc);
-		if (rc != EOK)
-			return rc;
-
-		/* Terminate the cluster chain */
-		rc = exfat_set_cluster(bs, service_id, lcl, EXFAT_CLST_EOF);
-		if (rc != EOK)
-			return rc;
-
-		/* Free all following clusters. */
-		rc = exfat_free_clusters(bs, service_id, nextc);
-		if (rc != EOK)
-			return rc;
-	}
-
-	/*
-	 * Update and re-enable the last cluster cache.
-	 */
-	nodep->lastc_cached_valid = true;
-	nodep->lastc_cached_value = lcl;
-
-	return EOK;
-}
-
-int
-exfat_zero_cluster(exfat_bs_t *bs, service_id_t service_id, exfat_cluster_t c)
-{
-	size_t i;
-	block_t *b;
-	int rc;
-
-	for (i = 0; i < SPC(bs); i++) {
-		rc = exfat_block_get_by_clst(&b, bs, service_id, false, c, NULL, i,
-		    BLOCK_FLAGS_NOREAD);
-		if (rc != EOK)
-			return rc;
-		memset(b->data, 0, BPS(bs));
-		b->dirty = true;
-		rc = block_put(b);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return EOK;
-}
-
-int
-exfat_read_uctable(exfat_bs_t *bs, exfat_node_t *nodep, uint8_t *uctable)
-{
-	size_t i, blocks, count;
-	block_t *b;
-	int rc;
-	blocks = ROUND_UP(nodep->size, BPS(bs))/BPS(bs);
-	count = BPS(bs);
-	
-	for (i = 0; i < blocks; i++) {
-		rc = exfat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NOREAD);
-		if (rc != EOK)
-			return rc;
-		if (i == blocks-1)
-			count = nodep->size - i*BPS(bs);
-		memcpy(uctable, b->data, count);
-		uctable += count;
-		rc = block_put(b);
-		if (rc != EOK)
-			return rc;
-	}
-
-	return EOK;
-}
-
-
-/** Perform basic sanity checks on the file system.
- *
- * Verify if values of boot sector fields are sane. Also verify media
- * descriptor. This is used to rule out cases when a device obviously
- * does not contain a exfat file system.
- */
-int exfat_sanity_check(exfat_bs_t *bs, service_id_t service_id)
-{
-	/* TODO */
-	return EOK;
-}
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_fat.h
===================================================================
--- uspace/srv/fs/exfat/exfat_fat.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,95 +1,0 @@
-/*
- * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */
-
-#ifndef EXFAT_FAT_FAT_H_
-#define EXFAT_FAT_FAT_H_
-
-#include "../../vfs/vfs.h"
-#include <stdint.h>
-#include <libblock.h>
-
-#define EXFAT_ROOT_IDX		0
-#define EXFAT_BITMAP_IDX	1
-#define EXFAT_UCTABLE_IDX	2
-
-#define EXFAT_ROOT_PAR	0
-#define EXFAT_ROOT_POS	0
-
-#define EXFAT_CLST_FIRST	0x00000002
-#define EXFAT_CLST_LAST		0xfffffff6
-#define EXFAT_CLST_BAD		0xfffffff7
-#define EXFAT_CLST_EOF		0xffffffff
-
-/* forward declarations */
-struct block;
-struct exfat_node;
-struct exfat_bs;
-
-typedef uint32_t exfat_cluster_t;
-
-
-#define exfat_clusters_get(numc, bs, sid, fc) \
-    exfat_cluster_walk((bs), (sid), (fc), NULL, (numc), (uint32_t) -1)
-extern int exfat_cluster_walk(struct exfat_bs *bs, service_id_t service_id, 
-    exfat_cluster_t firstc, exfat_cluster_t *lastc, uint32_t *numc,
-    uint32_t max_clusters);
-extern int exfat_block_get(block_t **block, struct exfat_bs *bs,
-    struct exfat_node *nodep, aoff64_t bn, int flags);
-extern int exfat_block_get_by_clst(block_t **block, struct exfat_bs *bs, 
-    service_id_t service_id, bool fragmented, exfat_cluster_t fcl,
-    exfat_cluster_t *clp, aoff64_t bn, int flags);
-
-extern int exfat_get_cluster(struct exfat_bs *bs, service_id_t service_id,
-    exfat_cluster_t clst, exfat_cluster_t *value);
-extern int exfat_set_cluster(struct exfat_bs *bs, service_id_t service_id,
-    exfat_cluster_t clst, exfat_cluster_t value);
-extern int exfat_sanity_check(struct exfat_bs *, service_id_t);
-
-extern int exfat_append_clusters(struct exfat_bs *, struct exfat_node *,
-    exfat_cluster_t, exfat_cluster_t);
-extern int exfat_chop_clusters(struct exfat_bs *, struct exfat_node *,
-    exfat_cluster_t);
-extern int exfat_alloc_clusters(struct exfat_bs *, service_id_t, unsigned,
-    exfat_cluster_t *, exfat_cluster_t *);
-extern int exfat_free_clusters(struct exfat_bs *, service_id_t, exfat_cluster_t);
-extern int exfat_zero_cluster(struct exfat_bs * bs, service_id_t service_id, 
-    exfat_cluster_t mcl);
-
-extern int exfat_read_uctable(struct exfat_bs *bs, struct exfat_node *nodep, 
-    uint8_t *uctable);
-
-#endif
-
-/**
- * @}
- */
Index: pace/srv/fs/exfat/exfat_idx.c
===================================================================
--- uspace/srv/fs/exfat/exfat_idx.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,608 +1,0 @@
-/*
- * Copyright (c) 2008 Jakub Jermar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-/**
- * @file	exfat_idx.c
- * @brief	Layer for translating exFAT entities to VFS node indices.
- */
-
-#include "exfat.h"
-#include "../../vfs/vfs.h"
-#include <errno.h>
-#include <str.h>
-#include <adt/hash_table.h>
-#include <adt/list.h>
-#include <assert.h>
-#include <fibril_synch.h>
-#include <malloc.h>
-
-/** Each instance of this type describes one interval of freed VFS indices. */
-typedef struct {
-	link_t		link;
-	fs_index_t	first;
-	fs_index_t	last;
-} freed_t;
-
-/**
- * Each instance of this type describes state of all VFS indices that
- * are currently unused.
- */
-typedef struct {
-	link_t link;
-	service_id_t service_id;
-
-	/** Next unassigned index. */
-	fs_index_t next;
-	/** Number of remaining unassigned indices. */
-	uint64_t remaining;
-
-	/** Sorted list of intervals of freed indices. */
-	list_t freed_list;
-} unused_t;
-
-/** Mutex protecting the list of unused structures. */
-static FIBRIL_MUTEX_INITIALIZE(unused_lock);
-
-/** List of unused structures. */
-static LIST_INITIALIZE(unused_list);
-
-static void unused_initialize(unused_t *u, service_id_t service_id)
-{
-	link_initialize(&u->link);
-	u->service_id = service_id;
-	u->next = 0;
-	u->remaining = ((uint64_t)((fs_index_t)-1)) + 1;
-	list_initialize(&u->freed_list);
-}
-
-static unused_t *unused_find(service_id_t service_id, bool lock)
-{
-	unused_t *u;
-
-	if (lock)
-		fibril_mutex_lock(&unused_lock);
-	list_foreach(unused_list, l) {
-		u = list_get_instance(l, unused_t, link);
-		if (u->service_id == service_id) 
-			return u;
-	}
-
-	if (lock)
-		fibril_mutex_unlock(&unused_lock);
-	return NULL;
-}
-
-/** Mutex protecting the up_hash and ui_hash. */
-static FIBRIL_MUTEX_INITIALIZE(used_lock);
-
-/**
- * Global hash table of all used exfat_idx_t structures.
- * The index structures are hashed by the service_id, parent node's first
- * cluster and index within the parent directory.
- */ 
-static hash_table_t up_hash;
-
-#define UPH_BUCKETS_LOG	12
-#define UPH_BUCKETS	(1 << UPH_BUCKETS_LOG)
-
-#define UPH_SID_KEY	0
-#define UPH_PFC_KEY	1
-#define UPH_PDI_KEY	2
-
-static hash_index_t pos_hash(unsigned long key[])
-{
-	service_id_t service_id = (service_id_t)key[UPH_SID_KEY];
-	exfat_cluster_t pfc = (exfat_cluster_t)key[UPH_PFC_KEY];
-	unsigned pdi = (unsigned)key[UPH_PDI_KEY];
-
-	hash_index_t h;
-
-	/*
-	 * The least significant half of all bits are the least significant bits
-	 * of the parent node's first cluster.
-	 *
-	 * The least significant half of the most significant half of all bits
-	 * are the least significant bits of the node's dentry index within the
-	 * parent directory node.
-	 *
-	 * The most significant half of the most significant half of all bits
-	 * are the least significant bits of the device handle.
-	 */
-	h = pfc & ((1 << (UPH_BUCKETS_LOG / 2)) - 1);
-	h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
-	    (UPH_BUCKETS_LOG / 2); 
-	h |= (service_id & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
-	    (3 * (UPH_BUCKETS_LOG / 4));
-
-	return h;
-}
-
-static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item)
-{
-	service_id_t service_id = (service_id_t)key[UPH_SID_KEY];
-	exfat_cluster_t pfc;
-	unsigned pdi;
-	exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uph_link);
-
-	switch (keys) {
-	case 1:
-		return (service_id == fidx->service_id);
-	case 3:
-		pfc = (exfat_cluster_t) key[UPH_PFC_KEY];
-		pdi = (unsigned) key[UPH_PDI_KEY];
-		return (service_id == fidx->service_id) && (pfc == fidx->pfc) &&
-		    (pdi == fidx->pdi);
-	default:
-		assert((keys == 1) || (keys == 3));
-	}
-
-	return 0;
-}
-
-static void pos_remove_callback(link_t *item)
-{
-	/* nothing to do */
-}
-
-static hash_table_operations_t uph_ops = {
-	.hash = pos_hash,
-	.compare = pos_compare,
-	.remove_callback = pos_remove_callback,
-};
-
-/**
- * Global hash table of all used fat_idx_t structures.
- * The index structures are hashed by the service_id and index.
- */
-static hash_table_t ui_hash;
-
-#define UIH_BUCKETS_LOG	12
-#define UIH_BUCKETS	(1 << UIH_BUCKETS_LOG)
-
-#define UIH_SID_KEY	0
-#define UIH_INDEX_KEY	1
-
-static hash_index_t idx_hash(unsigned long key[])
-{
-	service_id_t service_id = (service_id_t)key[UIH_SID_KEY];
-	fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
-
-	hash_index_t h;
-
-	h = service_id & ((1 << (UIH_BUCKETS_LOG / 2)) - 1);
-	h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) <<
-	    (UIH_BUCKETS_LOG / 2);
-
-	return h;
-}
-
-static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item)
-{
-	service_id_t service_id = (service_id_t)key[UIH_SID_KEY];
-	fs_index_t index;
-	exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link);
-
-	switch (keys) {
-	case 1:
-		return (service_id == fidx->service_id);
-	case 2:
-		index = (fs_index_t) key[UIH_INDEX_KEY];
-		return (service_id == fidx->service_id) &&
-		    (index == fidx->index);
-	default:
-		assert((keys == 1) || (keys == 2));
-	}
-
-	return 0;
-}
-
-static void idx_remove_callback(link_t *item)
-{
-	exfat_idx_t *fidx = list_get_instance(item, exfat_idx_t, uih_link);
-
-	free(fidx);
-}
-
-static hash_table_operations_t uih_ops = {
-	.hash = idx_hash,
-	.compare = idx_compare,
-	.remove_callback = idx_remove_callback,
-};
-
-/** Allocate a VFS index which is not currently in use. */
-static bool exfat_index_alloc(service_id_t service_id, fs_index_t *index)
-{
-	unused_t *u;
-	
-	assert(index);
-	u = unused_find(service_id, true);
-	if (!u)
-		return false;	
-
-	if (list_empty(&u->freed_list)) {
-		if (u->remaining) { 
-			/*
-			 * There are no freed indices, allocate one directly
-			 * from the counter.
-			 */
-			*index = u->next++;
-			--u->remaining;
-			fibril_mutex_unlock(&unused_lock);
-			return true;
-		}
-	} else {
-		/* There are some freed indices which we can reuse. */
-		freed_t *f = list_get_instance(list_first(&u->freed_list),
-		    freed_t, link);
-		*index = f->first;
-		if (f->first++ == f->last) {
-			/* Destroy the interval. */
-			list_remove(&f->link);
-			free(f);
-		}
-		fibril_mutex_unlock(&unused_lock);
-		return true;
-	}
-	/*
-	 * We ran out of indices, which is extremely unlikely with FAT16, but
-	 * theoretically still possible (e.g. too many open unlinked nodes or
-	 * too many zero-sized nodes).
-	 */
-	fibril_mutex_unlock(&unused_lock);
-	return false;
-}
-
-/** If possible, coalesce two intervals of freed indices. */
-static void try_coalesce_intervals(link_t *l, link_t *r, link_t *cur)
-{
-	freed_t *fl = list_get_instance(l, freed_t, link);
-	freed_t *fr = list_get_instance(r, freed_t, link);
-
-	if (fl->last + 1 == fr->first) {
-		if (cur == l) {
-			fl->last = fr->last;
-			list_remove(r);
-			free(r);
-		} else {
-			fr->first = fl->first;
-			list_remove(l);
-			free(l);
-		}
-	}
-}
-
-/** Free a VFS index, which is no longer in use. */
-static void exfat_index_free(service_id_t service_id, fs_index_t index)
-{
-	unused_t *u;
-
-	u = unused_find(service_id, true);
-	assert(u);
-
-	if (u->next == index + 1) {
-		/* The index can be returned directly to the counter. */
-		u->next--;
-		u->remaining++;
-	} else {
-		/*
-		 * The index must be returned either to an existing freed
-		 * interval or a new interval must be created.
-		 */
-		link_t *lnk;
-		freed_t *n;
-		for (lnk = u->freed_list.head.next; lnk != &u->freed_list.head;
-		    lnk = lnk->next) {
-			freed_t *f = list_get_instance(lnk, freed_t, link);
-			if (f->first == index + 1) {
-				f->first--;
-				if (lnk->prev != &u->freed_list.head)
-					try_coalesce_intervals(lnk->prev, lnk,
-					    lnk);
-				fibril_mutex_unlock(&unused_lock);
-				return;
-			}
-			if (f->last == index - 1) {
-				f->last++;
-				if (lnk->next != &u->freed_list.head)
-					try_coalesce_intervals(lnk, lnk->next,
-					    lnk);
-				fibril_mutex_unlock(&unused_lock);
-				return;
-			}
-			if (index > f->first) {
-				n = malloc(sizeof(freed_t));
-				/* TODO: sleep until allocation succeeds */
-				assert(n);
-				link_initialize(&n->link);
-				n->first = index;
-				n->last = index;
-				list_insert_before(&n->link, lnk);
-				fibril_mutex_unlock(&unused_lock);
-				return;
-			}
-
-		}
-		/* The index will form the last interval. */
-		n = malloc(sizeof(freed_t));
-		/* TODO: sleep until allocation succeeds */
-		assert(n);
-		link_initialize(&n->link);
-		n->first = index;
-		n->last = index;
-		list_append(&n->link, &u->freed_list);
-	}
-	fibril_mutex_unlock(&unused_lock);
-}
-
-static int exfat_idx_create(exfat_idx_t **fidxp, service_id_t service_id)
-{
-	exfat_idx_t *fidx;
-
-	fidx = (exfat_idx_t *) malloc(sizeof(exfat_idx_t));
-	if (!fidx) 
-		return ENOMEM;
-	if (!exfat_index_alloc(service_id, &fidx->index)) {
-		free(fidx);
-		return ENOSPC;
-	}
-		
-	link_initialize(&fidx->uph_link);
-	link_initialize(&fidx->uih_link);
-	fibril_mutex_initialize(&fidx->lock);
-	fidx->service_id = service_id;
-	fidx->pfc = 0;	/* no parent yet */
-	fidx->pdi = 0;
-	fidx->nodep = NULL;
-
-	*fidxp = fidx;
-	return EOK;
-}
-
-int exfat_idx_get_new(exfat_idx_t **fidxp, service_id_t service_id)
-{
-	exfat_idx_t *fidx;
-	int rc;
-
-	fibril_mutex_lock(&used_lock);
-	rc = exfat_idx_create(&fidx, service_id);
-	if (rc != EOK) {
-		fibril_mutex_unlock(&used_lock);
-		return rc;
-	}
-		
-	unsigned long ikey[] = {
-		[UIH_SID_KEY] = service_id,
-		[UIH_INDEX_KEY] = fidx->index,
-	};
-	
-	hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
-	fibril_mutex_lock(&fidx->lock);
-	fibril_mutex_unlock(&used_lock);
-
-	*fidxp = fidx;
-	return EOK;
-}
-
-exfat_idx_t *
-exfat_idx_get_by_pos(service_id_t service_id, exfat_cluster_t pfc, unsigned pdi)
-{
-	exfat_idx_t *fidx;
-	link_t *l;
-	unsigned long pkey[] = {
-		[UPH_SID_KEY] = service_id,
-		[UPH_PFC_KEY] = pfc,
-		[UPH_PDI_KEY] = pdi,
-	};
-
-	fibril_mutex_lock(&used_lock);
-	l = hash_table_find(&up_hash, pkey);
-	if (l) {
-		fidx = hash_table_get_instance(l, exfat_idx_t, uph_link);
-	} else {
-		int rc;
-
-		rc = exfat_idx_create(&fidx, service_id);
-		if (rc != EOK) {
-			fibril_mutex_unlock(&used_lock);
-			return NULL;
-		}
-		
-		unsigned long ikey[] = {
-			[UIH_SID_KEY] = service_id,
-			[UIH_INDEX_KEY] = fidx->index,
-		};
-	
-		fidx->pfc = pfc;
-		fidx->pdi = pdi;
-
-		hash_table_insert(&up_hash, pkey, &fidx->uph_link);
-		hash_table_insert(&ui_hash, ikey, &fidx->uih_link);
-	}
-	fibril_mutex_lock(&fidx->lock);
-	fibril_mutex_unlock(&used_lock);
-
-	return fidx;
-}
-
-void exfat_idx_hashin(exfat_idx_t *idx)
-{
-	unsigned long pkey[] = {
-		[UPH_SID_KEY] = idx->service_id,
-		[UPH_PFC_KEY] = idx->pfc,
-		[UPH_PDI_KEY] = idx->pdi,
-	};
-
-	fibril_mutex_lock(&used_lock);
-	hash_table_insert(&up_hash, pkey, &idx->uph_link);
-	fibril_mutex_unlock(&used_lock);
-}
-
-void exfat_idx_hashout(exfat_idx_t *idx)
-{
-	unsigned long pkey[] = {
-		[UPH_SID_KEY] = idx->service_id,
-		[UPH_PFC_KEY] = idx->pfc,
-		[UPH_PDI_KEY] = idx->pdi,
-	};
-
-	fibril_mutex_lock(&used_lock);
-	hash_table_remove(&up_hash, pkey, 3);
-	fibril_mutex_unlock(&used_lock);
-}
-
-exfat_idx_t *
-exfat_idx_get_by_index(service_id_t service_id, fs_index_t index)
-{
-	exfat_idx_t *fidx = NULL;
-	link_t *l;
-	unsigned long ikey[] = {
-		[UIH_SID_KEY] = service_id,
-		[UIH_INDEX_KEY] = index,
-	};
-
-	fibril_mutex_lock(&used_lock);
-	l = hash_table_find(&ui_hash, ikey);
-	if (l) {
-		fidx = hash_table_get_instance(l, exfat_idx_t, uih_link);
-		fibril_mutex_lock(&fidx->lock);
-	}
-	fibril_mutex_unlock(&used_lock);
-
-	return fidx;
-}
-
-/** Destroy the index structure.
- *
- * @param idx		The index structure to be destroyed.
- */
-void exfat_idx_destroy(exfat_idx_t *idx)
-{
-	unsigned long ikey[] = {
-		[UIH_SID_KEY] = idx->service_id,
-		[UIH_INDEX_KEY] = idx->index,
-	};
-	service_id_t service_id = idx->service_id;
-	fs_index_t index = idx->index;
-
-	/* TODO: assert(idx->pfc == FAT_CLST_RES0); */
-	assert(idx->pfc == 0);
-
-	fibril_mutex_lock(&used_lock);
-	/*
-	 * Since we can only free unlinked nodes, the index structure is not
-	 * present in the position hash (uph). We therefore hash it out from
-	 * the index hash only.
-	 */
-	hash_table_remove(&ui_hash, ikey, 2);
-	fibril_mutex_unlock(&used_lock);
-	/* Release the VFS index. */
-	exfat_index_free(service_id, index);
-	/* The index structure itself is freed in idx_remove_callback(). */
-}
-
-int exfat_idx_init(void)
-{
-	if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops)) 
-		return ENOMEM;
-	if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) {
-		hash_table_destroy(&up_hash);
-		return ENOMEM;
-	}
-	return EOK;
-}
-
-void exfat_idx_fini(void)
-{
-	/* We assume the hash tables are empty. */
-	hash_table_destroy(&up_hash);
-	hash_table_destroy(&ui_hash);
-}
-
-int exfat_idx_init_by_service_id(service_id_t service_id)
-{
-	unused_t *u;
-	int rc = EOK;
-
-	u = (unused_t *) malloc(sizeof(unused_t));
-	if (!u)
-		return ENOMEM;
-	unused_initialize(u, service_id);
-	fibril_mutex_lock(&unused_lock);
-	if (!unused_find(service_id, false)) {
-		list_append(&u->link, &unused_list);
-	} else {
-		free(u);
-		rc = EEXIST;
-	}
-	fibril_mutex_unlock(&unused_lock);
-	return rc;
-}
-
-void exfat_idx_fini_by_service_id(service_id_t service_id)
-{
-	unsigned long ikey[] = {
-		[UIH_SID_KEY] = service_id 
-	};
-	unsigned long pkey[] = {
-		[UPH_SID_KEY] = service_id 
-	};
-
-	/*
-	 * Remove this instance's index structure from up_hash and ui_hash.
-	 * Process up_hash first and ui_hash second because the index structure
-	 * is actually removed in idx_remove_callback(). 
-	 */
-	fibril_mutex_lock(&used_lock);
-	hash_table_remove(&up_hash, pkey, 1);
-	hash_table_remove(&ui_hash, ikey, 1);
-	fibril_mutex_unlock(&used_lock);
-
-	/*
-	 * Free the unused and freed structures for this instance.
-	 */
-	unused_t *u = unused_find(service_id, true);
-	assert(u);
-	list_remove(&u->link);
-	fibril_mutex_unlock(&unused_lock);
-
-	while (!list_empty(&u->freed_list)) {
-		freed_t *f;
-		f = list_get_instance(list_first(&u->freed_list), freed_t, link);
-		list_remove(&f->link);
-		free(f);
-	}
-	free(u); 
-}
-
-/**
- * @}
- */ 
Index: pace/srv/fs/exfat/exfat_ops.c
===================================================================
--- uspace/srv/fs/exfat/exfat_ops.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,1482 +1,0 @@
-/*
- * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */
-
-/**
- * @file	exfat_ops.c
- * @brief	Implementation of VFS operations for the exFAT file system server.
- */
-
-#include "exfat.h"
-#include "exfat_fat.h"
-#include "exfat_dentry.h"
-#include "exfat_directory.h"
-#include "exfat_bitmap.h"
-#include "../../vfs/vfs.h"
-#include <libfs.h>
-#include <libblock.h>
-#include <ipc/services.h>
-#include <ipc/loc.h>
-#include <macros.h>
-#include <async.h>
-#include <errno.h>
-#include <str.h>
-#include <byteorder.h>
-#include <adt/hash_table.h>
-#include <adt/list.h>
-#include <assert.h>
-#include <fibril_synch.h>
-#include <sys/mman.h>
-#include <align.h>
-#include <malloc.h>
-#include <stdio.h>
-
-/** Mutex protecting the list of cached free FAT nodes. */
-static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
-
-/** List of cached free FAT nodes. */
-static LIST_INITIALIZE(ffn_list);
-
-/*
- * Forward declarations of FAT libfs operations.
- */
-
-static int exfat_root_get(fs_node_t **, service_id_t);
-static int exfat_match(fs_node_t **, fs_node_t *, const char *);
-static int exfat_node_get(fs_node_t **, service_id_t, fs_index_t);
-static int exfat_node_open(fs_node_t *);
-/* static int exfat_node_put(fs_node_t *); */
-static int exfat_create_node(fs_node_t **, service_id_t, int);
-static int exfat_destroy_node(fs_node_t *);
-static int exfat_link(fs_node_t *, fs_node_t *, const char *);
-static int exfat_unlink(fs_node_t *, fs_node_t *, const char *);
-static int exfat_has_children(bool *, fs_node_t *);
-static fs_index_t exfat_index_get(fs_node_t *);
-static aoff64_t exfat_size_get(fs_node_t *);
-static unsigned exfat_lnkcnt_get(fs_node_t *);
-static bool exfat_is_directory(fs_node_t *);
-static bool exfat_is_file(fs_node_t *node);
-static service_id_t exfat_device_get(fs_node_t *node);
-
-/*
- * Helper functions.
- */
-static void exfat_node_initialize(exfat_node_t *node)
-{
-	fibril_mutex_initialize(&node->lock);
-	node->bp = NULL;
-	node->idx = NULL;
-	node->type = EXFAT_UNKNOW;
-	link_initialize(&node->ffn_link);
-	node->size = 0;
-	node->lnkcnt = 0;
-	node->refcnt = 0;
-	node->dirty = false;
-	node->fragmented = false;
-	node->lastc_cached_valid = false;
-	node->lastc_cached_value = 0;
-	node->currc_cached_valid = false;
-	node->currc_cached_bn = 0;
-	node->currc_cached_value = 0;
-}
-
-static int exfat_node_sync(exfat_node_t *node)
-{
-	int rc;
-	exfat_directory_t di;
-	exfat_file_dentry_t df;
-	exfat_stream_dentry_t ds;
-
-	if (!(node->type == EXFAT_DIRECTORY || node->type == EXFAT_FILE))
-		return EOK;
-
-	if (node->type == EXFAT_DIRECTORY)
-		df.attr = EXFAT_ATTR_SUBDIR;
-	else
-		df.attr = 0;
-
-	ds.firstc = node->firstc;
-	if (node->size == 0 && node->firstc == 0) {
-		ds.flags = 0;
-	} else {
-		ds.flags = 1;
-		ds.flags |= (!node->fragmented << 1);
-	}
-	ds.valid_data_size = node->size;
-	ds.data_size = node->size;
-
-	exfat_directory_open_parent(&di, node->idx->service_id, node->idx->pfc, 
-	    node->idx->parent_fragmented);
-	rc = exfat_directory_seek(&di, node->idx->pdi);
-	if (rc != EOK) {
-		(void) exfat_directory_close(&di);
-		return rc;
-	}
-
-	rc = exfat_directory_sync_file(&di, &df, &ds);
-	if (rc != EOK) {
-		(void) exfat_directory_close(&di);
-		return rc;
-	}
-	return exfat_directory_close(&di);
-}
-
-static int exfat_node_fini_by_service_id(service_id_t service_id)
-{
-	exfat_node_t *nodep;
-	int rc;
-
-	/*
-	 * We are called from fat_unmounted() and assume that there are already
-	 * no nodes belonging to this instance with non-zero refcount. Therefore
-	 * it is sufficient to clean up only the FAT free node list.
-	 */
-
-restart:
-	fibril_mutex_lock(&ffn_mutex);
-	list_foreach(ffn_list, lnk) {
-		nodep = list_get_instance(lnk, exfat_node_t, ffn_link);
-		if (!fibril_mutex_trylock(&nodep->lock)) {
-			fibril_mutex_unlock(&ffn_mutex);
-			goto restart;
-		}
-		if (!fibril_mutex_trylock(&nodep->idx->lock)) {
-			fibril_mutex_unlock(&nodep->lock);
-			fibril_mutex_unlock(&ffn_mutex);
-			goto restart;
-		}
-		if (nodep->idx->service_id != service_id) {
-			fibril_mutex_unlock(&nodep->idx->lock);
-			fibril_mutex_unlock(&nodep->lock);
-			continue;
-		}
-
-		list_remove(&nodep->ffn_link);
-		fibril_mutex_unlock(&ffn_mutex);
-
-		/*
-		 * We can unlock the node and its index structure because we are
-		 * the last player on this playground and VFS is preventing new
-		 * players from entering.
-		 */
-		fibril_mutex_unlock(&nodep->idx->lock);
-		fibril_mutex_unlock(&nodep->lock);
-
-		if (nodep->dirty) {
-			rc = exfat_node_sync(nodep);
-			if (rc != EOK)
-				return rc;
-		}
-		nodep->idx->nodep = NULL;
-		free(nodep->bp);
-		free(nodep);
-
-		/* Need to restart because we changed the ffn_list. */
-		goto restart;
-	}
-	fibril_mutex_unlock(&ffn_mutex);
-
-	return EOK;
-}
-
-static int exfat_node_get_new(exfat_node_t **nodepp)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	int rc;
-
-	fibril_mutex_lock(&ffn_mutex);
-	if (!list_empty(&ffn_list)) {
-		/* Try to use a cached free node structure. */
-		exfat_idx_t *idxp_tmp;
-		nodep = list_get_instance(list_first(&ffn_list), exfat_node_t,
-		    ffn_link);
-		if (!fibril_mutex_trylock(&nodep->lock))
-			goto skip_cache;
-		idxp_tmp = nodep->idx;
-		if (!fibril_mutex_trylock(&idxp_tmp->lock)) {
-			fibril_mutex_unlock(&nodep->lock);
-			goto skip_cache;
-		}
-		list_remove(&nodep->ffn_link);
-		fibril_mutex_unlock(&ffn_mutex);
-		if (nodep->dirty) {
-			rc = exfat_node_sync(nodep);
-			if (rc != EOK) {
-				idxp_tmp->nodep = NULL;
-				fibril_mutex_unlock(&nodep->lock);
-				fibril_mutex_unlock(&idxp_tmp->lock);
-				free(nodep->bp);
-				free(nodep);
-				return rc;
-			}
-		}
-		idxp_tmp->nodep = NULL;
-		fibril_mutex_unlock(&nodep->lock);
-		fibril_mutex_unlock(&idxp_tmp->lock);
-		fn = FS_NODE(nodep);
-	} else {
-skip_cache:
-		/* Try to allocate a new node structure. */
-		fibril_mutex_unlock(&ffn_mutex);
-		fn = (fs_node_t *)malloc(sizeof(fs_node_t));
-		if (!fn)
-			return ENOMEM;
-		nodep = (exfat_node_t *)malloc(sizeof(exfat_node_t));
-		if (!nodep) {
-			free(fn);
-			return ENOMEM;
-		}
-	}
-	exfat_node_initialize(nodep);
-	fs_node_initialize(fn);
-	fn->data = nodep;
-	nodep->bp = fn;
-
-	*nodepp = nodep;
-	return EOK;
-}
-
-static int exfat_node_get_new_by_pos(exfat_node_t **nodepp, 
-    service_id_t service_id, exfat_cluster_t pfc, unsigned pdi)
-{
-	exfat_idx_t *idxp = exfat_idx_get_by_pos(service_id, pfc, pdi);
-	if (!idxp)
-		return ENOMEM;
-	if (exfat_node_get_new(nodepp) != EOK)
-		return ENOMEM;
-	(*nodepp)->idx = idxp;
-	idxp->nodep = *nodepp;
-	return EOK;
-}
-
-
-/** Internal version of exfat_node_get().
- *
- * @param idxp		Locked index structure.
- */
-static int exfat_node_get_core(exfat_node_t **nodepp, exfat_idx_t *idxp)
-{
-	exfat_dentry_t *d;
-	exfat_node_t *nodep = NULL;
-	exfat_directory_t di;
-	int rc;
-
-	if (idxp->nodep) {
-		/*
-		 * We are lucky.
-		 * The node is already instantiated in memory.
-		 */
-		fibril_mutex_lock(&idxp->nodep->lock);
-		if (!idxp->nodep->refcnt++) {
-			fibril_mutex_lock(&ffn_mutex);
-			list_remove(&idxp->nodep->ffn_link);
-			fibril_mutex_unlock(&ffn_mutex);
-		}
-		fibril_mutex_unlock(&idxp->nodep->lock);
-		*nodepp = idxp->nodep;
-		return EOK;
-	}
-
-	/*
-	 * We must instantiate the node from the file system.
-	 */
-
-	assert(idxp->pfc);
-
-	rc = exfat_node_get_new(&nodep);
-	if (rc != EOK)
-		return rc;
-
-	exfat_directory_open_parent(&di, idxp->service_id, idxp->pfc, 
-	    idxp->parent_fragmented);
-	rc = exfat_directory_seek(&di, idxp->pdi);
-	if (rc != EOK) {
-		(void) exfat_directory_close(&di);
-		(void) exfat_node_put(FS_NODE(nodep));
-		return rc;
-	}
-	rc = exfat_directory_get(&di, &d);
-	if (rc != EOK) {
-		(void) exfat_directory_close(&di);
-		(void) exfat_node_put(FS_NODE(nodep));
-		return rc;
-	}
-
-	switch (exfat_classify_dentry(d)) {
-	case EXFAT_DENTRY_FILE:
-		nodep->type = (uint16_t_le2host(d->file.attr) & EXFAT_ATTR_SUBDIR)? 
-		    EXFAT_DIRECTORY : EXFAT_FILE;
-		rc = exfat_directory_next(&di);
-		if (rc != EOK) {
-			(void) exfat_directory_close(&di);
-			(void) exfat_node_put(FS_NODE(nodep));
-			return rc;
-		}
-		rc = exfat_directory_get(&di, &d);
-		if (rc != EOK) {
-			(void) exfat_directory_close(&di);
-			(void) exfat_node_put(FS_NODE(nodep));
-			return rc;
-		}
-		nodep->firstc = uint32_t_le2host(d->stream.firstc);
-		nodep->size = uint64_t_le2host(d->stream.data_size);
-		nodep->fragmented = (d->stream.flags & 0x02) == 0;
-		break;
-	case EXFAT_DENTRY_BITMAP:
-		nodep->type = EXFAT_BITMAP;
-		nodep->firstc = uint32_t_le2host(d->bitmap.firstc);
-		nodep->size = uint64_t_le2host(d->bitmap.size);
-		nodep->fragmented = true;
-		break;
-	case EXFAT_DENTRY_UCTABLE:
-		nodep->type = EXFAT_UCTABLE;
-		nodep->firstc = uint32_t_le2host(d->uctable.firstc);
-		nodep->size = uint64_t_le2host(d->uctable.size);
-		nodep->fragmented = true;
-		break;
-	default:
-	case EXFAT_DENTRY_SKIP:
-	case EXFAT_DENTRY_LAST:
-	case EXFAT_DENTRY_FREE:
-	case EXFAT_DENTRY_VOLLABEL:
-	case EXFAT_DENTRY_GUID:
-	case EXFAT_DENTRY_STREAM:
-	case EXFAT_DENTRY_NAME:
-		(void) exfat_directory_close(&di);
-		(void) exfat_node_put(FS_NODE(nodep));
-		return ENOENT;
-	}
-
-	nodep->lnkcnt = 1;
-	nodep->refcnt = 1;
-
-	rc = exfat_directory_close(&di);
-	if (rc != EOK) {
-		(void) exfat_node_put(FS_NODE(nodep));
-		return rc;
-	}
-
-	/* Link the idx structure with the node structure. */
-	nodep->idx = idxp;
-	idxp->nodep = nodep;
-
-	*nodepp = nodep;
-	return EOK;
-}
-
-int exfat_node_expand(service_id_t service_id, exfat_node_t *nodep, exfat_cluster_t clusters)
-{
-	exfat_bs_t *bs;
-	int rc;
-	bs = block_bb_get(service_id);
-
-	if (!nodep->fragmented) {
-		rc = bitmap_append_clusters(bs, nodep, clusters);
-		if (rc != ENOSPC)
-			return rc;
-		if (rc == ENOSPC) {
-			nodep->fragmented = true;
-			nodep->dirty = true;		/* need to sync node */
-			rc = bitmap_replicate_clusters(bs, nodep);
-			if (rc != EOK)
-				return rc;
-		}
-	}
-
-	/* If we cant linear expand the node, we should use FAT instead */
-	exfat_cluster_t mcl, lcl;
-
-	/* create an independent chain of nclsts clusters in all FATs */
-	rc = exfat_alloc_clusters(bs, service_id, clusters, &mcl, &lcl);
-	if (rc != EOK)
-		return rc;
-	rc = exfat_zero_cluster(bs, service_id, mcl);
-	if (rc != EOK) {
-		(void) exfat_free_clusters(bs, service_id, mcl);
-		return rc;
-	}
-	/*
-	 * Append the cluster chain starting in mcl to the end of the
-	 * node's cluster chain.
-	 */
-	rc = exfat_append_clusters(bs, nodep, mcl, lcl);
-	if (rc != EOK) {
-		(void) exfat_free_clusters(bs, service_id, mcl);
-		return rc;
-	}
-
-	return EOK;
-}
-
-static int exfat_node_shrink(service_id_t service_id, exfat_node_t *nodep, aoff64_t size)
-{
-	exfat_bs_t *bs;
-	int rc;
-	bs = block_bb_get(service_id);
-
-	if (!nodep->fragmented) {
-		exfat_cluster_t clsts, prev_clsts, new_clsts;
-		prev_clsts = ROUND_UP(nodep->size, BPC(bs)) / BPC(bs);
-		new_clsts =  ROUND_UP(size, BPC(bs)) / BPC(bs);
-
-		assert(new_clsts < prev_clsts);
-
-		clsts = prev_clsts - new_clsts;
-		rc = bitmap_free_clusters(bs, nodep, clsts);
-		if (rc != EOK)
-			return rc;
-	} else {
-		/*
-		 * The node will be shrunk, clusters will be deallocated.
-		 */
-		if (size == 0) {
-			rc = exfat_chop_clusters(bs, nodep, 0);
-			if (rc != EOK)
-				return rc;
-		} else {
-			exfat_cluster_t lastc;
-			rc = exfat_cluster_walk(bs, service_id, nodep->firstc,
-			    &lastc, NULL, (size - 1) / BPC(bs));
-			if (rc != EOK)
-				return rc;
-			rc = exfat_chop_clusters(bs, nodep, lastc);
-			if (rc != EOK)
-				return rc;
-		}
-	}
-
-	nodep->size = size;
-	nodep->dirty = true;		/* need to sync node */
-	return EOK;
-}
-
-
-/*
- * EXFAT libfs operations.
- */
-
-int exfat_root_get(fs_node_t **rfn, service_id_t service_id)
-{
-	return exfat_node_get(rfn, service_id, EXFAT_ROOT_IDX);
-}
-
-int exfat_bitmap_get(fs_node_t **rfn, service_id_t service_id)
-{
-	return exfat_node_get(rfn, service_id, EXFAT_BITMAP_IDX);
-}
-
-int exfat_uctable_get(fs_node_t **rfn, service_id_t service_id)
-{
-	return exfat_node_get(rfn, service_id, EXFAT_UCTABLE_IDX);
-}
-
-
-int exfat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
-{
-	exfat_node_t *parentp = EXFAT_NODE(pfn);
-	char name[EXFAT_FILENAME_LEN+1];
-	exfat_file_dentry_t df;
-	exfat_stream_dentry_t ds;
-	service_id_t service_id;
-	int rc;
-
-	fibril_mutex_lock(&parentp->idx->lock);
-	service_id = parentp->idx->service_id;
-	fibril_mutex_unlock(&parentp->idx->lock);
-	
-	exfat_directory_t di;
-	rc = exfat_directory_open(parentp, &di);
-	if (rc != EOK)
-		return rc;
-
-	while (exfat_directory_read_file(&di, name, EXFAT_FILENAME_LEN, 
-	    &df, &ds) == EOK) {
-		if (stricmp(name, component) == 0) {
-			/* hit */
-			exfat_node_t *nodep;
-			aoff64_t o = di.pos % (BPS(di.bs) / sizeof(exfat_dentry_t));
-			exfat_idx_t *idx = exfat_idx_get_by_pos(service_id,
-				parentp->firstc, di.bnum * DPS(di.bs) + o);
-			if (!idx) {
-				/*
-				 * Can happen if memory is low or if we
-				 * run out of 32-bit indices.
-				 */
-				rc = exfat_directory_close(&di);
-				return (rc == EOK) ? ENOMEM : rc;
-			}
-			rc = exfat_node_get_core(&nodep, idx);
-			fibril_mutex_unlock(&idx->lock);
-			if (rc != EOK) {
-				(void) exfat_directory_close(&di);
-				return rc;
-			}
-			*rfn = FS_NODE(nodep);
-			rc = exfat_directory_close(&di);
-			if (rc != EOK)
-				(void) exfat_node_put(*rfn);
-			return rc;
-		} else {
-			rc = exfat_directory_next(&di);
-			if (rc != EOK)
-				break;
-		}
-	}
-	(void) exfat_directory_close(&di);
-	*rfn = NULL;
-	return EOK;
-}
-
-/** Instantiate a exFAT in-core node. */
-int exfat_node_get(fs_node_t **rfn, service_id_t service_id, fs_index_t index)
-{
-	exfat_node_t *nodep;
-	exfat_idx_t *idxp;
-	int rc;
-
-	idxp = exfat_idx_get_by_index(service_id, index);
-	if (!idxp) {
-		*rfn = NULL;
-		return EOK;
-	}
-	/* idxp->lock held */
-	rc = exfat_node_get_core(&nodep, idxp);
-	fibril_mutex_unlock(&idxp->lock);
-	if (rc == EOK)
-		*rfn = FS_NODE(nodep);
-	return rc;
-}
-
-int exfat_node_open(fs_node_t *fn)
-{
-	/*
-	 * Opening a file is stateless, nothing
-	 * to be done here.
-	 */
-	return EOK;
-}
-
-int exfat_node_put(fs_node_t *fn)
-{
-	exfat_node_t *nodep = EXFAT_NODE(fn);
-	bool destroy = false;
-
-	fibril_mutex_lock(&nodep->lock);
-	if (!--nodep->refcnt) {
-		if (nodep->idx) {
-			fibril_mutex_lock(&ffn_mutex);
-			list_append(&nodep->ffn_link, &ffn_list);
-			fibril_mutex_unlock(&ffn_mutex);
-		} else {
-			/*
-			 * The node does not have any index structure associated
-			 * with itself. This can only mean that we are releasing
-			 * the node after a failed attempt to allocate the index
-			 * structure for it.
-			 */
-			destroy = true;
-		}
-	}
-	fibril_mutex_unlock(&nodep->lock);
-	if (destroy) {
-		free(nodep->bp);
-		free(nodep);
-	}
-	return EOK;
-}
-
-int exfat_create_node(fs_node_t **rfn, service_id_t service_id, int flags)
-{
-	exfat_idx_t *idxp;
-	exfat_node_t *nodep;
-	exfat_bs_t *bs;
-	int rc;
-
-	bs = block_bb_get(service_id);
-	rc = exfat_node_get_new(&nodep);
-	if (rc != EOK)
-		return rc;
-
-	rc = exfat_idx_get_new(&idxp, service_id);
-	if (rc != EOK) {
-		(void) exfat_node_put(FS_NODE(nodep));
-		return rc;
-	}
-
-	nodep->firstc = 0;
-	nodep->size = 0;
-	nodep->fragmented = false;
-	nodep->lnkcnt = 0;	/* not linked anywhere */
-	nodep->refcnt = 1;
-	nodep->dirty = true;
-
-	nodep->idx = idxp;
-	idxp->nodep = nodep;
-	fibril_mutex_unlock(&idxp->lock);
-
-	if (flags & L_DIRECTORY) {
-		nodep->type = EXFAT_DIRECTORY;
-		rc = exfat_node_expand(service_id, nodep, 1);
-		if (rc != EOK) {
-			(void) exfat_node_put(FS_NODE(nodep));
-			return rc;
-		}
-		nodep->size = BPC(bs);
-	} else {
-		nodep->type = EXFAT_FILE;
-	}
-
-	*rfn = FS_NODE(nodep);
-	return EOK;
-}
-
-int exfat_destroy_node(fs_node_t *fn)
-{
-	exfat_node_t *nodep = EXFAT_NODE(fn);
-	exfat_bs_t *bs;
-	bool has_children;
-	int rc;
-
-	/*
-	 * The node is not reachable from the file system. This means that the
-	 * link count should be zero and that the index structure cannot be
-	 * found in the position hash. Obviously, we don't need to lock the node
-	 * nor its index structure.
-	 */
-	assert(nodep->lnkcnt == 0);
-
-	/*
-	 * The node may not have any children.
-	 */
-	rc = exfat_has_children(&has_children, fn);
-	if (rc != EOK)
-		return rc;
-	assert(!has_children);
-
-	bs = block_bb_get(nodep->idx->service_id);
-	if (nodep->firstc != 0) {
-		assert(nodep->size);
-		/* Free all clusters allocated to the node. */
-		if (nodep->fragmented)
-			rc = exfat_free_clusters(bs, nodep->idx->service_id,
-				nodep->firstc);
-		else
-			rc = bitmap_free_clusters(bs, nodep, 
-			    ROUND_UP(nodep->size, BPC(bs)) / BPC(bs));
-	} 
-
-	exfat_idx_destroy(nodep->idx);
-	free(nodep->bp);
-	free(nodep);
-	return rc;
-}
-
-int exfat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)
-{
-	exfat_node_t *parentp = EXFAT_NODE(pfn);
-	exfat_node_t *childp = EXFAT_NODE(cfn);
-	exfat_directory_t di;
-	int rc;
-
-	fibril_mutex_lock(&childp->lock);
-	if (childp->lnkcnt == 1) {
-		/*
-		 * We don't support multiple hard links.
-		 */
-		fibril_mutex_unlock(&childp->lock);
-		return EMLINK;
-	}
-	assert(childp->lnkcnt == 0);
-	fibril_mutex_unlock(&childp->lock);
-
-	if (!exfat_valid_name(name))
-		return ENOTSUP;
-
-	fibril_mutex_lock(&parentp->idx->lock);
-	rc = exfat_directory_open(parentp, &di);
-	if (rc != EOK)
-		return rc;
-	/*
-	 * At this point we only establish the link between the parent and the
-	 * child.  The dentry, except of the name and the extension, will remain
-	 * uninitialized until the corresponding node is synced. Thus the valid
-	 * dentry data is kept in the child node structure.
-	 */
-	rc = exfat_directory_write_file(&di, name);
-	if (rc!=EOK)
-		return rc;
-	rc = exfat_directory_close(&di);
-	if (rc!=EOK)
-		return rc;
-
-	fibril_mutex_unlock(&parentp->idx->lock);
-	if (rc != EOK)
-		return rc;
-
-	fibril_mutex_lock(&childp->idx->lock);
-
-
-	childp->idx->pfc = parentp->firstc;
-	childp->idx->parent_fragmented = parentp->fragmented;
-	childp->idx->pdi = di.pos;
-	fibril_mutex_unlock(&childp->idx->lock);
-
-	fibril_mutex_lock(&childp->lock);
-	childp->lnkcnt = 1;
-	childp->dirty = true;		/* need to sync node */
-	fibril_mutex_unlock(&childp->lock);
-
-	/*
-	 * Hash in the index structure into the position hash.
-	 */
-	exfat_idx_hashin(childp->idx);
-
-	return EOK;
-
-}
-
-int exfat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
-{
-	exfat_node_t *parentp = EXFAT_NODE(pfn);
-	exfat_node_t *childp = EXFAT_NODE(cfn);
-	bool has_children;
-	int rc;
-
-	if (!parentp)
-		return EBUSY;
-
-	rc = exfat_has_children(&has_children, cfn);
-	if (rc != EOK)
-		return rc;
-	if (has_children)
-		return ENOTEMPTY;
-
-	fibril_mutex_lock(&parentp->lock);
-	fibril_mutex_lock(&childp->lock);
-	assert(childp->lnkcnt == 1);
-	fibril_mutex_lock(&childp->idx->lock);
-	
-	exfat_directory_t di;
-	rc = exfat_directory_open(parentp,&di);
-	if (rc != EOK)
-		goto error;
-	rc = exfat_directory_erase_file(&di, childp->idx->pdi);
-	if (rc != EOK)
-		goto error;
-	rc = exfat_directory_close(&di);
-	if (rc != EOK)
-		goto error;
-
-	/* remove the index structure from the position hash */
-	exfat_idx_hashout(childp->idx);
-	/* clear position information */
-	childp->idx->pfc = 0;
-	childp->idx->pdi = 0;
-	fibril_mutex_unlock(&childp->idx->lock);
-	childp->lnkcnt = 0;
-	childp->refcnt++;	/* keep the node in memory until destroyed */
-	childp->dirty = true;
-	fibril_mutex_unlock(&childp->lock);
-	fibril_mutex_unlock(&parentp->lock);
-
-	return EOK;
-
-error:
-	(void) exfat_directory_close(&di);
-	fibril_mutex_unlock(&childp->idx->lock);
-	fibril_mutex_unlock(&childp->lock);
-	fibril_mutex_unlock(&parentp->lock);
-	return rc;
-
-}
-
-int exfat_has_children(bool *has_children, fs_node_t *fn)
-{
-	exfat_directory_t di;
-	exfat_dentry_t *d;
-	exfat_node_t *nodep = EXFAT_NODE(fn);
-	int rc;
-
-	*has_children = false;
-
-	if (nodep->type != EXFAT_DIRECTORY)
-		return EOK;
-
-	fibril_mutex_lock(&nodep->idx->lock);
-
-	rc = exfat_directory_open(nodep, &di);
-	if (rc != EOK) {
-		fibril_mutex_unlock(&nodep->idx->lock);
-		return rc;
-	}
-
-	do {
-		rc = exfat_directory_get(&di, &d);
-		if (rc != EOK) {
-			(void) exfat_directory_close(&di);
-			fibril_mutex_unlock(&nodep->idx->lock);
-			return rc;
-		}
-		switch (exfat_classify_dentry(d)) {
-		case EXFAT_DENTRY_SKIP:
-		case EXFAT_DENTRY_FREE:
-			continue;
-		case EXFAT_DENTRY_LAST:
-			*has_children = false;
-			goto exit;
-		default:
-			*has_children = true;
-			goto exit;
-		}
-	} while (exfat_directory_next(&di) == EOK);
-
-exit:
-	rc = exfat_directory_close(&di);
-	fibril_mutex_unlock(&nodep->idx->lock);
-	return rc;
-}
-
-
-fs_index_t exfat_index_get(fs_node_t *fn)
-{
-	return EXFAT_NODE(fn)->idx->index;
-}
-
-aoff64_t exfat_size_get(fs_node_t *fn)
-{
-	return EXFAT_NODE(fn)->size;
-}
-
-unsigned exfat_lnkcnt_get(fs_node_t *fn)
-{
-	return EXFAT_NODE(fn)->lnkcnt;
-}
-
-bool exfat_is_directory(fs_node_t *fn)
-{
-	return EXFAT_NODE(fn)->type == EXFAT_DIRECTORY;
-}
-
-bool exfat_is_file(fs_node_t *fn)
-{
-	return EXFAT_NODE(fn)->type == EXFAT_FILE;
-}
-
-service_id_t exfat_device_get(fs_node_t *node)
-{
-	return 0;
-}
-
-
-/** libfs operations */
-libfs_ops_t exfat_libfs_ops = {
-	.root_get = exfat_root_get,
-	.match = exfat_match,
-	.node_get = exfat_node_get,
-	.node_open = exfat_node_open,
-	.node_put = exfat_node_put,
-	.create = exfat_create_node,
-	.destroy = exfat_destroy_node,
-	.link = exfat_link,
-	.unlink = exfat_unlink,
-	.has_children = exfat_has_children,
-	.index_get = exfat_index_get,
-	.size_get = exfat_size_get,
-	.lnkcnt_get = exfat_lnkcnt_get,
-	.is_directory = exfat_is_directory,
-	.is_file = exfat_is_file,
-	.device_get = exfat_device_get
-};
-
-
-/*
- * VFS_OUT operations.
- */
-
-/* Print debug info */
-/*
-static void exfat_fsinfo(exfat_bs_t *bs, service_id_t service_id)
-{
-	printf("exFAT file system mounted\n");
-	printf("Version: %d.%d\n", bs->version.major, bs->version.minor);
-	printf("Volume serial: %d\n", uint32_t_le2host(bs->volume_serial));
-	printf("Volume first sector: %lld\n", VOL_FS(bs));
-	printf("Volume sectors: %lld\n", VOL_CNT(bs));
-	printf("FAT first sector: %d\n", FAT_FS(bs));
-	printf("FAT sectors: %d\n", FAT_CNT(bs));
-	printf("Data first sector: %d\n", DATA_FS(bs));
-	printf("Data sectors: %d\n", DATA_CNT(bs));
-	printf("Root dir first cluster: %d\n", ROOT_FC(bs));
-	printf("Bytes per sector: %d\n", BPS(bs));
-	printf("Sectors per cluster: %d\n", SPC(bs));
-	printf("KBytes per cluster: %d\n", SPC(bs)*BPS(bs)/1024);
-
-	int i, rc;
-	exfat_cluster_t clst;
-	for (i=0; i<=7; i++) {
-		rc = exfat_get_cluster(bs, service_id, i, &clst);
-		if (rc != EOK)
-			return;
-		printf("Clst %d: %x", i, clst);
-		if (i>=2)
-			printf(", Bitmap: %d\n", bitmap_is_free(bs, service_id, i)!=EOK);
-		else
-			printf("\n");
-	}
-}
-*/
- 
-static int
-exfat_mounted(service_id_t service_id, const char *opts, fs_index_t *index,
-    aoff64_t *size, unsigned *linkcnt)
-{
-	int rc;
-	exfat_node_t *rootp=NULL, *bitmapp=NULL, *uctablep=NULL;
-	enum cache_mode cmode;
-	exfat_bs_t *bs;
-
-	/* Check for option enabling write through. */
-	if (str_cmp(opts, "wtcache") == 0)
-		cmode = CACHE_MODE_WT;
-	else
-		cmode = CACHE_MODE_WB;
-
-	/* initialize libblock */
-	rc = block_init(EXCHANGE_SERIALIZE, service_id, BS_SIZE);
-	if (rc != EOK)
-		return rc;
-
-	/* prepare the boot block */
-	rc = block_bb_read(service_id, BS_BLOCK);
-	if (rc != EOK) {
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* get the buffer with the boot sector */
-	bs = block_bb_get(service_id);
-
-	/* Initialize the block cache */
-	rc = block_cache_init(service_id, BPS(bs), 0 /* XXX */, cmode);
-	if (rc != EOK) {
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Do some simple sanity checks on the file system. */
-	rc = exfat_sanity_check(bs, service_id);
-	if (rc != EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	rc = exfat_idx_init_by_service_id(service_id);
-	if (rc != EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		return rc;
-	}
-
-	/* Initialize the root node. */
-	rc = exfat_node_get_new_by_pos(&rootp, service_id, EXFAT_ROOT_PAR, 
-	    EXFAT_ROOT_POS);
-	if (rc!=EOK) {
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(rootp->idx->index == EXFAT_ROOT_IDX);
-
-	rootp->type = EXFAT_DIRECTORY;
-	rootp->firstc = ROOT_FC(bs);
-	rootp->fragmented = true;
-	rootp->refcnt = 1;
-	rootp->lnkcnt = 0;	/* FS root is not linked */
-
-	uint32_t clusters;
-	rc = exfat_clusters_get(&clusters, bs, service_id, rootp->firstc);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-	rootp->size = BPS(bs) * SPC(bs) * clusters;
-	fibril_mutex_unlock(&rootp->idx->lock);
-
-	/* Open root directory and looking for Bitmap and UC-Table */
-	exfat_directory_t di;
-	exfat_dentry_t *de;
-	rc = exfat_directory_open(rootp, &di);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	/* Initialize the bitmap node. */
-	rc = exfat_directory_find(&di, EXFAT_DENTRY_BITMAP, &de);
-	if (rc != EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_node_get_new_by_pos(&bitmapp, service_id, rootp->firstc, 
-	    di.pos);
-	if (rc!=EOK) {
-		free(rootp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(bitmapp->idx->index == EXFAT_BITMAP_IDX);
-	fibril_mutex_unlock(&bitmapp->idx->lock);
-
-	bitmapp->type = EXFAT_BITMAP;
-	bitmapp->firstc = uint32_t_le2host(de->bitmap.firstc);
-	bitmapp->fragmented = true;
-	bitmapp->idx->parent_fragmented = true;
-	bitmapp->refcnt = 1;
-	bitmapp->lnkcnt = 0;
-	bitmapp->size = uint64_t_le2host(de->bitmap.size);
-
-	/* Initialize the uctable node. */
-	rc = exfat_directory_seek(&di, 0);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_directory_find(&di, EXFAT_DENTRY_UCTABLE, &de);
-	if (rc != EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOTSUP;
-	}
-
-	rc = exfat_node_get_new_by_pos(&uctablep, service_id, rootp->firstc, 
-	    di.pos);
-	if (rc!=EOK) {
-		free(rootp);
-		free(bitmapp);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-	assert(uctablep->idx->index == EXFAT_UCTABLE_IDX);
-	fibril_mutex_unlock(&uctablep->idx->lock);
-
-	uctablep->type = EXFAT_UCTABLE;
-	uctablep->firstc = uint32_t_le2host(de->uctable.firstc);
-	uctablep->fragmented = true;
-	uctablep->idx->parent_fragmented = true;
-	uctablep->refcnt = 1;
-	uctablep->lnkcnt = 0;
-	uctablep->size = uint64_t_le2host(de->uctable.size);
-
-	rc = exfat_directory_close(&di);
-	if (rc!=EOK) {
-		free(rootp);
-		free(bitmapp);
-		free(uctablep);
-		(void) block_cache_fini(service_id);
-		block_fini(service_id);
-		exfat_idx_fini_by_service_id(service_id);
-		return ENOMEM;
-	}
-
-	/* exfat_fsinfo(bs, service_id); */
-
-	*index = rootp->idx->index;
-	*size = rootp->size;
-	*linkcnt = rootp->lnkcnt;
-	
-	return EOK;
-}
-
-static int exfat_unmounted(service_id_t service_id)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	int rc;
-
-	rc = exfat_root_get(&fn, service_id);
-	if (rc != EOK)
-		return rc;
-	nodep = EXFAT_NODE(fn);
-
-	/*
-	 * We expect exactly two references on the root node. One for the
-	 * fat_root_get() above and one created in fat_mounted().
-	 */
-	if (nodep->refcnt != 2) {
-		(void) exfat_node_put(fn);
-		return EBUSY;
-	}
-
-	/*
-	 * Put the root node and force it to the FAT free node list.
-	 */
-	(void) exfat_node_put(fn);
-	(void) exfat_node_put(fn);
-
-	/*
-	 * Perform cleanup of the node structures, index structures and
-	 * associated data. Write back this file system's dirty blocks and
-	 * stop using libblock for this instance.
-	 */
-	(void) exfat_node_fini_by_service_id(service_id);
-	exfat_idx_fini_by_service_id(service_id);
-	(void) block_cache_fini(service_id);
-	block_fini(service_id);
-
-	return EOK;
-}
-
-static int
-exfat_read(service_id_t service_id, fs_index_t index, aoff64_t pos,
-    size_t *rbytes)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	exfat_bs_t *bs;
-	size_t bytes=0;
-	block_t *b;
-	int rc;
-
-	rc = exfat_node_get(&fn, service_id, index);
-	if (rc != EOK)
-		return rc;
-	if (!fn)
-		return ENOENT;
-	nodep = EXFAT_NODE(fn);
-
-	ipc_callid_t callid;
-	size_t len;
-	if (!async_data_read_receive(&callid, &len)) {
-		exfat_node_put(fn);
-		async_answer_0(callid, EINVAL);
-		return EINVAL;
-	}
-
-	bs = block_bb_get(service_id);
-
-	if (nodep->type == EXFAT_FILE) {
-		/*
-		 * Our strategy for regular file reads is to read one block at
-		 * most and make use of the possibility to return less data than
-		 * requested. This keeps the code very simple.
-		 */
-		if (pos >= nodep->size) {
-			/* reading beyond the EOF */
-			bytes = 0;
-			(void) async_data_read_finalize(callid, NULL, 0);
-		} else {
-			bytes = min(len, BPS(bs) - pos % BPS(bs));
-			bytes = min(bytes, nodep->size - pos);
-			rc = exfat_block_get(&b, bs, nodep, pos / BPS(bs),
-			    BLOCK_FLAGS_NONE);
-			if (rc != EOK) {
-				exfat_node_put(fn);
-				async_answer_0(callid, rc);
-				return rc;
-			}
-			(void) async_data_read_finalize(callid,
-			    b->data + pos % BPS(bs), bytes);
-			rc = block_put(b);
-			if (rc != EOK) {
-				exfat_node_put(fn);
-				return rc;
-			}
-		}
-	} else {
-		if (nodep->type != EXFAT_DIRECTORY) {
-			async_answer_0(callid, ENOTSUP);
-			return ENOTSUP;
-		}
-			
-		aoff64_t spos = pos;
-		char name[EXFAT_FILENAME_LEN+1];
-		exfat_file_dentry_t df;
-		exfat_stream_dentry_t ds;
-
-		assert(nodep->size % BPS(bs) == 0);
-		assert(BPS(bs) % sizeof(exfat_dentry_t) == 0);
-
-		exfat_directory_t di;
-		rc = exfat_directory_open(nodep, &di);
-		if (rc != EOK) goto err;
-		rc = exfat_directory_seek(&di, pos);
-		if (rc != EOK) {
-			(void) exfat_directory_close(&di);
-			goto err;
-		}
-
-		rc = exfat_directory_read_file(&di, name, EXFAT_FILENAME_LEN, &df, &ds);
-		if (rc == EOK) goto hit;
-		if (rc == ENOENT) goto miss;
-
-err:
-		(void) exfat_node_put(fn);
-		async_answer_0(callid, rc);
-		return rc;
-
-miss:
-		rc = exfat_directory_close(&di);
-		if (rc!=EOK)
-			goto err;
-		rc = exfat_node_put(fn);
-		async_answer_0(callid, rc != EOK ? rc : ENOENT);
-		*rbytes = 0;
-		return rc != EOK ? rc : ENOENT;
-
-hit:
-		pos = di.pos;
-		rc = exfat_directory_close(&di);
-		if (rc!=EOK)
-			goto err;
-		(void) async_data_read_finalize(callid, name, str_size(name) + 1);
-		bytes = (pos - spos)+1;
-	}
-
-	rc = exfat_node_put(fn);
-	*rbytes = bytes;
-	return rc;
-}
-
-static int exfat_close(service_id_t service_id, fs_index_t index)
-{
-	return EOK;
-}
-
-static int exfat_sync(service_id_t service_id, fs_index_t index)
-{
-	fs_node_t *fn;
-	int rc = exfat_node_get(&fn, service_id, index);
-	if (rc != EOK)
-		return rc;
-	if (!fn)
-		return ENOENT;
-
-	exfat_node_t *nodep = EXFAT_NODE(fn);
-
-	nodep->dirty = true;
-	rc = exfat_node_sync(nodep);
-
-	exfat_node_put(fn);
-	return rc;
-}
-
-static int
-exfat_write(service_id_t service_id, fs_index_t index, aoff64_t pos,
-    size_t *wbytes, aoff64_t *nsize)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	exfat_bs_t *bs;
-	size_t bytes;
-	block_t *b;
-	aoff64_t boundary;
-	int flags = BLOCK_FLAGS_NONE;
-	int rc;
-
-	rc = exfat_node_get(&fn, service_id, index);
-	if (rc != EOK)
-		return rc;
-	if (!fn)
-		return ENOENT;
-	nodep = EXFAT_NODE(fn);
-
-	ipc_callid_t callid;
-	size_t len;
-	if (!async_data_write_receive(&callid, &len)) {
-		(void) exfat_node_put(fn);
-		async_answer_0(callid, EINVAL);
-		return EINVAL;
-	}
-
-	bs = block_bb_get(service_id);
-
-	/*
-	 * In all scenarios, we will attempt to write out only one block worth
-	 * of data at maximum. There might be some more efficient approaches,
-	 * but this one greatly simplifies fat_write(). Note that we can afford
-	 * to do this because the client must be ready to handle the return
-	 * value signalizing a smaller number of bytes written.
-	 */
-	bytes = min(len, BPS(bs) - pos % BPS(bs));
-	if (bytes == BPS(bs))
-		flags |= BLOCK_FLAGS_NOREAD;
-
-	boundary = ROUND_UP(nodep->size, BPC(bs));
-	if (pos >= boundary) {
-		unsigned nclsts;
-		nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
-		rc = exfat_node_expand(service_id, nodep, nclsts);
-		if (rc != EOK) {
-			/* could not expand node */
-			(void) exfat_node_put(fn);
-			async_answer_0(callid, rc);
-			return rc;
-		}
-	}
-
-	if (pos + bytes > nodep->size) {
-		nodep->size = pos + bytes;
-		nodep->dirty = true;	/* need to sync node */
-	}
-
-	/*
-	 * This is the easier case - we are either overwriting already
-	 * existing contents or writing behind the EOF, but still within
-	 * the limits of the last cluster. The node size may grow to the
-	 * next block size boundary.
-	 */
-	rc = exfat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		async_answer_0(callid, rc);
-		return rc;
-	}
-
-	(void) async_data_write_finalize(callid,
-		b->data + pos % BPS(bs), bytes);
-	b->dirty = true;		/* need to sync block */
-	rc = block_put(b);
-	if (rc != EOK) {
-		(void) exfat_node_put(fn);
-		return rc;
-	}
-
-
-	*wbytes = bytes;
-	*nsize = nodep->size;
-	rc = exfat_node_put(fn);
-	return rc;
-}
-
-static int
-exfat_truncate(service_id_t service_id, fs_index_t index, aoff64_t size)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	exfat_bs_t *bs;
-	int rc;
-
-	rc = exfat_node_get(&fn, service_id, index);
-	if (rc != EOK)
-		return rc;
-	if (!fn)
-		return ENOENT;
-	nodep = EXFAT_NODE(fn);
-
-	bs = block_bb_get(service_id);
-
-	if (nodep->size == size) {
-		rc = EOK;
-	} else if (nodep->size < size) {
-		/*
-		 * The standard says we have the freedom to grow the node.
-		 * For now, we simply return an error.
-		 */
-		rc = EINVAL;
-	} else if (ROUND_UP(nodep->size, BPC(bs)) == ROUND_UP(size, BPC(bs))) {
-		/*
-		 * The node will be shrunk, but no clusters will be deallocated.
-		 */
-		nodep->size = size;
-		nodep->dirty = true;		/* need to sync node */
-		rc = EOK;
-	} else {
-		rc = exfat_node_shrink(service_id, nodep, size);
-	}
-
-	(void) exfat_node_put(fn);
-	return rc;
-}
-
-static int exfat_destroy(service_id_t service_id, fs_index_t index)
-{
-	fs_node_t *fn;
-	exfat_node_t *nodep;
-	int rc;
-
-	rc = exfat_node_get(&fn, service_id, index);
-	if (rc != EOK)
-		return rc;
-	if (!fn)
-		return ENOENT;
-
-	nodep = EXFAT_NODE(fn);
-	/*
-	 * We should have exactly two references. One for the above
-	 * call to fat_node_get() and one from fat_unlink().
-	 */
-	assert(nodep->refcnt == 2);
-
-	rc = exfat_destroy_node(fn);
-	return rc;
-}
-
-vfs_out_ops_t exfat_ops = {
-	.mounted = exfat_mounted,
-	.unmounted = exfat_unmounted,
-	.read = exfat_read,
-	.write = exfat_write,
-	.truncate = exfat_truncate,
-	.close = exfat_close,
-	.destroy = exfat_destroy,
-	.sync = exfat_sync,
-};
-
-
-/**
- * @}
- */
Index: uspace/srv/fs/fat/Makefile
===================================================================
--- uspace/srv/fs/fat/Makefile	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/Makefile	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -39,5 +39,4 @@
 	fat_idx.c \
 	fat_dentry.c \
-	fat_directory.c \
 	fat_fat.c
 
Index: uspace/srv/fs/fat/fat.c
===================================================================
--- uspace/srv/fs/fat/fat.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -2,5 +2,4 @@
  * Copyright (c) 2006 Martin Decky
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
Index: uspace/srv/fs/fat/fat.h
===================================================================
--- uspace/srv/fs/fat/fat.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat.h	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -56,7 +55,5 @@
 #define RSCNT(bs)	uint16_t_le2host((bs)->rscnt)
 #define FATCNT(bs)	(bs)->fatcnt
-#define SF(bs)		(uint16_t_le2host((bs)->sec_per_fat) !=0 ? \
-    uint16_t_le2host((bs)->sec_per_fat) : \
-    uint32_t_le2host(bs->fat32.sectors_per_fat))
+#define SF(bs)		uint16_t_le2host((bs)->sec_per_fat)
 #define RDE(bs)		uint16_t_le2host((bs)->root_ent_max)
 #define TS(bs)		(uint16_t_le2host((bs)->totsec16) != 0 ? \
Index: uspace/srv/fs/fat/fat_dentry.c
===================================================================
--- uspace/srv/fs/fat/fat_dentry.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat_dentry.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -40,7 +39,12 @@
 #include <ctype.h>
 #include <str.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <assert.h>
+
+static bool is_d_char(const char ch)
+{
+	if (isalnum(ch) || ch == '_')
+		return true;
+	else
+		return false;
+}
 
 /** Compare path component with the name read from the dentry.
@@ -76,297 +80,10 @@
 }
 
-void fat_dentry_name_get(const fat_dentry_t *d, char *buf)
-{
-	unsigned int i;
-	
-	for (i = 0; i < FAT_NAME_LEN; i++) {
-		if (d->name[i] == FAT_PAD)
-			break;
-		
-		if (d->name[i] == FAT_DENTRY_E5_ESC)
-			*buf++ = 0xe5;
-		else {
-			if (d->lcase & FAT_LCASE_LOWER_NAME)
-				*buf++ = tolower(d->name[i]);
-			else
-				*buf++ = d->name[i];
-		}
-	}
-	
-	if (d->ext[0] != FAT_PAD)
-		*buf++ = '.';
-	
-	for (i = 0; i < FAT_EXT_LEN; i++) {
-		if (d->ext[i] == FAT_PAD) {
-			*buf = '\0';
-			return;
-		}
-		
-		if (d->ext[i] == FAT_DENTRY_E5_ESC)
-			*buf++ = 0xe5;
-		else {
-			if (d->lcase & FAT_LCASE_LOWER_EXT)
-				*buf++ = tolower(d->ext[i]);
-			else
-				*buf++ = d->ext[i];
-		}
-	}
-	
-	*buf = '\0';
-}
-
-void fat_dentry_name_set(fat_dentry_t *d, const char *name)
-{
-	unsigned int i;
-	const char fake_ext[] = "   ";
-	bool lower_name = true;
-	bool lower_ext = true;
-	
-	for (i = 0; i < FAT_NAME_LEN; i++) {
-		switch ((uint8_t) *name) {
-		case 0xe5:
-			d->name[i] = FAT_DENTRY_E5_ESC;
-			name++;
-			break;
-		case '\0':
-		case '.':
-			d->name[i] = FAT_PAD;
-			break;
-		default:
-			if (isalpha(*name)) {
-				if (!islower(*name))
-					lower_name = false;
-			}
-			
-			d->name[i] = toupper(*name++);
-			break;
-		}
-	}
-	
-	if (*name++ != '.')
-		name = fake_ext;
-	
-	for (i = 0; i < FAT_EXT_LEN; i++) {
-		switch ((uint8_t) *name) {
-		case 0xe5:
-			d->ext[i] = FAT_DENTRY_E5_ESC;
-			name++;
-			break;
-		case '\0':
-			d->ext[i] = FAT_PAD;
-			break;
-		default:
-			if (isalpha(*name)) {
-				if (!islower(*name))
-					lower_ext = false;
-			}
-			
-			d->ext[i] = toupper(*name++);
-			break;
-		}
-	}
-	
-	if (lower_name)
-		d->lcase |= FAT_LCASE_LOWER_NAME;
-	else
-		d->lcase &= ~FAT_LCASE_LOWER_NAME;
-	
-	if (lower_ext)
-		d->lcase |= FAT_LCASE_LOWER_EXT;
-	else
-		d->lcase &= ~FAT_LCASE_LOWER_EXT;
-}
-
-fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d)
-{
-	if (d->attr == FAT_ATTR_LFN) {
-		/* long name entry */
-		if (FAT_LFN_ORDER(d) & FAT_LFN_ERASED)
-			return FAT_DENTRY_FREE;
-		else
-			return FAT_DENTRY_LFN;
-	}
-	if (d->attr & FAT_ATTR_VOLLABEL) {
-		/* volume label entry */
-		return FAT_DENTRY_SKIP;
-	}
-	if (d->name[0] == FAT_DENTRY_ERASED) {
-		/* not-currently-used entry */
-		return FAT_DENTRY_FREE;
-	}
-	if (d->name[0] == FAT_DENTRY_UNUSED) {
-		/* never used entry */
-		return FAT_DENTRY_LAST;
-	}
-	if (d->name[0] == FAT_DENTRY_DOT) {
-		/*
-		 * Most likely '.' or '..'.
-		 * It cannot occur in a regular file name.
-		 */
-		return FAT_DENTRY_SKIP;
-	}
-	return FAT_DENTRY_VALID;
-}
-
-/** Compute checksum of Node name.
- *
- * Returns an unsigned byte checksum computed on an unsigned byte
- * array. The array must be 11 bytes long and is assumed to contain
- * a name stored in the format of a MS-DOS directory entry.
- *
- * @param name		Node name read from the dentry.
- *
- * @return		An 8-bit unsigned checksum of the name.
- */
-uint8_t fat_dentry_chksum(uint8_t *name)
-{
-	uint8_t i, sum=0;
-	for (i=0; i<(FAT_NAME_LEN+FAT_EXT_LEN); i++) {
-		sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + name[i];
-	}
-	return sum;
-}
-
-/** Get number of bytes in a string with size limit.
- *
- * @param str  NULL-terminated (or not) string.
- * @param size Maximum number of bytes to consider.
- *
- * @return Number of bytes in string (without 0 and ff).
- *
- */
-size_t fat_lfn_str_nlength(const uint16_t *str, size_t size)
-{
-	size_t offset = 0;
-
-	while (offset < size) {
-		if (str[offset] == 0 || str[offset] == FAT_LFN_PAD) 
-			break;
-		offset++;
-	}
-	return offset;
-}
-
-/** Get number of bytes in a FAT long entry occuped by characters.
- *
- * @param d FAT long entry.
- *
- * @return Number of bytes.
- *
- */
-size_t fat_lfn_size(const fat_dentry_t *d)
-{
-	size_t size = 0;
-	
-	size += fat_lfn_str_nlength(FAT_LFN_PART1(d), FAT_LFN_PART1_SIZE);
-	size += fat_lfn_str_nlength(FAT_LFN_PART2(d), FAT_LFN_PART2_SIZE);
-	size += fat_lfn_str_nlength(FAT_LFN_PART3(d), FAT_LFN_PART3_SIZE);	
-	
-	return size;
-}
-
-size_t fat_lfn_get_entry(const fat_dentry_t *d, uint16_t *dst, size_t *offset)
-{
-	int i;
-	for (i=FAT_LFN_PART3_SIZE-1; i>=0 && *offset>0; i--) {
-		if (d->lfn.part3[i] == 0 || d->lfn.part3[i] == FAT_LFN_PAD)
-			continue;
-		(*offset)--;
-		dst[(*offset)] = uint16_t_le2host(d->lfn.part3[i]);
-	}
-	for (i=FAT_LFN_PART2_SIZE-1; i>=0 && *offset>0; i--) {
-		if (d->lfn.part2[i] == 0 || d->lfn.part2[i] == FAT_LFN_PAD)
-			continue;
-		(*offset)--;
-		dst[(*offset)] = uint16_t_le2host(d->lfn.part2[i]);
-	}
-	for (i=FAT_LFN_PART1_SIZE-1; i>=0 && *offset>0; i--) {
-		if (d->lfn.part1[i] == 0 || d->lfn.part1[i] == FAT_LFN_PAD)
-			continue;
-		(*offset)--;
-		dst[(*offset)] = uint16_t_le2host(d->lfn.part1[i]);
-	}
-	return *offset;
-}
-
-size_t fat_lfn_set_entry(const uint16_t *src, size_t *offset, size_t size, fat_dentry_t *d)
-{
-	size_t idx;
-	for (idx=0; idx < FAT_LFN_PART1_SIZE; idx++) {
-		if (*offset < size) {
-			d->lfn.part1[idx] = host2uint16_t_le(src[*offset]);
-			(*offset)++;
-		}
-		else
-			d->lfn.part1[idx] = FAT_LFN_PAD;
-	}
-	for (idx=0; idx < FAT_LFN_PART2_SIZE; idx++) {
-		if (*offset < size) {
-			d->lfn.part2[idx] = host2uint16_t_le(src[*offset]);
-			(*offset)++;
-		}
-		else
-			d->lfn.part2[idx] = FAT_LFN_PAD;
-	}
-	for (idx=0; idx < FAT_LFN_PART3_SIZE; idx++) {
-		if (*offset < size) {
-			d->lfn.part3[idx] = host2uint16_t_le(src[*offset]);
-			(*offset)++;
-		}
-		else
-			d->lfn.part3[idx] = FAT_LFN_PAD;
-	}
-
-	if (src[*offset] == 0)
-		offset++;
-	FAT_LFN_ATTR(d) = FAT_ATTR_LFN;
-	d->lfn.type = 0;
-	d->lfn.firstc_lo = 0;
-	
-	return *offset;
-}
-
-void str_to_ascii(char *dst, const char *src, size_t count, uint8_t pad)
-{
-	wchar_t ch;
-	size_t off = 0;
-	size_t i = 0;
-	
-	while (i < count) {
-		if ((ch = str_decode(src, &off, STR_NO_LIMIT)) != 0) {
-			if (ascii_check(ch) & IS_D_CHAR(ch))
-				*dst = toupper(ch);
-			else
-				*dst = pad;
-		}
-		else
-			break;
-
-		dst++;
-		i++;
-	}
-	*dst = '\0';
-}
-
-bool fat_valid_name(const char *name)
-{
-	wchar_t ch;
-	size_t offset=0;
-	bool result = true;
-	
-	while ((ch = str_decode(name, &offset, STR_NO_LIMIT)) != 0) {
-		if (wstr_chr(FAT_STOP_CHARS, ch) != NULL) {
-			result = false;
-			break;
-		}
-	}
-	return result;
-}
-
-bool fat_valid_short_name(const char *name)
+bool fat_dentry_name_verify(const char *name)
 {
 	unsigned int i;
 	unsigned int dot = 0;
 	bool dot_found = false;
+	
 
 	for (i = 0; name[i]; i++) {
@@ -379,5 +96,5 @@
 			}
 		} else {
-			if (!IS_D_CHAR(name[i]))
+			if (!is_d_char(name[i]))
 				return false;
 		}
@@ -397,12 +114,128 @@
 }
 
-size_t utf16_length(const uint16_t *wstr)
-{
-	size_t len = 0;
-	
-	while (*wstr++ != 0)
-		len++;
-	
-	return len;
+void fat_dentry_name_get(const fat_dentry_t *d, char *buf)
+{
+	unsigned int i;
+	
+	for (i = 0; i < FAT_NAME_LEN; i++) {
+		if (d->name[i] == FAT_PAD)
+			break;
+		
+		if (d->name[i] == FAT_DENTRY_E5_ESC)
+			*buf++ = 0xe5;
+		else {
+			if (d->lcase & FAT_LCASE_LOWER_NAME)
+				*buf++ = tolower(d->name[i]);
+			else
+				*buf++ = d->name[i];
+		}
+	}
+	
+	if (d->ext[0] != FAT_PAD)
+		*buf++ = '.';
+	
+	for (i = 0; i < FAT_EXT_LEN; i++) {
+		if (d->ext[i] == FAT_PAD) {
+			*buf = '\0';
+			return;
+		}
+		
+		if (d->ext[i] == FAT_DENTRY_E5_ESC)
+			*buf++ = 0xe5;
+		else {
+			if (d->lcase & FAT_LCASE_LOWER_EXT)
+				*buf++ = tolower(d->ext[i]);
+			else
+				*buf++ = d->ext[i];
+		}
+	}
+	
+	*buf = '\0';
+}
+
+void fat_dentry_name_set(fat_dentry_t *d, const char *name)
+{
+	unsigned int i;
+	const char fake_ext[] = "   ";
+	bool lower_name = true;
+	bool lower_ext = true;
+	
+	for (i = 0; i < FAT_NAME_LEN; i++) {
+		switch ((uint8_t) *name) {
+		case 0xe5:
+			d->name[i] = FAT_DENTRY_E5_ESC;
+			name++;
+			break;
+		case '\0':
+		case '.':
+			d->name[i] = FAT_PAD;
+			break;
+		default:
+			if (isalpha(*name)) {
+				if (!islower(*name))
+					lower_name = false;
+			}
+			
+			d->name[i] = toupper(*name++);
+			break;
+		}
+	}
+	
+	if (*name++ != '.')
+		name = fake_ext;
+	
+	for (i = 0; i < FAT_EXT_LEN; i++) {
+		switch ((uint8_t) *name) {
+		case 0xe5:
+			d->ext[i] = FAT_DENTRY_E5_ESC;
+			name++;
+			break;
+		case '\0':
+			d->ext[i] = FAT_PAD;
+			break;
+		default:
+			if (isalpha(*name)) {
+				if (!islower(*name))
+					lower_ext = false;
+			}
+			
+			d->ext[i] = toupper(*name++);
+			break;
+		}
+	}
+	
+	if (lower_name)
+		d->lcase |= FAT_LCASE_LOWER_NAME;
+	else
+		d->lcase &= ~FAT_LCASE_LOWER_NAME;
+	
+	if (lower_ext)
+		d->lcase |= FAT_LCASE_LOWER_EXT;
+	else
+		d->lcase &= ~FAT_LCASE_LOWER_EXT;
+}
+
+fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *d)
+{
+	if (d->attr & FAT_ATTR_VOLLABEL) {
+		/* volume label entry */
+		return FAT_DENTRY_SKIP;
+	}
+	if (d->name[0] == FAT_DENTRY_ERASED) {
+		/* not-currently-used entry */
+		return FAT_DENTRY_FREE;
+	}
+	if (d->name[0] == FAT_DENTRY_UNUSED) {
+		/* never used entry */
+		return FAT_DENTRY_LAST;
+	}
+	if (d->name[0] == FAT_DENTRY_DOT) {
+		/*
+		 * Most likely '.' or '..'.
+		 * It cannot occur in a regular file name.
+		 */
+		return FAT_DENTRY_SKIP;
+	}
+	return FAT_DENTRY_VALID;
 }
 
Index: uspace/srv/fs/fat/fat_dentry.h
===================================================================
--- uspace/srv/fs/fat/fat_dentry.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat_dentry.h	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -38,7 +37,4 @@
 #include <bool.h>
 
-#define IS_D_CHAR(ch) (isalnum(ch) || ch == '_')
-#define FAT_STOP_CHARS L"*?/\\\n\t|'"
-
 #define FAT_NAME_LEN		8
 #define FAT_EXT_LEN		3
@@ -48,19 +44,12 @@
 #define FAT_EXT_PAD		"   "
 
-#define FAT_ATTR_RDONLY   0x01
-#define FAT_ATTR_HIDDEN   0x02
-#define FAT_ATTR_SYSTEM   0x04
-#define FAT_ATTR_VOLLABEL 0x08
-#define FAT_ATTR_SUBDIR   0x10
-#define FAT_ATTR_ARCHIVE  0x20
-#define FAT_ATTR_LFN \
-    (FAT_ATTR_RDONLY | FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM | FAT_ATTR_VOLLABEL)
-    
+#define FAT_ATTR_RDONLY		(1 << 0)
+#define FAT_ATTR_VOLLABEL	(1 << 3)
+#define FAT_ATTR_SUBDIR		(1 << 4)
+
 #define FAT_LCASE_LOWER_NAME	0x08
 #define FAT_LCASE_LOWER_EXT	0x10
 
-#define FAT_PAD			' '
-#define FAT_LFN_PAD	0xffff
-#define FAT_SFN_CHAR '_'
+#define FAT_PAD			' ' 
 
 #define FAT_DENTRY_UNUSED	0x00
@@ -68,25 +57,4 @@
 #define FAT_DENTRY_DOT		0x2e
 #define FAT_DENTRY_ERASED	0xe5
-#define FAT_LFN_LAST		0x40
-#define FAT_LFN_ERASED		0x80
-
-#define FAT_LFN_ORDER(d) (d->lfn.order)
-#define FAT_IS_LFN(d) \
-    ((FAT_LFN_ORDER(d) & FAT_LFN_LAST) == FAT_LFN_LAST)
-#define FAT_LFN_COUNT(d) \
-    (FAT_LFN_ORDER(d) ^ FAT_LFN_LAST)
-#define FAT_LFN_PART1(d) (d->lfn.part1)
-#define FAT_LFN_PART2(d) (d->lfn.part2)
-#define FAT_LFN_PART3(d) (d->lfn.part3)
-#define FAT_LFN_ATTR(d) (d->lfn.attr)
-#define FAT_LFN_CHKSUM(d) (d->lfn.check_sum)
-
-#define FAT_LFN_NAME_SIZE   260
-#define FAT_LFN_MAX_COUNT   20
-#define FAT_LFN_PART1_SIZE  5
-#define FAT_LFN_PART2_SIZE  6
-#define FAT_LFN_PART3_SIZE  2
-#define FAT_LFN_ENTRY_SIZE \
-    (FAT_LFN_PART1_SIZE + FAT_LFN_PART2_SIZE + FAT_LFN_PART3_SIZE)
 
 typedef enum {
@@ -94,62 +62,34 @@
 	FAT_DENTRY_LAST,
 	FAT_DENTRY_FREE,
-	FAT_DENTRY_VALID,
-	FAT_DENTRY_LFN
+	FAT_DENTRY_VALID
 } fat_dentry_clsf_t;
 
 typedef struct {
+	uint8_t		name[8];
+	uint8_t		ext[3];
+	uint8_t		attr;
+	uint8_t		lcase;
+	uint8_t		ctime_fine;
+	uint16_t	ctime;
+	uint16_t	cdate;
+	uint16_t	adate;
 	union {
-		struct {
-			uint8_t		name[8];
-			uint8_t		ext[3];
-			uint8_t		attr;
-			uint8_t		lcase;
-			uint8_t		ctime_fine;
-			uint16_t	ctime;
-			uint16_t	cdate;
-			uint16_t	adate;
-			union {
-				uint16_t	eaidx;		/* FAT12/FAT16 */
-				uint16_t	firstc_hi;	/* FAT32 */
-			} __attribute__ ((packed));
-			uint16_t	mtime;
-			uint16_t	mdate;
-			union {
-				uint16_t	firstc;		/* FAT12/FAT16 */
-				uint16_t	firstc_lo;	/* FAT32 */
-			} __attribute__ ((packed));
-			uint32_t	size;
-		} __attribute__ ((packed));
-		struct {
-			uint8_t		order;
-			uint16_t	part1[FAT_LFN_PART1_SIZE];
-			uint8_t		attr;
-			uint8_t		type;
-			uint8_t		check_sum;
-			uint16_t	part2[FAT_LFN_PART2_SIZE];
-			uint16_t	firstc_lo; /* MUST be 0 */
-			uint16_t	part3[FAT_LFN_PART3_SIZE];
-		} __attribute__ ((packed)) lfn;
-	};
+		uint16_t	eaidx;		/* FAT12/FAT16 */
+		uint16_t	firstc_hi;	/* FAT32 */
+	} __attribute__ ((packed));
+	uint16_t	mtime;
+	uint16_t	mdate;
+	union {
+		uint16_t	firstc;		/* FAT12/FAT16 */
+		uint16_t	firstc_lo;	/* FAT32 */
+	} __attribute__ ((packed));
+	uint32_t	size;
 } __attribute__ ((packed)) fat_dentry_t;
 
-
 extern int fat_dentry_namecmp(char *, const char *);
+extern bool fat_dentry_name_verify(const char *);
 extern void fat_dentry_name_get(const fat_dentry_t *, char *);
 extern void fat_dentry_name_set(fat_dentry_t *, const char *);
 extern fat_dentry_clsf_t fat_classify_dentry(const fat_dentry_t *);
-extern uint8_t fat_dentry_chksum(uint8_t *);
-
-extern size_t fat_lfn_str_nlength(const uint16_t *, size_t);
-extern size_t fat_lfn_size(const fat_dentry_t *);
-extern size_t fat_lfn_get_entry(const fat_dentry_t *, uint16_t *, size_t *);
-extern size_t fat_lfn_set_entry(const uint16_t *, size_t *, size_t, fat_dentry_t *);
-
-extern void str_to_ascii(char *dst, const char *src, size_t count, uint8_t pad);
-extern size_t utf16_length(const uint16_t *wstr);
-
-extern bool fat_valid_name(const char *name);
-extern bool fat_valid_short_name(const char *name);
-
 
 #endif
Index: pace/srv/fs/fat/fat_directory.c
===================================================================
--- uspace/srv/fs/fat/fat_directory.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,495 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-/**
- * @file	fat_directory.c
- * @brief	Functions that work with FAT directory.
- */
-
-#include "fat_directory.h"
-#include "fat_fat.h"
-#include <libblock.h>
-#include <errno.h>
-#include <byteorder.h>
-#include <mem.h>
-#include <str.h>
-#include <align.h>
-
-int fat_directory_block_load(fat_directory_t *);
-
-
-int fat_directory_open(fat_node_t *nodep, fat_directory_t *di)
-{
-	di->b = NULL;
-	di->nodep = nodep;	
-	if (di->nodep->type != FAT_DIRECTORY)
-		return EINVAL;
-
-	di->bs = block_bb_get(di->nodep->idx->service_id);
-	di->blocks = ROUND_UP(nodep->size, BPS(di->bs))/BPS(di->bs);
-	di->pos = 0;
-	di->bnum = 0;
-	di->last = false;
-	return EOK;
-}
-
-int fat_directory_close(fat_directory_t *di)
-{
-	int rc=EOK;
-	
-	if (di->b)
-		rc = block_put(di->b);
-	
-	return rc;
-}
-
-int fat_directory_block_load(fat_directory_t *di)
-{
-	uint32_t i;
-	int rc;
-
-	i = (di->pos * sizeof(fat_dentry_t)) / BPS(di->bs);
-	if (i < di->blocks) {
-		if (di->b && di->bnum != i) {
-			block_put(di->b);
-			di->b = NULL;
-		}
-		if (!di->b) {
-			rc = fat_block_get(&di->b, di->bs, di->nodep, i, BLOCK_FLAGS_NONE);
-			if (rc != EOK) {
-				di->b = NULL;
-				return rc;
-			}
-			di->bnum = i;
-		}
-		return EOK;
-	}
-	return ENOENT;
-}
-
-int fat_directory_next(fat_directory_t *di)
-{
-	int rc;
-
-	di->pos += 1;
-	rc = fat_directory_block_load(di);
-	if (rc!=EOK)
-		di->pos -= 1;
-	
-	return rc;
-}
-
-int fat_directory_prev(fat_directory_t *di)
-{
-	int rc=EOK;
-	
-	if (di->pos > 0) {
-		di->pos -= 1;
-		rc=fat_directory_block_load(di);
-	}
-	else
-		return ENOENT;
-	
-	if (rc!=EOK)
-		di->pos += 1;
-	
-	return rc;
-}
-
-int fat_directory_seek(fat_directory_t *di, aoff64_t pos)
-{
-	aoff64_t _pos = di->pos;
-	int rc;
-
-	di->pos = pos;
-	rc = fat_directory_block_load(di);
-	if (rc!=EOK)
-		di->pos = _pos;
-	
-	return rc;
-}
-
-int fat_directory_get(fat_directory_t *di, fat_dentry_t **d)
-{
-	int rc;
-	
-	rc = fat_directory_block_load(di);
-	if (rc == EOK) {
-		aoff64_t o = di->pos % (BPS(di->bs) / sizeof(fat_dentry_t));
-		*d = ((fat_dentry_t *)di->b->data) + o;
-	}
-	
-	return rc;
-}
-
-int fat_directory_read(fat_directory_t *di, char *name, fat_dentry_t **de)
-{
-	fat_dentry_t *d = NULL;
-	uint16_t wname[FAT_LFN_NAME_SIZE];
-	size_t lfn_offset, lfn_size;
-	bool long_entry = false;
-	int long_entry_count = 0;
-	uint8_t checksum = 0;
-
-	do {
-		if (fat_directory_get(di, &d) == EOK) {
-			switch (fat_classify_dentry(d)) {
-			case FAT_DENTRY_LAST:
-				long_entry_count = 0;
-				long_entry = false;
-				return ENOENT;
-			case FAT_DENTRY_LFN:
-				if (long_entry) {
-					/* We found long entry */
-					long_entry_count--;
-					if ((FAT_LFN_ORDER(d) == long_entry_count) && 
-						(checksum == FAT_LFN_CHKSUM(d))) {
-						/* Right order! */
-						fat_lfn_get_entry(d, wname, &lfn_offset);
-					} else {
-						/* Something wrong with order. Skip this long entries set */
-						long_entry_count = 0;
-						long_entry = false;
-					}
-				} else {
-					if (FAT_IS_LFN(d)) {
-						/* We found Last long entry! */
-						if (FAT_LFN_COUNT(d) <= FAT_LFN_MAX_COUNT) {
-							long_entry = true;
-							long_entry_count = FAT_LFN_COUNT(d);
-							lfn_size = (FAT_LFN_ENTRY_SIZE * 
-								(FAT_LFN_COUNT(d) - 1)) + fat_lfn_size(d);
-							lfn_offset = lfn_size;
-							fat_lfn_get_entry(d, wname, &lfn_offset);
-							checksum = FAT_LFN_CHKSUM(d);
-						}
-					}
-				}
-				break;
-			case FAT_DENTRY_VALID:
-				if (long_entry && 
-					(checksum == fat_dentry_chksum(d->name))) {
-					wname[lfn_size] = '\0';
-					if (utf16_to_str(name, FAT_LFN_NAME_SIZE, wname) != EOK)
-						fat_dentry_name_get(d, name);
-				}
-				else
-					fat_dentry_name_get(d, name);
-				
-				*de = d;
-				return EOK;
-			default:
-			case FAT_DENTRY_SKIP:
-			case FAT_DENTRY_FREE:
-				long_entry_count = 0;
-				long_entry = false;
-				break;
-			}
-		}
-	} while (fat_directory_next(di) == EOK);
-	
-	return ENOENT;
-}
-
-int fat_directory_erase(fat_directory_t *di)
-{
-	int rc;
-	fat_dentry_t *d;
-	bool flag = false;
-	uint8_t checksum;
-
-	rc = fat_directory_get(di, &d);
-	if (rc != EOK)
-		return rc;
-	checksum = fat_dentry_chksum(d->name);
-
-	d->name[0] = FAT_DENTRY_ERASED;
-	di->b->dirty = true;
-	
-	while (!flag && fat_directory_prev(di) == EOK) {
-		if (fat_directory_get(di, &d) == EOK &&
-			fat_classify_dentry(d) == FAT_DENTRY_LFN &&			
-			checksum == FAT_LFN_CHKSUM(d)) {
-				if (FAT_IS_LFN(d))
-					flag = true;
-				memset(d, 0, sizeof(fat_dentry_t));
-				d->name[0] = FAT_DENTRY_ERASED;
-				di->b->dirty = true;
-		}
-		else
-			break;
-	}
-
-	return EOK;
-}
-
-int fat_directory_write(fat_directory_t *di, const char *name, fat_dentry_t *de)
-{
-	int rc;
-	bool enable_lfn = true; /* We can use this variable to switch off LFN support */
-	
-	if (fat_valid_short_name(name)) {
-		/* NAME could be directly stored in dentry without creating LFN */
-		fat_dentry_name_set(de, name);
-		if (fat_directory_is_sfn_exist(di, de))
-			return EEXIST;
-		rc = fat_directory_lookup_free(di, 1);
-		if (rc != EOK)
-			return rc;
-		rc = fat_directory_write_dentry(di, de);
-		return rc;
-	} else if (enable_lfn && fat_valid_name(name)) {
-		/* We should create long entries to store name */
-		int long_entry_count;
-		uint8_t checksum;
-		uint16_t wname[FAT_LFN_NAME_SIZE];
-		size_t lfn_size, lfn_offset;
-		
-		rc = str_to_utf16(wname, FAT_LFN_NAME_SIZE, name);
-		if (rc != EOK)
-			return rc;
-		
-		lfn_size = utf16_length(wname);
-		long_entry_count = lfn_size / FAT_LFN_ENTRY_SIZE;
-		if (lfn_size % FAT_LFN_ENTRY_SIZE)
-			long_entry_count++;
-		rc = fat_directory_lookup_free(di, long_entry_count+1);
-		if (rc != EOK)
-			return rc;
-		aoff64_t start_pos = di->pos;
-
-		/* Write Short entry */
-		rc = fat_directory_create_sfn(di, de, name);
-		if (rc != EOK)
-			return rc;
-		checksum = fat_dentry_chksum(de->name);
-
-		rc = fat_directory_seek(di, start_pos+long_entry_count);
-		if (rc != EOK)
-			return rc;
-		rc = fat_directory_write_dentry(di, de);
-		if (rc != EOK)
-			return rc;
-
-		/* Write Long entry by parts */
-		lfn_offset = 0;
-		fat_dentry_t *d;
-		size_t idx = 0;
-		do {
-			rc = fat_directory_prev(di);
-			if (rc != EOK)
-				return rc;
-			rc = fat_directory_get(di, &d);
-			if (rc != EOK)
-				return rc;
-			fat_lfn_set_entry(wname, &lfn_offset, lfn_size+1, d);
-			FAT_LFN_CHKSUM(d) = checksum;
-			FAT_LFN_ORDER(d) = ++idx;
-			di->b->dirty = true;
-		} while (lfn_offset < lfn_size);
-		FAT_LFN_ORDER(d) |= FAT_LFN_LAST;
-
-		rc = fat_directory_seek(di, start_pos+long_entry_count);
-		return rc;
-	}
-
-	return ENOTSUP;
-}
-
-int fat_directory_create_sfn(fat_directory_t *di, fat_dentry_t *de, const char *lname)
-{
-	char name[FAT_NAME_LEN+1];
-	char ext[FAT_EXT_LEN+1];
-	char number[FAT_NAME_LEN+1];
-	memset(name, FAT_PAD, FAT_NAME_LEN);
-	memset(ext, FAT_PAD, FAT_EXT_LEN);
-	memset(number, FAT_PAD, FAT_NAME_LEN);
-
-	size_t name_len = str_size(lname);
-	char *pdot = str_rchr(lname, '.');
-	ext[FAT_EXT_LEN] = '\0';
-	if (pdot) {
-		pdot++;
-		str_to_ascii(ext, pdot, FAT_EXT_LEN, FAT_SFN_CHAR);
-		name_len = (pdot - lname - 1);
-	}
-	if (name_len > FAT_NAME_LEN)
-		name_len = FAT_NAME_LEN;
-	str_to_ascii(name, lname, name_len, FAT_SFN_CHAR);
-
-	size_t idx;
-	for (idx=1; idx <= FAT_MAX_SFN; idx++) {
-		if (size_t_str(idx, 10, number, FAT_NAME_LEN-2)!=EOK)
-			return EOVERFLOW;
-
-		/* Fill de->name with FAT_PAD */
-		memset(de->name, FAT_PAD, FAT_NAME_LEN+FAT_EXT_LEN);
-		/* Copy ext */
-		memcpy(de->ext, ext, str_size(ext));
-		/* Copy name */
-		memcpy(de->name, name, str_size(name));
-
-		/* Copy number */
-		size_t offset;
-		if (str_size(name)+str_size(number)+1 >FAT_NAME_LEN)
-			offset = FAT_NAME_LEN - str_size(number)-1;
-		else
-			offset = str_size(name);
-		de->name[offset] = '~';
-		offset++;
-		memcpy(de->name+offset, number, str_size(number));
-
-		if (!fat_directory_is_sfn_exist(di, de))
-			return EOK;
-	}
-	return ERANGE;
-}
-
-int fat_directory_write_dentry(fat_directory_t *di, fat_dentry_t *de)
-{
-	fat_dentry_t *d;
-	int rc;
-
-	rc = fat_directory_get(di, &d);
-	if (rc!=EOK)
-		return rc;
-	memcpy(d, de, sizeof(fat_dentry_t));
-	di->b->dirty = true;
-	return EOK;
-}
-
-int fat_directory_expand(fat_directory_t *di)
-{
-	int rc;
-	fat_cluster_t mcl, lcl;
-
-	if (!FAT_IS_FAT32(di->bs) && di->nodep->firstc == FAT_CLST_ROOT) {
-		/* Can't grow the root directory on FAT12/16. */
-		return ENOSPC;
-	}
-	rc = fat_alloc_clusters(di->bs, di->nodep->idx->service_id, 1, &mcl, &lcl);
-	if (rc != EOK)
-		return rc;
-	rc = fat_zero_cluster(di->bs, di->nodep->idx->service_id, mcl);
-	if (rc != EOK) {
-		(void) fat_free_clusters(di->bs, di->nodep->idx->service_id, mcl);
-		return rc;
-	}
-	rc = fat_append_clusters(di->bs, di->nodep, mcl, lcl);
-	if (rc != EOK) {
-		(void) fat_free_clusters(di->bs, di->nodep->idx->service_id, mcl);
-		return rc;
-	}
-	di->nodep->size += BPS(di->bs) * SPC(di->bs);
-	di->nodep->dirty = true;		/* need to sync node */
-	di->blocks = di->nodep->size / BPS(di->bs);
-	
-	return EOK;
-}
-
-int fat_directory_lookup_free(fat_directory_t *di, size_t count)
-{
-	fat_dentry_t *d;
-	size_t found;
-	aoff64_t pos;
-	
-	do {
-		found = 0;
-		pos=0;
-		fat_directory_seek(di, 0);
-		do {
-			if (fat_directory_get(di, &d) == EOK) {
-				switch (fat_classify_dentry(d)) {
-				case FAT_DENTRY_LAST:
-				case FAT_DENTRY_FREE:
-					if (found==0) pos = di->pos;
-					found++;
-					if (found == count) {
-						fat_directory_seek(di, pos);
-						return EOK;
-					}
-					break;
-				case FAT_DENTRY_VALID:
-				case FAT_DENTRY_LFN:
-				case FAT_DENTRY_SKIP:
-				default:
-					found = 0;
-					break;
-				}
-			}
-		} while (fat_directory_next(di) == EOK);	
-	} while (fat_directory_expand(di) == EOK);
-	return ENOSPC;
-}
-
-int fat_directory_lookup_name(fat_directory_t *di, const char *name, fat_dentry_t **de)
-{
-	char entry[FAT_LFN_NAME_SIZE];
-	fat_directory_seek(di, 0);
-	while (fat_directory_read(di, entry, de) == EOK) {
-		if (fat_dentry_namecmp(entry, name) == 0) {
-			return EOK;
-		} else {
-			if (fat_directory_next(di) != EOK)
-				break;
-		}
-	}
-	return ENOENT;
-}
-
-bool fat_directory_is_sfn_exist(fat_directory_t *di, fat_dentry_t *de)
-{
-	fat_dentry_t *d;
-	fat_directory_seek(di, 0);
-	do {
-		if (fat_directory_get(di, &d) == EOK) {
-			switch (fat_classify_dentry(d)) {
-			case FAT_DENTRY_LAST:
-				return false;
-			case FAT_DENTRY_VALID:
-					if (bcmp(de->name, d->name, FAT_NAME_LEN+FAT_EXT_LEN)==0)
-						return true;
-					break;
-			default:
-			case FAT_DENTRY_LFN:
-			case FAT_DENTRY_SKIP:
-			case FAT_DENTRY_FREE:
-				break;
-			}
-		}
-	} while (fat_directory_next(di) == EOK);	
-	return false;
-}
-
-/**
- * @}
- */ 
Index: pace/srv/fs/fat/fat_directory.h
===================================================================
--- uspace/srv/fs/fat/fat_directory.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ 	(revision )
@@ -1,78 +1,0 @@
-/*
- * Copyright (c) 2011 Oleg Romanenko
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup fs
- * @{
- */ 
-
-#ifndef FAT_FAT_DIRECTORY_H_
-#define FAT_FAT_DIRECTORY_H_
-
-#include <stdint.h>
-#include "fat.h"
-#include "fat_dentry.h"
-
-#define FAT_MAX_SFN 9999
-
-typedef struct {
-	/* Directory data */
-	fat_bs_t *bs;
-	fat_node_t *nodep;
-	uint32_t blocks;
-	uint32_t bnum;
-	aoff64_t pos;
-	block_t *b;
-	bool last;
-} fat_directory_t;
-
-
-extern int fat_directory_open(fat_node_t *, fat_directory_t *);
-extern int fat_directory_close(fat_directory_t *);
-
-extern int fat_directory_next(fat_directory_t *);
-extern int fat_directory_prev(fat_directory_t *);
-extern int fat_directory_seek(fat_directory_t *, aoff64_t);
-extern int fat_directory_get(fat_directory_t *, fat_dentry_t **);
-
-extern int fat_directory_read(fat_directory_t *, char *, fat_dentry_t **);
-extern int fat_directory_write(fat_directory_t *, const char *, fat_dentry_t *);
-extern int fat_directory_erase(fat_directory_t *);
-extern int fat_directory_lookup_name(fat_directory_t *, const char *, fat_dentry_t **);
-extern bool fat_directory_is_sfn_exist(fat_directory_t *, fat_dentry_t *);
-
-extern int fat_directory_lookup_free(fat_directory_t *di, size_t count);
-extern int fat_directory_write_dentry(fat_directory_t *di, fat_dentry_t *de);
-extern int fat_directory_create_sfn(fat_directory_t *di, fat_dentry_t *de, const char *lname);
-extern int fat_directory_expand(fat_directory_t *di);
-
-
-#endif
-
-/**
- * @}
- */
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat_fat.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -30,5 +29,5 @@
 /** @addtogroup fs
  * @{
- */
+ */ 
 
 /**
@@ -55,8 +54,10 @@
  * primitive boot sector members.
  */
+#define RDS(bs)		((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \
+			(((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0)
+#define SSA(bs)		(RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs))
+
 #define CLBN2PBN(bs, cl, bn) \
 	(SSA((bs)) + ((cl) - FAT_CLST_FIRST) * SPC((bs)) + (bn) % SPC((bs)))
-
-#define IS_ODD(number)	(number & 0x1)
 
 /**
@@ -64,5 +65,5 @@
  * during allocation of clusters. The lock does not have to be held durring
  * deallocation of clusters.
- */
+ */  
 static FIBRIL_MUTEX_INITIALIZE(fat_alloc_lock);
 
@@ -76,15 +77,15 @@
  * @param numc		If non-NULL, output argument holding the number of
  *			clusters seen during the walk.
- * @param max_clusters	Maximum number of clusters to visit.
+ * @param max_clusters	Maximum number of clusters to visit.	
  *
  * @return		EOK on success or a negative error code.
  */
-int
+int 
 fat_cluster_walk(fat_bs_t *bs, service_id_t service_id, fat_cluster_t firstc,
-    fat_cluster_t *lastc, uint32_t *numc, uint32_t max_clusters)
-{
-	uint32_t clusters = 0;
-	fat_cluster_t clst = firstc, clst_last1 = FAT_CLST_LAST1(bs);
-	fat_cluster_t clst_bad = FAT_CLST_BAD(bs);
+    fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters)
+{
+	block_t *b;
+	uint16_t clusters = 0;
+	fat_cluster_t clst = firstc;
 	int rc;
 
@@ -98,19 +99,27 @@
 	}
 
-	while (clst < clst_last1 && clusters < max_clusters) {
+	while (clst < FAT_CLST_LAST1 && clusters < max_clusters) {
+		aoff64_t fsec;	/* sector offset relative to FAT1 */
+		unsigned fidx;	/* FAT1 entry index */
+
 		assert(clst >= FAT_CLST_FIRST);
 		if (lastc)
 			*lastc = clst;	/* remember the last cluster number */
-
+		fsec = (clst * sizeof(fat_cluster_t)) / BPS(bs);
+		fidx = clst % (BPS(bs) / sizeof(fat_cluster_t));
 		/* read FAT1 */
-		rc = fat_get_cluster(bs, service_id, FAT1, clst, &clst);
-		if (rc != EOK)
-			return rc;
-
-		assert(clst != clst_bad);
+		rc = block_get(&b, service_id, RSCNT(bs) + fsec,
+		    BLOCK_FLAGS_NONE);
+		if (rc != EOK)
+			return rc;
+		clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]);
+		assert(clst != FAT_CLST_BAD);
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
 		clusters++;
 	}
 
-	if (lastc && clst < clst_last1)
+	if (lastc && clst < FAT_CLST_LAST1)
 		*lastc = clst;
 	if (numc)
@@ -142,5 +151,5 @@
 		return ELIMIT;
 
-	if (!FAT_IS_FAT32(bs) && nodep->firstc == FAT_CLST_ROOT)
+	if (nodep->firstc == FAT_CLST_ROOT) 
 		goto fall_through;
 
@@ -169,5 +178,5 @@
 	if (rc != EOK)
 		return rc;
-
+	
 	/*
 	 * Update the "current" cluster cache.
@@ -189,5 +198,5 @@
  * @param clp		If not NULL, address where the cluster containing bn
  *			will be stored.
- *			stored
+ *			stored 
  * @param bn		Block number.
  * @param flags		Flags passed to libblock.
@@ -199,6 +208,6 @@
     fat_cluster_t fcl, fat_cluster_t *clp, aoff64_t bn, int flags)
 {
-	uint32_t clusters;
-	uint32_t max_clusters;
+	uint16_t clusters;
+	unsigned max_clusters;
 	fat_cluster_t c;
 	int rc;
@@ -210,5 +219,5 @@
 		return ELIMIT;
 
-	if (!FAT_IS_FAT32(bs) && fcl == FAT_CLST_ROOT) {
+	if (fcl == FAT_CLST_ROOT) {
 		/* root directory special case */
 		assert(bn < RDS(bs));
@@ -266,8 +275,8 @@
 			return rc;
 	}
-
+	
 	if (o >= pos)
 		return EOK;
-
+	
 	/* zero out the initial part of the new cluster chain */
 	for (o = boundary; o < pos; o += BPS(bs)) {
@@ -286,5 +295,5 @@
 }
 
-/** Get cluster from the first FAT. FAT12 version
+/** Get cluster from the first FAT.
  *
  * @param bs		Buffer holding the boot sector for the file system.
@@ -296,310 +305,20 @@
  */
 int
-fat_get_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
+fat_get_cluster(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
     fat_cluster_t clst, fat_cluster_t *value)
 {
-	block_t *b, *b1;
-	uint16_t byte1, byte2;
-	aoff64_t offset;
-	int rc;
-
-	offset = (clst + clst/2);
-	if (offset / BPS(bs) >= SF(bs))
-		return ERANGE;
+	block_t *b;
+	fat_cluster_t *cp;
+	int rc;
 
 	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
+	    (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
 	if (rc != EOK)
 		return rc;
-
-	byte1 = ((uint8_t*) b->data)[offset % BPS(bs)];
-	/* This cluster access spans a sector boundary. Check only for FAT12 */
-	if ((offset % BPS(bs)) + 1 == BPS(bs)) {
-		/* Is it last sector of FAT? */
-		if (offset / BPS(bs) < SF(bs)) {
-			/* No. Reading next sector */
-			rc = block_get(&b1, service_id, 1 + RSCNT(bs) +
-				SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE);
-			if (rc != EOK) {
-				block_put(b);
-				return rc;
-			}
-			/*
-			* Combining value with last byte of current sector and
-			* first byte of next sector
-			*/
-			byte2 = ((uint8_t*) b1->data)[0];
-
-			rc = block_put(b1);
-			if (rc != EOK) {
-				block_put(b);
-				return rc;
-			}
-		}
-		else {
-			/* Yes. It is last sector of FAT */
-			block_put(b);
-			return ERANGE;
-		}
-	}
-	else
-		byte2 = ((uint8_t*) b->data)[(offset % BPS(bs))+1];
-
-	*value = uint16_t_le2host(byte1 | (byte2 << 8));
-	if (IS_ODD(clst))
-		*value = (*value) >> 4;
-	else
-		*value = (*value) & FAT12_MASK;
+	cp = (fat_cluster_t *)b->data +
+	    clst % (BPS(bs) / sizeof(fat_cluster_t));
+	*value = uint16_t_le2host(*cp);
+	rc = block_put(b);
 	
-	rc = block_put(b);
-	return rc;
-}
-
-/** Get cluster from the first FAT. FAT16 version
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param clst		Cluster which to get.
- * @param value		Output argument holding the value of the cluster.
- *
- * @return		EOK or a negative error code.
- */
-int
-fat_get_cluster_fat16(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t *value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-
-	offset = (clst * FAT16_CLST_SIZE);
-
-	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	*value = uint16_t_le2host(*(uint16_t *)(b->data + offset % BPS(bs)));
-
-	rc = block_put(b);
-
-	return rc;
-}
-
-/** Get cluster from the first FAT. FAT32 version
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param clst		Cluster which to get.
- * @param value		Output argument holding the value of the cluster.
- *
- * @return		EOK or a negative error code.
- */
-int
-fat_get_cluster_fat32(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t *value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-
-	offset = (clst * FAT32_CLST_SIZE);
-
-	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	*value = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs))) & FAT32_MASK;
-
-	rc = block_put(b);
-
-	return rc;
-}
-
-
-/** Get cluster from the first FAT.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param clst		Cluster which to get.
- * @param value		Output argument holding the value of the cluster.
- *
- * @return		EOK or a negative error code.
- */
-int
-fat_get_cluster(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t *value)
-{
-	int rc;
-
-	assert(fatno < FATCNT(bs));
-
-	if (FAT_IS_FAT12(bs)) {
-		rc = fat_get_cluster_fat12(bs, service_id, fatno, clst, value);
-	}
-	else {
-		if (FAT_IS_FAT32(bs))
-			rc = fat_get_cluster_fat32(bs, service_id, fatno, clst, value);
-		else
-			rc = fat_get_cluster_fat16(bs, service_id, fatno, clst, value);
-	}
-
-	return rc;
-}
-
-/** Set cluster in one instance of FAT. FAT12 version.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param fatno		Number of the FAT instance where to make the change.
- * @param clst		Cluster which is to be set.
- * @param value		Value to set the cluster with.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-fat_set_cluster_fat12(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t value)
-{
-	block_t *b, *b1=NULL;
-	aoff64_t offset;
-	uint16_t byte1, byte2;
-	int rc;
-
-	offset = (clst + clst/2);
-	if (offset / BPS(bs) >= SF(bs))
-		return ERANGE;
-	
-	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	byte1 = ((uint8_t*) b->data)[offset % BPS(bs)];
-	bool border = false;
-	/* This cluster access spans a sector boundary. Check only for FAT12 */
-	if ((offset % BPS(bs))+1 == BPS(bs)) {
-		/* Is it last sector of FAT? */
-		if (offset / BPS(bs) < SF(bs)) {
-			/* No. Reading next sector */
-			rc = block_get(&b1, service_id, 1 + RSCNT(bs) +
-				SF(bs)*fatno + offset / BPS(bs), BLOCK_FLAGS_NONE);
-			if (rc != EOK) {
-				block_put(b);
-				return rc;
-			}
-			/*
-			 * Combining value with last byte of current sector and
-			 * first byte of next sector
-			 */
-			byte2 = ((uint8_t*) b1->data)[0];
-			border = true;
-		}
-		else {
-			/* Yes. It is last sector of fat */
-			block_put(b);
-			return ERANGE;
-		}
-	}
-	else
-		byte2 = ((uint8_t*) b->data)[(offset % BPS(bs))+1];
-
-	if (IS_ODD(clst)) {
-		byte1 &= 0x0f;
-		byte2 = 0;
-		value = (value << 4);
-	} else {
-		byte1 = 0;
-		byte2 &= 0xf0;
-		value &= FAT12_MASK;
-	}
-
-	byte1 = byte1 | (value & 0xff);
-	byte2 = byte2 | (value >> 8);
-
-	((uint8_t*) b->data)[(offset % BPS(bs))] = byte1;
-	if (border) {
-		((uint8_t*) b1->data)[0] = byte2;
-
-		b1->dirty = true;
-		rc = block_put(b1);
-		if (rc != EOK) {
-			block_put(b);
-			return rc;
-		}
-	} else 
-		((uint8_t*) b->data)[(offset % BPS(bs))+1] = byte2;
-
-	b->dirty = true;	/* need to sync block */
-	rc = block_put(b);
-	return rc;
-}
-
-/** Set cluster in one instance of FAT. FAT16 version.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param fatno		Number of the FAT instance where to make the change.
- * @param clst		Cluster which is to be set.
- * @param value		Value to set the cluster with.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-fat_set_cluster_fat16(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-
-	offset = (clst * FAT16_CLST_SIZE);
-
-	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	*(uint16_t *)(b->data + offset % BPS(bs)) = host2uint16_t_le(value);
-
-	b->dirty = true;	/* need to sync block */
-	rc = block_put(b);
-	return rc;
-}
-
-/** Set cluster in one instance of FAT. FAT32 version.
- *
- * @param bs		Buffer holding the boot sector for the file system.
- * @param service_id	Service ID for the file system.
- * @param fatno		Number of the FAT instance where to make the change.
- * @param clst		Cluster which is to be set.
- * @param value		Value to set the cluster with.
- *
- * @return		EOK on success or a negative error code.
- */
-int
-fat_set_cluster_fat32(fat_bs_t *bs, service_id_t service_id, unsigned fatno,
-    fat_cluster_t clst, fat_cluster_t value)
-{
-	block_t *b;
-	aoff64_t offset;
-	int rc;
-	fat_cluster_t temp;
-
-	offset = (clst * FAT32_CLST_SIZE);
-
-	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
-	    offset / BPS(bs), BLOCK_FLAGS_NONE);
-	if (rc != EOK)
-		return rc;
-
-	temp = uint32_t_le2host(*(uint32_t *)(b->data + offset % BPS(bs)));
-	temp &= 0xf0000000;
-	temp |= (value & FAT32_MASK);
-	*(uint32_t *)(b->data + offset % BPS(bs)) = host2uint32_t_le(temp);
-
-	b->dirty = true;	/* need to sync block */
-	rc = block_put(b);
 	return rc;
 }
@@ -619,15 +338,18 @@
     fat_cluster_t clst, fat_cluster_t value)
 {
+	block_t *b;
+	fat_cluster_t *cp;
 	int rc;
 
 	assert(fatno < FATCNT(bs));
-
-	if (FAT_IS_FAT12(bs))
-		rc = fat_set_cluster_fat12(bs, service_id, fatno, clst, value);
-	else if (FAT_IS_FAT32(bs))
-		rc = fat_set_cluster_fat32(bs, service_id, fatno, clst, value);
-	else
-		rc = fat_set_cluster_fat16(bs, service_id, fatno, clst, value);
-
+	rc = block_get(&b, service_id, RSCNT(bs) + SF(bs) * fatno +
+	    (clst * sizeof(fat_cluster_t)) / BPS(bs), BLOCK_FLAGS_NONE);
+	if (rc != EOK)
+		return rc;
+	cp = (fat_cluster_t *)b->data +
+	    clst % (BPS(bs) / sizeof(fat_cluster_t));
+	*cp = host2uint16_t_le(value);
+	b->dirty = true;		/* need to sync block */
+	rc = block_put(b);
 	return rc;
 }
@@ -647,11 +369,10 @@
 	uint8_t fatno;
 	unsigned c;
-	fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs);
-	int rc;
-
-	for (fatno = FAT1 + 1; fatno < FATCNT(bs); fatno++) {
+	int rc;
+
+	for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) {
 		for (c = 0; c < nclsts; c++) {
 			rc = fat_set_cluster(bs, service_id, fatno, lifo[c],
-			    c == 0 ? clst_last1 : lifo[c - 1]);
+			    c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]);
 			if (rc != EOK)
 				return rc;
@@ -683,57 +404,94 @@
     fat_cluster_t *mcl, fat_cluster_t *lcl)
 {
-	fat_cluster_t *lifo;    /* stack for storing free cluster numbers */
-	unsigned found = 0;     /* top of the free cluster number stack */
-	fat_cluster_t clst, value, clst_last1 = FAT_CLST_LAST1(bs);
-	int rc = EOK;
+	block_t *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; 
+	int rc;
 
 	lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t));
 	if (!lifo)
 		return ENOMEM;
+	
 	/*
 	 * Search FAT1 for unused clusters.
 	 */
 	fibril_mutex_lock(&fat_alloc_lock);
-	for (clst=FAT_CLST_FIRST; clst < CC(bs)+2 && found < nclsts; clst++) {
-		rc = fat_get_cluster(bs, service_id, FAT1, clst, &value);
-		if (rc != EOK)
-		break;
-
-		if (value == FAT_CLST_RES0) {
-		/*
-		 * The cluster is free. Put it into our stack
-		 * of found clusters and mark it as non-free.
-		 */
-		lifo[found] = clst;
-		rc = fat_set_cluster(bs, service_id, FAT1, clst,
-		    (found == 0) ?  clst_last1 : lifo[found - 1]);
-		if (rc != EOK)
-			break;
-
-		found++;
+	for (b = 0, cl = 0; b < SF(bs); b++) {
+		rc = block_get(&blk, service_id, RSCNT(bs) + b,
+		    BLOCK_FLAGS_NONE);
+		if (rc != EOK)
+			goto error;
+		for (c = 0; c < BPS(bs) / sizeof(fat_cluster_t); c++, cl++) {
+			/*
+			 * Check if the entire cluster is physically there.
+			 * This check becomes necessary when the file system is
+			 * created with fewer total sectors than how many is
+			 * inferred from the size of the file allocation table
+			 * or when the last cluster ends beyond the end of the
+			 * device.
+			 */
+			if ((cl >= FAT_CLST_FIRST) &&
+			    CLBN2PBN(bs, cl, SPC(bs) - 1) >= TS(bs)) {
+				rc = block_put(blk);
+				if (rc != EOK)
+					goto error;
+				goto out;
+			}
+
+			fat_cluster_t *clst = (fat_cluster_t *)blk->data + c;
+			if (uint16_t_le2host(*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;
+				*clst = (found == 0) ?
+				    host2uint16_t_le(FAT_CLST_LAST1) :
+				    host2uint16_t_le(lifo[found - 1]);
+				blk->dirty = true;	/* need to sync block */
+				if (++found == nclsts) {
+					/* we are almost done */
+					rc = block_put(blk);
+					if (rc != EOK)
+						goto error;
+					/* update the shadow copies of FAT */
+					rc = fat_alloc_shadow_clusters(bs,
+					    service_id, lifo, nclsts);
+					if (rc != EOK)
+						goto error;
+					*mcl = lifo[found - 1];
+					*lcl = lifo[0];
+					free(lifo);
+					fibril_mutex_unlock(&fat_alloc_lock);
+					return EOK;
+				}
+			}
 		}
-	}
-
-	if (rc == EOK && found == nclsts) {
-		rc = fat_alloc_shadow_clusters(bs, service_id, lifo, nclsts);
-		if (rc == EOK) {
-			*mcl = lifo[found - 1];
-			*lcl = lifo[0];
+		rc = block_put(blk);
+		if (rc != EOK) {
+error:
+			fibril_mutex_unlock(&fat_alloc_lock);
 			free(lifo);
-			fibril_mutex_unlock(&fat_alloc_lock);
-			return EOK;
+			return rc;
 		}
 	}
-
-	/* If something wrong - free the clusters */
-	if (found > 0) {
-		while (found--) {
+out:
+	fibril_mutex_unlock(&fat_alloc_lock);
+
+	/*
+	 * We could not find enough clusters. Now we need to free the clusters
+	 * we have allocated so far.
+	 */
+	while (found--) {
 		rc = fat_set_cluster(bs, service_id, FAT1, lifo[found],
 		    FAT_CLST_RES0);
+		if (rc != EOK) {
+			free(lifo);
+			return rc;
 		}
 	}
-
+	
 	free(lifo);
-	fibril_mutex_unlock(&fat_alloc_lock);
 	return ENOSPC;
 }
@@ -751,14 +509,14 @@
 {
 	unsigned fatno;
-	fat_cluster_t nextc, clst_bad = FAT_CLST_BAD(bs);
+	fat_cluster_t nextc;
 	int rc;
 
 	/* Mark all clusters in the chain as free in all copies of FAT. */
-	while (firstc < FAT_CLST_LAST1(bs)) {
-		assert(firstc >= FAT_CLST_FIRST && firstc < clst_bad);
+	while (firstc < FAT_CLST_LAST1) {
+		assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD);
 		rc = fat_get_cluster(bs, service_id, FAT1, firstc, &nextc);
 		if (rc != EOK)
 			return rc;
-		for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
 			rc = fat_set_cluster(bs, service_id, fatno, firstc,
 			    FAT_CLST_RES0);
@@ -806,7 +564,7 @@
 		}
 
-		for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
-			rc = fat_set_cluster(bs, nodep->idx->service_id,
-			    fatno, lastc, mcl);
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
+			rc = fat_set_cluster(bs, nodep->idx->service_id, fatno,
+			    lastc, mcl);
 			if (rc != EOK)
 				return rc;
@@ -832,5 +590,4 @@
 int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lcl)
 {
-	fat_cluster_t clst_last1 = FAT_CLST_LAST1(bs);
 	int rc;
 	service_id_t service_id = nodep->idx->service_id;
@@ -859,7 +616,7 @@
 
 		/* Terminate the cluster chain in all copies of FAT. */
-		for (fatno = FAT1; fatno < FATCNT(bs); fatno++) {
+		for (fatno = FAT1; fatno < bs->fatcnt; fatno++) {
 			rc = fat_set_cluster(bs, service_id, fatno, lcl,
-			    clst_last1);
+			    FAT_CLST_LAST1);
 			if (rc != EOK)
 				return rc;
@@ -916,13 +673,14 @@
 
 	/* Check number of FATs. */
-	if (FATCNT(bs) == 0)
+	if (bs->fatcnt == 0)
 		return ENOTSUP;
 
 	/* Check total number of sectors. */
-	if (TS(bs) == 0)
+
+	if (bs->totsec16 == 0 && bs->totsec32 == 0)
 		return ENOTSUP;
 
 	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
-	    bs->totsec16 != bs->totsec32)
+	    bs->totsec16 != bs->totsec32) 
 		return ENOTSUP;
 
@@ -932,5 +690,5 @@
 
 	/* Check number of sectors per FAT. */
-	if (SF(bs) == 0)
+	if (bs->sec_per_fat == 0)
 		return ENOTSUP;
 
@@ -942,9 +700,11 @@
 	 * sanitized to support file systems with this property.
 	 */
-	if (!FAT_IS_FAT32(bs) && (RDE(bs) * sizeof(fat_dentry_t)) % BPS(bs) != 0)
+	if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %
+	    uint16_t_le2host(bs->bps) != 0)
 		return ENOTSUP;
 
 	/* Check signature of each FAT. */
-	for (fat_no = 0; fat_no < FATCNT(bs); fat_no++) {
+
+	for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
 		rc = fat_get_cluster(bs, service_id, fat_no, 0, &e0);
 		if (rc != EOK)
@@ -963,6 +723,5 @@
 		 * set to one.
 		 */
-		if (!FAT_IS_FAT12(bs) && 
-			((e0 >> 8) != (FAT_MASK(bs) >> 8) || e1 != FAT_MASK(bs)))
+		if ((e0 >> 8) != 0xff || e1 != 0xffff)
 			return ENOTSUP;
 	}
@@ -973,3 +732,3 @@
 /**
  * @}
- */
+ */ 
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat_fat.h	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -30,5 +29,5 @@
 /** @addtogroup fs
  * @{
- */
+ */ 
 
 #ifndef FAT_FAT_FAT_H_
@@ -41,23 +40,10 @@
 #define FAT1		0
 
-#define FAT_CLST_RES0	  0
-#define FAT_CLST_RES1	  1
-#define FAT_CLST_FIRST	  2
-
-#define FAT32_CLST_BAD    0x0ffffff7
-#define FAT32_CLST_LAST1  0x0ffffff8
-#define FAT32_CLST_LAST8  0x0fffffff
-
-#define FAT12_MASK        0x0fff
-#define FAT16_MASK        0xffff
-#define FAT32_MASK        0x0fffffff
-
-#define FAT12_CLST_MAX    4085
-#define FAT16_CLST_MAX    65525
-
-/* Size in bytes for cluster value of FAT */
-#define FAT12_CLST_SIZE   2
-#define FAT16_CLST_SIZE   2
-#define FAT32_CLST_SIZE   4
+#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 */
@@ -66,34 +52,4 @@
 #define FAT_CLST_ROOT		FAT_CLST_RES1
 
-/*
- * Convenience macros for computing some frequently used values from the
- * primitive boot sector members.
- */
-#define RDS(bs)	  ((sizeof(fat_dentry_t) * RDE((bs))) / BPS((bs))) + \
-		   (((sizeof(fat_dentry_t) * RDE((bs))) % BPS((bs))) != 0)
-#define SSA(bs)	  (RSCNT((bs)) + FATCNT((bs)) * SF((bs)) + RDS(bs))
-#define DS(bs)	  (TS(bs) - SSA(bs))
-#define CC(bs)	  (DS(bs) / SPC(bs))
-
-#define FAT_IS_FAT12(bs)	(CC(bs) < FAT12_CLST_MAX)
-#define FAT_IS_FAT16(bs) \
-    ((CC(bs) >= FAT12_CLST_MAX) && (CC(bs) < FAT16_CLST_MAX))
-#define FAT_IS_FAT32(bs)	(CC(bs) >= FAT16_CLST_MAX)
-
-#define FAT_CLST_SIZE(bs) \
-    (FAT_IS_FAT32(bs) ? FAT32_CLST_SIZE : FAT16_CLST_SIZE)
-
-#define FAT_MASK(bs) \
-    (FAT_IS_FAT12(bs) ? FAT12_MASK : \
-    (FAT_IS_FAT32(bs) ? FAT32_MASK : FAT16_MASK))
-
-#define FAT_CLST_LAST1(bs)      (FAT32_CLST_LAST1 & FAT_MASK((bs)))
-#define FAT_CLST_LAST8(bs)      (FAT32_CLST_LAST8 & FAT_MASK((bs)))
-#define FAT_CLST_BAD(bs)        (FAT32_CLST_BAD & FAT_MASK((bs)))
-
-#define FAT_ROOT_CLST(bs) \
-    (FAT_IS_FAT32(bs) ? uint32_t_le2host(bs->fat32.root_cluster) : \
-    FAT_CLST_ROOT)
-
 /* forward declarations */
 struct block;
@@ -101,10 +57,10 @@
 struct fat_bs;
 
-typedef uint32_t fat_cluster_t;
+typedef uint16_t fat_cluster_t;
 
-#define fat_clusters_get(numc, bs, sid, fc) \
-    fat_cluster_walk((bs), (sid), (fc), NULL, (numc), (uint32_t) -1)
+#define fat_clusters_get(numc, bs, dh, fc) \
+    fat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint16_t) -1)
 extern int fat_cluster_walk(struct fat_bs *, service_id_t, fat_cluster_t,
-    fat_cluster_t *, uint32_t *, uint32_t);
+    fat_cluster_t *, uint16_t *, uint16_t);
 
 extern int fat_block_get(block_t **, struct fat_bs *, struct fat_node *,
@@ -122,18 +78,6 @@
 extern int fat_alloc_shadow_clusters(struct fat_bs *, service_id_t,
     fat_cluster_t *, unsigned);
-extern int fat_get_cluster_fat12(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t *);
-extern int fat_get_cluster_fat16(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t *);
-extern int fat_get_cluster_fat32(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t *);
 extern int fat_get_cluster(struct fat_bs *, service_id_t, unsigned,
     fat_cluster_t, fat_cluster_t *);
-extern int fat_set_cluster_fat12(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t);
-extern int fat_set_cluster_fat16(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t);
-extern int fat_set_cluster_fat32(struct fat_bs *, service_id_t, unsigned,
-    fat_cluster_t, fat_cluster_t);
 extern int fat_set_cluster(struct fat_bs *, service_id_t, unsigned,
     fat_cluster_t, fat_cluster_t);
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision 375ab5e571cc53eeb2aa803a8e86052b51d7ad00)
+++ uspace/srv/fs/fat/fat_ops.c	(revision 7fadb6526b88d8a8d0bbeb5d5997969a53e7e66d)
@@ -1,5 +1,4 @@
 /*
  * Copyright (c) 2008 Jakub Jermar
- * Copyright (c) 2011 Oleg Romanenko
  * All rights reserved.
  *
@@ -30,5 +29,5 @@
 /** @addtogroup fs
  * @{
- */
+ */ 
 
 /**
@@ -40,5 +39,4 @@
 #include "fat_dentry.h"
 #include "fat_fat.h"
-#include "fat_directory.h"
 #include "../../vfs/vfs.h"
 #include <libfs.h>
@@ -58,5 +56,4 @@
 #include <align.h>
 #include <malloc.h>
-#include <str.h>
 
 #define FAT_NODE(node)	((node) ? (fat_node_t *) (node)->data : NULL)
@@ -107,8 +104,8 @@
 	node->dirty = false;
 	node->lastc_cached_valid = false;
-	node->lastc_cached_value = 0;
+	node->lastc_cached_value = FAT_CLST_LAST1;
 	node->currc_cached_valid = false;
 	node->currc_cached_bn = 0;
-	node->currc_cached_value = 0;
+	node->currc_cached_value = FAT_CLST_LAST1;
 }
 
@@ -119,9 +116,9 @@
 	fat_dentry_t *d;
 	int rc;
-
+	
 	assert(node->dirty);
 
 	bs = block_bb_get(node->idx->service_id);
-
+	
 	/* Read the block that contains the dentry of interest. */
 	rc = _fat_block_get(&b, bs, node->idx->service_id, node->idx->pfc,
@@ -139,7 +136,7 @@
 		d->attr = FAT_ATTR_SUBDIR;
 	}
-
+	
 	/* TODO: update other fields? (e.g time fields) */
-
+	
 	b->dirty = true;		/* need to sync block */
 	rc = block_put(b);
@@ -258,5 +255,5 @@
 	fn->data = nodep;
 	nodep->bp = fn;
-
+	
 	*nodepp = nodep;
 	return EOK;
@@ -294,5 +291,5 @@
 	 * We must instantiate the node from the file system.
 	 */
-
+	
 	assert(idxp->pfc);
 
@@ -312,13 +309,6 @@
 
 	d = ((fat_dentry_t *)b->data) + (idxp->pdi % DPS(bs));
-	if (FAT_IS_FAT32(bs)) {
-		nodep->firstc = uint16_t_le2host(d->firstc_lo) | 
-		    (uint16_t_le2host(d->firstc_hi) << 16);
-	} 
-	else
-		nodep->firstc = uint16_t_le2host(d->firstc);
-
 	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
@@ -326,5 +316,4 @@
 		 */
 		nodep->type = FAT_DIRECTORY;
-
 		/*
 		 * Unfortunately, the 'size' field of the FAT dentry is not
@@ -332,6 +321,7 @@
 		 * size of the directory by walking the FAT.
 		 */
-		uint32_t clusters;
-		rc = fat_clusters_get(&clusters, bs, idxp->service_id, nodep->firstc);
+		uint16_t clusters;
+		rc = fat_clusters_get(&clusters, bs, idxp->service_id,
+		    uint16_t_le2host(d->firstc));
 		if (rc != EOK) {
 			(void) block_put(b);
@@ -344,5 +334,5 @@
 		nodep->size = uint32_t_le2host(d->size);
 	}
-
+	nodep->firstc = uint16_t_le2host(d->firstc);
 	nodep->lnkcnt = 1;
 	nodep->refcnt = 1;
@@ -373,8 +363,12 @@
 int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component)
 {
+	fat_bs_t *bs;
 	fat_node_t *parentp = FAT_NODE(pfn);
-	char name[FAT_LFN_NAME_SIZE];
+	char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
+	unsigned i, j;
+	unsigned blocks;
 	fat_dentry_t *d;
 	service_id_t service_id;
+	block_t *b;
 	int rc;
 
@@ -382,43 +376,58 @@
 	service_id = parentp->idx->service_id;
 	fibril_mutex_unlock(&parentp->idx->lock);
-	
-	fat_directory_t di;
-	rc = fat_directory_open(parentp, &di);
-	if (rc != EOK)
-		return rc;
-
-	while (fat_directory_read(&di, name, &d) == EOK) {
-		if (fat_dentry_namecmp(name, component) == 0) {
-			/* hit */
-			fat_node_t *nodep;
-			aoff64_t o = di.pos % (BPS(di.bs) / sizeof(fat_dentry_t));
-			fat_idx_t *idx = fat_idx_get_by_pos(service_id,
-				parentp->firstc, di.bnum * DPS(di.bs) + o);
-			if (!idx) {
-				/*
-				 * Can happen if memory is low or if we
-				 * run out of 32-bit indices.
-				 */
-				rc = fat_directory_close(&di);
-				return (rc == EOK) ? ENOMEM : rc;
+
+	bs = block_bb_get(service_id);
+	blocks = parentp->size / BPS(bs);
+	for (i = 0; i < blocks; i++) {
+		rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+		if (rc != EOK)
+			return rc;
+		for (j = 0; j < DPS(bs); j++) { 
+			d = ((fat_dentry_t *)b->data) + j;
+			switch (fat_classify_dentry(d)) {
+			case FAT_DENTRY_SKIP:
+			case FAT_DENTRY_FREE:
+				continue;
+			case FAT_DENTRY_LAST:
+				/* miss */
+				rc = block_put(b);
+				*rfn = NULL;
+				return rc;
+			default:
+			case FAT_DENTRY_VALID:
+				fat_dentry_name_get(d, name);
+				break;
 			}
-			rc = fat_node_get_core(&nodep, idx);
-			fibril_mutex_unlock(&idx->lock);
-			if (rc != EOK) {
-				(void) fat_directory_close(&di);
+			if (fat_dentry_namecmp(name, component) == 0) {
+				/* hit */
+				fat_node_t *nodep;
+				fat_idx_t *idx = fat_idx_get_by_pos(service_id,
+				    parentp->firstc, i * DPS(bs) + j);
+				if (!idx) {
+					/*
+					 * Can happen if memory is low or if we
+					 * run out of 32-bit indices.
+					 */
+					rc = block_put(b);
+					return (rc == EOK) ? ENOMEM : rc;
+				}
+				rc = fat_node_get_core(&nodep, idx);
+				fibril_mutex_unlock(&idx->lock);
+				if (rc != EOK) {
+					(void) block_put(b);
+					return rc;
+				}
+				*rfn = FS_NODE(nodep);
+				rc = block_put(b);
+				if (rc != EOK)
+					(void) fat_node_put(*rfn);
 				return rc;
 			}
-			*rfn = FS_NODE(nodep);
-			rc = fat_directory_close(&di);
-			if (rc != EOK)
-				(void) fat_node_put(*rfn);
-			return rc;
-		} else {
-			rc = fat_directory_next(&di);
-			if (rc != EOK)
-				break;
-		}
-	}
-	(void) fat_directory_close(&di);
+		}
+		rc = block_put(b);
+		if (rc != EOK)
+			return rc;
+	}
+
 	*rfn = NULL;
 	return EOK;
@@ -582,6 +591,7 @@
 	fat_bs_t *bs;
 	block_t *b;
-	fat_directory_t di;
-	fat_dentry_t de;
+	unsigned i, j;
+	unsigned blocks;
+	fat_cluster_t mcl, lcl;
 	int rc;
 
@@ -597,13 +607,83 @@
 	fibril_mutex_unlock(&childp->lock);
 
-	if (!fat_valid_name(name))
+	if (!fat_dentry_name_verify(name)) {
+		/*
+		 * Attempt to create unsupported name.
+		 */
 		return ENOTSUP;
-
+	}
+
+	/*
+	 * Get us an unused parent node's dentry or grow the parent and allocate
+	 * a new one.
+	 */
+	
 	fibril_mutex_lock(&parentp->idx->lock);
 	bs = block_bb_get(parentp->idx->service_id);
-	rc = fat_directory_open(parentp, &di);
-	if (rc != EOK)
-		return rc;
-
+
+	blocks = parentp->size / BPS(bs);
+
+	for (i = 0; i < blocks; i++) {
+		rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
+		for (j = 0; j < DPS(bs); j++) {
+			d = ((fat_dentry_t *)b->data) + j;
+			switch (fat_classify_dentry(d)) {
+			case FAT_DENTRY_SKIP:
+			case FAT_DENTRY_VALID:
+				/* skipping used and meta entries */
+				continue;
+			case FAT_DENTRY_FREE:
+			case FAT_DENTRY_LAST:
+				/* found an empty slot */
+				goto hit;
+			}
+		}
+		rc = block_put(b);
+		if (rc != EOK) {
+			fibril_mutex_unlock(&parentp->idx->lock);
+			return rc;
+		}
+	}
+	j = 0;
+	
+	/*
+	 * We need to grow the parent in order to create a new unused dentry.
+	 */
+	if (parentp->firstc == FAT_CLST_ROOT) {
+		/* Can't grow the root directory. */
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return ENOSPC;
+	}
+	rc = fat_alloc_clusters(bs, parentp->idx->service_id, 1, &mcl, &lcl);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	rc = fat_zero_cluster(bs, parentp->idx->service_id, mcl);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, parentp->idx->service_id, mcl);
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	rc = fat_append_clusters(bs, parentp, mcl, lcl);
+	if (rc != EOK) {
+		(void) fat_free_clusters(bs, parentp->idx->service_id, mcl);
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	parentp->size += BPS(bs) * SPC(bs);
+	parentp->dirty = true;		/* need to sync node */
+	rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE);
+	if (rc != EOK) {
+		fibril_mutex_unlock(&parentp->idx->lock);
+		return rc;
+	}
+	d = (fat_dentry_t *)b->data;
+
+hit:
 	/*
 	 * At this point we only establish the link between the parent and the
@@ -612,19 +692,14 @@
 	 * dentry data is kept in the child node structure.
 	 */
-	memset(&de, 0, sizeof(fat_dentry_t));
-
-	rc = fat_directory_write(&di, name, &de);
-	if (rc!=EOK)
-		return rc;
-	rc = fat_directory_close(&di);
-	if (rc!=EOK)
-		return rc;
-
+	memset(d, 0, sizeof(fat_dentry_t));
+	fat_dentry_name_set(d, name);
+	b->dirty = true;		/* need to sync block */
+	rc = block_put(b);
 	fibril_mutex_unlock(&parentp->idx->lock);
-	if (rc != EOK)
+	if (rc != EOK) 
 		return rc;
 
 	fibril_mutex_lock(&childp->idx->lock);
-
+	
 	if (childp->type == FAT_DIRECTORY) {
 		/*
@@ -645,5 +720,5 @@
 		d = (fat_dentry_t *) b->data;
 		if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
-		    (bcmp(d->name, FAT_NAME_DOT, FAT_NAME_LEN)) == 0) {
+		    (str_cmp((char *) d->name, FAT_NAME_DOT)) == 0) {
 			memset(d, 0, sizeof(fat_dentry_t));
 			memcpy(d->name, FAT_NAME_DOT, FAT_NAME_LEN);
@@ -655,11 +730,11 @@
 		d++;
 		if ((fat_classify_dentry(d) == FAT_DENTRY_LAST) ||
-		    (bcmp(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN) == 0)) {
+		    (str_cmp((char *) d->name, FAT_NAME_DOT_DOT) == 0)) {
 			memset(d, 0, sizeof(fat_dentry_t));
 			memcpy(d->name, FAT_NAME_DOT_DOT, FAT_NAME_LEN);
 			memcpy(d->ext, FAT_EXT_PAD, FAT_EXT_LEN);
 			d->attr = FAT_ATTR_SUBDIR;
-			d->firstc = (parentp->firstc == FAT_ROOT_CLST(bs)) ?
-			    host2uint16_t_le(FAT_CLST_ROOTPAR) :
+			d->firstc = (parentp->firstc == FAT_CLST_ROOT) ?
+			    host2uint16_t_le(FAT_CLST_RES0) :
 			    host2uint16_t_le(parentp->firstc);
 			/* TODO: initialize also the date/time members. */
@@ -675,5 +750,5 @@
 
 	childp->idx->pfc = parentp->firstc;
-	childp->idx->pdi = di.pos;	/* di.pos holds absolute position of SFN entry */
+	childp->idx->pdi = i * DPS(bs) + j;
 	fibril_mutex_unlock(&childp->idx->lock);
 
@@ -695,4 +770,7 @@
 	fat_node_t *parentp = FAT_NODE(pfn);
 	fat_node_t *childp = FAT_NODE(cfn);
+	fat_bs_t *bs;
+	fat_dentry_t *d;
+	block_t *b;
 	bool has_children;
 	int rc;
@@ -700,5 +778,5 @@
 	if (!parentp)
 		return EBUSY;
-
+	
 	rc = fat_has_children(&has_children, cfn);
 	if (rc != EOK)
@@ -711,16 +789,17 @@
 	assert(childp->lnkcnt == 1);
 	fibril_mutex_lock(&childp->idx->lock);
-	
-	fat_directory_t di;
-	rc = fat_directory_open(parentp,&di);
-	if (rc != EOK)
+	bs = block_bb_get(childp->idx->service_id);
+
+	rc = _fat_block_get(&b, bs, childp->idx->service_id, childp->idx->pfc,
+	    NULL, (childp->idx->pdi * sizeof(fat_dentry_t)) / BPS(bs),
+	    BLOCK_FLAGS_NONE);
+	if (rc != EOK) 
 		goto error;
-	rc = fat_directory_seek(&di, childp->idx->pdi);
-	if (rc != EOK)
-		goto error;
-	rc = fat_directory_erase(&di);
-	if (rc != EOK)
-		goto error;
-	rc = fat_directory_close(&di);
+	d = (fat_dentry_t *)b->data +
+	    (childp->idx->pdi % (BPS(bs) / sizeof(fat_dentry_t)));
+	/* mark the dentry as not-currently-used */
+	d->name[0] = FAT_DENTRY_ERASED;
+	b->dirty = true;		/* need to sync block */
+	rc = block_put(b);
 	if (rc != EOK)
 		goto error;
@@ -741,8 +820,7 @@
 
 error:
-	(void) fat_directory_close(&di);
+	fibril_mutex_unlock(&parentp->idx->lock);
+	fibril_mutex_unlock(&childp->lock);
 	fibril_mutex_unlock(&childp->idx->lock);
-	fibril_mutex_unlock(&childp->lock);
-	fibril_mutex_unlock(&parentp->lock);
 	return rc;
 }
@@ -761,5 +839,5 @@
 		return EOK;
 	}
-
+	
 	fibril_mutex_lock(&nodep->idx->lock);
 	bs = block_bb_get(nodep->idx->service_id);
@@ -769,5 +847,5 @@
 	for (i = 0; i < blocks; i++) {
 		fat_dentry_t *d;
-
+	
 		rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE);
 		if (rc != EOK) {
@@ -797,5 +875,5 @@
 		if (rc != EOK) {
 			fibril_mutex_unlock(&nodep->idx->lock);
-			return rc;
+			return rc;	
 		}
 	}
@@ -868,5 +946,5 @@
 	fat_bs_t *bs;
 	int rc;
-
+	
 	/* Check for option enabling write through. */
 	if (str_cmp(opts, "wtcache") == 0)
@@ -925,5 +1003,4 @@
 		return ENOMEM;
 	}
-
 	fs_node_initialize(rfn);
 	fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t));
@@ -950,28 +1027,13 @@
 
 	rootp->type = FAT_DIRECTORY;
-	rootp->firstc = FAT_ROOT_CLST(bs);
+	rootp->firstc = FAT_CLST_ROOT;
 	rootp->refcnt = 1;
 	rootp->lnkcnt = 0;	/* FS root is not linked */
-
-	if (FAT_IS_FAT32(bs)) {
-		uint32_t clusters;
-		rc = fat_clusters_get(&clusters, bs, service_id, rootp->firstc);
-		if (rc != EOK) {
-			free(rfn);
-			free(rootp);
-			(void) block_cache_fini(service_id);
-			block_fini(service_id);
-			fat_idx_fini_by_service_id(service_id);
-			return ENOTSUP;
-		}
-		rootp->size = BPS(bs) * SPC(bs) * clusters;
-	} else
-		rootp->size = RDE(bs) * sizeof(fat_dentry_t);
-
+	rootp->size = RDE(bs) * sizeof(fat_dentry_t);
 	rootp->idx = ridxp;
 	ridxp->nodep = rootp;
 	rootp->bp = rfn;
 	rfn->data = rootp;
-
+	
 	fibril_mutex_unlock(&ridxp->lock);
 
@@ -1002,5 +1064,5 @@
 		return EBUSY;
 	}
-
+	
 	/*
 	 * Put the root node and force it to the FAT free node list.
@@ -1079,6 +1141,7 @@
 		}
 	} else {
+		unsigned bnum;
 		aoff64_t spos = pos;
-		char name[FAT_LFN_NAME_SIZE];
+		char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1];
 		fat_dentry_t *d;
 
@@ -1087,26 +1150,46 @@
 		assert(BPS(bs) % sizeof(fat_dentry_t) == 0);
 
-		fat_directory_t di;
-		rc = fat_directory_open(nodep, &di);
-		if (rc != EOK) goto err;
-		rc = fat_directory_seek(&di, pos);
-		if (rc != EOK) {
-			(void) fat_directory_close(&di);
-			goto err;
-		}
-
-		rc = fat_directory_read(&di, name, &d);
-		if (rc == EOK) goto hit;
-		if (rc == ENOENT) goto miss;
-
-err:
-		(void) fat_node_put(fn);
-		async_answer_0(callid, rc);
-		return rc;
-
+		/*
+		 * Our strategy for readdir() is to use the position pointer as
+		 * an index into the array of all dentries. On entry, it points
+		 * to the first unread dentry. If we skip any dentries, we bump
+		 * the position pointer accordingly.
+		 */
+		bnum = (pos * sizeof(fat_dentry_t)) / BPS(bs);
+		while (bnum < nodep->size / BPS(bs)) {
+			aoff64_t o;
+
+			rc = fat_block_get(&b, bs, nodep, bnum,
+			    BLOCK_FLAGS_NONE);
+			if (rc != EOK)
+				goto err;
+			for (o = pos % (BPS(bs) / sizeof(fat_dentry_t));
+			    o < BPS(bs) / sizeof(fat_dentry_t);
+			    o++, pos++) {
+				d = ((fat_dentry_t *)b->data) + o;
+				switch (fat_classify_dentry(d)) {
+				case FAT_DENTRY_SKIP:
+				case FAT_DENTRY_FREE:
+					continue;
+				case FAT_DENTRY_LAST:
+					rc = block_put(b);
+					if (rc != EOK)
+						goto err;
+					goto miss;
+				default:
+				case FAT_DENTRY_VALID:
+					fat_dentry_name_get(d, name);
+					rc = block_put(b);
+					if (rc != EOK)
+						goto err;
+					goto hit;
+				}
+			}
+			rc = block_put(b);
+			if (rc != EOK)
+				goto err;
+			bnum++;
+		}
 miss:
-		rc = fat_directory_close(&di);
-		if (rc!=EOK)
-			goto err;
 		rc = fat_node_put(fn);
 		async_answer_0(callid, rc != EOK ? rc : ENOENT);
@@ -1114,11 +1197,12 @@
 		return rc != EOK ? rc : ENOENT;
 
+err:
+		(void) fat_node_put(fn);
+		async_answer_0(callid, rc);
+		return rc;
+
 hit:
-		pos = di.pos;
-		rc = fat_directory_close(&di);
-		if (rc!=EOK)
-			goto err;
 		(void) async_data_read_finalize(callid, name, str_size(name) + 1);
-		bytes = (pos - spos)+1;
+		bytes = (pos - spos) + 1;
 	}
 
@@ -1147,5 +1231,5 @@
 		return ENOENT;
 	nodep = FAT_NODE(fn);
-
+	
 	ipc_callid_t callid;
 	size_t len;
@@ -1163,10 +1247,10 @@
 	 * but this one greatly simplifies fat_write(). Note that we can afford
 	 * to do this because the client must be ready to handle the return
-	 * value signalizing a smaller number of bytes written.
-	 */
+	 * value signalizing a smaller number of bytes written. 
+	 */ 
 	bytes = min(len, BPS(bs) - pos % BPS(bs));
 	if (bytes == BPS(bs))
 		flags |= BLOCK_FLAGS_NOREAD;
-
+	
 	boundary = ROUND_UP(nodep->size, BPC(bs));
 	if (pos < boundary) {
@@ -1211,6 +1295,6 @@
 		 */
 		unsigned nclsts;
-		fat_cluster_t mcl, lcl;
-
+		fat_cluster_t mcl, lcl; 
+ 
 		nclsts = (ROUND_UP(pos + bytes, BPC(bs)) - boundary) / BPC(bs);
 		/* create an independent chain of nclsts clusters in all FATs */
@@ -1296,5 +1380,5 @@
 		nodep->size = size;
 		nodep->dirty = true;		/* need to sync node */
-		rc = EOK;
+		rc = EOK;	
 	} else {
 		/*
@@ -1317,5 +1401,5 @@
 		nodep->size = size;
 		nodep->dirty = true;		/* need to sync node */
-		rc = EOK;
+		rc = EOK;	
 	}
 out:
@@ -1360,10 +1444,10 @@
 	if (!fn)
 		return ENOENT;
-
+	
 	fat_node_t *nodep = FAT_NODE(fn);
-
+	
 	nodep->dirty = true;
 	rc = fat_node_sync(nodep);
-
+	
 	fat_node_put(fn);
 	return rc;
