Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/fs/fat/fat_fat.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -608,4 +608,74 @@
 }
 
+/** 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 fat file system.
+ */
+int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
+{
+	fat_cluster_t e0, e1;
+	unsigned fat_no;
+	int rc;
+
+	/* Check number of FATs. */
+	if (bs->fatcnt == 0)
+		return ENOTSUP;
+
+	/* Check total number of sectors. */
+
+	if (bs->totsec16 == 0 && bs->totsec32 == 0)
+		return ENOTSUP;
+
+	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
+	    bs->totsec16 != bs->totsec32) 
+		return ENOTSUP;
+
+	/* Check media descriptor. Must be between 0xf0 and 0xff. */
+	if ((bs->mdesc & 0xf0) != 0xf0)
+		return ENOTSUP;
+
+	/* Check number of sectors per FAT. */
+	if (bs->sec_per_fat == 0)
+		return ENOTSUP;
+
+	/*
+	 * Check that the root directory entries take up whole blocks.
+	 * This check is rather strict, but it allows us to treat the root
+	 * directory and non-root directories uniformly in some places.
+	 * It can be removed provided that functions such as fat_read() are
+	 * sanitized to support file systems with this property.
+	 */
+	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 < bs->fatcnt; fat_no++) {
+		rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
+		if (rc != EOK)
+			return EIO;
+
+		rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
+		if (rc != EOK)
+			return EIO;
+
+		/* Check that first byte of FAT contains the media descriptor. */
+		if ((e0 & 0xff) != bs->mdesc)
+			return ENOTSUP;
+
+		/*
+		 * Check that remaining bits of the first two entries are
+		 * set to one.
+		 */
+		if ((e0 >> 8) != 0xff || e1 != 0xffff)
+			return ENOTSUP;
+	}
+
+	return EOK;
+}
+
 /**
  * @}
Index: uspace/srv/fs/fat/fat_fat.h
===================================================================
--- uspace/srv/fs/fat/fat_fat.h	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/fs/fat/fat_fat.h	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -87,4 +87,5 @@
     off_t);
 extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);
+extern int fat_sanity_check(struct fat_bs *, dev_handle_t);
 
 #endif
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/fs/fat/fat_idx.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -531,8 +531,10 @@
 	unused_initialize(u, dev_handle);
 	fibril_mutex_lock(&unused_lock);
-	if (!unused_find(dev_handle, false))
+	if (!unused_find(dev_handle, false)) {
 		list_append(&u->link, &unused_head);
-	else
+	} else {
+		free(u);
 		rc = EEXIST;
+	}
 	fibril_mutex_unlock(&unused_lock);
 	return rc;
Index: uspace/srv/fs/fat/fat_ops.c
===================================================================
--- uspace/srv/fs/fat/fat_ops.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/fs/fat/fat_ops.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -290,74 +290,4 @@
 
 	*nodepp = nodep;
-	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 fat file system.
- */
-static int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)
-{
-	fat_cluster_t e0, e1;
-	unsigned fat_no;
-	int rc;
-
-	/* Check number of FATs. */
-	if (bs->fatcnt == 0)
-		return ENOTSUP;
-
-	/* Check total number of sectors. */
-
-	if (bs->totsec16 == 0 && bs->totsec32 == 0)
-		return ENOTSUP;
-
-	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
-	    bs->totsec16 != bs->totsec32) 
-		return ENOTSUP;
-
-	/* Check media descriptor. Must be between 0xf0 and 0xff. */
-	if ((bs->mdesc & 0xf0) != 0xf0)
-		return ENOTSUP;
-
-	/* Check number of sectors per FAT. */
-	if (bs->sec_per_fat == 0)
-		return ENOTSUP;
-
-	/*
-	 * Check that the root directory entries take up whole blocks.
-	 * This check is rather strict, but it allows us to treat the root
-	 * directory and non-root directories uniformly in some places.
-	 * It can be removed provided that functions such as fat_read() are
-	 * sanitized to support file systems with this property.
-	 */
-	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 < bs->fatcnt; fat_no++) {
-		rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);
-		if (rc != EOK)
-			return EIO;
-
-		rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);
-		if (rc != EOK)
-			return EIO;
-
-		/* Check that first byte of FAT contains the media descriptor. */
-		if ((e0 & 0xff) != bs->mdesc)
-			return ENOTSUP;
-
-		/*
-		 * Check that remaining bits of the first two entries are
-		 * set to one.
-		 */
-		if ((e0 >> 8) != 0xff || e1 != 0xffff)
-			return ENOTSUP;
-	}
-
 	return EOK;
 }
@@ -1015,4 +945,6 @@
 		cmode = CACHE_MODE_WB;
 
+	free(opts);
+
 	/* initialize libblock */
 	rc = block_init(dev_handle, BS_SIZE);
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/vfs/vfs.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -137,5 +137,5 @@
 	}
 	
-	/* TODO: cleanup after the client */
+	vfs_files_done();
 }
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/vfs/vfs.h	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -177,4 +177,5 @@
     vfs_pair_t *, ...);
 extern int vfs_open_node_internal(vfs_lookup_res_t *);
+extern int vfs_close_internal(vfs_file_t *);
 
 extern bool vfs_nodes_init(void);
@@ -188,4 +189,5 @@
 
 extern bool vfs_files_init(void);
+extern void vfs_files_done(void);
 extern vfs_file_t *vfs_file_get(int);
 extern int vfs_fd_assign(vfs_file_t *file, int fd);
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/vfs/vfs_file.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -72,4 +72,22 @@
 	}
 	return true;
+}
+
+/** Cleanup the table of open files. */
+void vfs_files_done(void)
+{
+	int i;
+
+	if (!files)
+		return;
+
+	for (i = 0; i < MAX_OPEN_FILES; i++) {
+		if (files[i]) {
+			(void) vfs_close_internal(files[i]);
+			(void) vfs_fd_free(i);
+		}
+	}
+	
+	free(files);
 }
 
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision b73c26d0a9e1cc90dc174dbf3e084e09ed5b0e02)
+++ uspace/srv/vfs/vfs_ops.c	(revision ab4bace49a15f19c4af11adbd750419e62886c26)
@@ -817,5 +817,5 @@
 }
 
-static int vfs_close_internal(vfs_file_t *file)
+int vfs_close_internal(vfs_file_t *file)
 {
 	/*
