Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 45df59abc4095939638157c9c4f73004baf03b88)
+++ uspace/lib/block/libblock.c	(revision f092718bd8d8ba6c92d58209c22e1b6756b222b5)
@@ -66,4 +66,5 @@
 	fibril_mutex_t lock;
 	size_t lblock_size;		/**< Logical block size. */
+	unsigned blocks_cluster;	/**< Physical blocks per block_t */
 	unsigned block_count;		/**< Total number of blocks. */
 	unsigned blocks_cached;		/**< Number of cached blocks. */
@@ -90,4 +91,5 @@
 static int get_block_size(int dev_phone, size_t *bsize);
 static int get_num_blocks(int dev_phone, aoff64_t *nblocks);
+static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba);
 
 static devcon_t *devcon_search(devmap_handle_t devmap_handle)
@@ -292,6 +294,9 @@
 	cache->mode = mode;
 
-	/* No block size translation a.t.m. */
-	assert(cache->lblock_size == devcon->pblock_size);
+	/* Allow 1:1 or small-to-large block size translation */
+	if (cache->lblock_size % devcon->pblock_size != 0)
+		return ENOTSUP;
+
+	cache->blocks_cluster = cache->lblock_size / devcon->pblock_size;
 
 	if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1,
@@ -329,5 +334,5 @@
 		if (b->dirty) {
 			memcpy(devcon->comm_area, b->data, b->size);
-			rc = write_blocks(devcon, b->boff, 1);
+			rc = write_blocks(devcon, b->pba, cache->blocks_cluster);
 			if (rc != EOK)
 				return rc;
@@ -465,5 +470,6 @@
 				fibril_mutex_lock(&devcon->comm_area_lock);
 				memcpy(devcon->comm_area, b->data, b->size);
-				rc = write_blocks(devcon, b->boff, 1);
+				rc = write_blocks(devcon, b->pba,
+				    cache->blocks_cluster);
 				fibril_mutex_unlock(&devcon->comm_area_lock);
 				if (rc != EOK) {
@@ -503,4 +509,5 @@
 		b->size = cache->lblock_size;
 		b->boff = boff;
+		b->pba = ba_ltop(devcon, b->boff);
 		hash_table_insert(&cache->block_hash, &key, &b->hash_link);
 
@@ -519,5 +526,5 @@
 			 */
 			fibril_mutex_lock(&devcon->comm_area_lock);
-			rc = read_blocks(devcon, b->boff, 1);
+			rc = read_blocks(devcon, b->pba, cache->blocks_cluster);
 			memcpy(b->data, devcon->comm_area, cache->lblock_size);
 			fibril_mutex_unlock(&devcon->comm_area_lock);
@@ -580,5 +587,5 @@
 		fibril_mutex_lock(&devcon->comm_area_lock);
 		memcpy(devcon->comm_area, block->data, block->size);
-		rc = write_blocks(devcon, block->boff, 1);
+		rc = write_blocks(devcon, block->pba, cache->blocks_cluster);
 		fibril_mutex_unlock(&devcon->comm_area_lock);
 		block->dirty = false;
@@ -879,4 +886,11 @@
 }
 
+/** Convert logical block address to physical block address. */
+static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
+{
+	assert(devcon->cache != NULL);
+	return lba * devcon->cache->blocks_cluster;
+}
+
 /** @}
  */
Index: uspace/lib/block/libblock.h
===================================================================
--- uspace/lib/block/libblock.h	(revision 45df59abc4095939638157c9c4f73004baf03b88)
+++ uspace/lib/block/libblock.h	(revision f092718bd8d8ba6c92d58209c22e1b6756b222b5)
@@ -73,6 +73,8 @@
 	/** Handle of the device where the block resides. */
 	devmap_handle_t devmap_handle;
-	/** Block offset on the block device. Counted in 'size'-byte blocks. */
+	/** Logical block address */
 	aoff64_t boff;
+	/** Physical block address */
+	aoff64_t pba;
 	/** Size of the block. */
 	size_t size;
Index: uspace/srv/fs/fat/fat_fat.c
===================================================================
--- uspace/srv/fs/fat/fat_fat.c	(revision 45df59abc4095939638157c9c4f73004baf03b88)
+++ uspace/srv/fs/fat/fat_fat.c	(revision f092718bd8d8ba6c92d58209c22e1b6756b222b5)
@@ -671,4 +671,6 @@
 	int rc;
 
+	printf("fat_sanity_check() begin\n");
+
 	/* Check number of FATs. */
 	if (bs->fatcnt == 0)
@@ -677,6 +679,10 @@
 	/* Check total number of sectors. */
 
+	printf("fat_sanity_check() totsec\n");
+
 	if (bs->totsec16 == 0 && bs->totsec32 == 0)
 		return ENOTSUP;
+
+	printf("fat_sanity_check() totsec16 vs 32\n");
 
 	if (bs->totsec16 != 0 && bs->totsec32 != 0 &&
@@ -684,11 +690,17 @@
 		return ENOTSUP;
 
+	printf("fat_sanity_check() media descriptor\n");
+
 	/* Check media descriptor. Must be between 0xf0 and 0xff. */
 	if ((bs->mdesc & 0xf0) != 0xf0)
 		return ENOTSUP;
 
+	printf("fat_sanity_check() sec_pre_fat\n");
+
 	/* Check number of sectors per FAT. */
 	if (bs->sec_per_fat == 0)
 		return ENOTSUP;
+
+	printf("fat_sanity_check() root dir size\n");
 
 	/*
@@ -705,16 +717,23 @@
 	/* Check signature of each FAT. */
 
+	printf("fat_sanity_check() FAT signatures\n");
+
 	for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {
+		printf("fat_sanity_check() read cluster 0\n");
 		rc = fat_get_cluster(bs, devmap_handle, fat_no, 0, &e0);
 		if (rc != EOK)
 			return EIO;
 
+		printf("fat_sanity_check() read cluster 1\n");
 		rc = fat_get_cluster(bs, devmap_handle, fat_no, 1, &e1);
 		if (rc != EOK)
 			return EIO;
 
+		printf("fat_sanity_check() check FAT mdesc\n");
 		/* Check that first byte of FAT contains the media descriptor. */
 		if ((e0 & 0xff) != bs->mdesc)
 			return ENOTSUP;
+
+		printf("fat_sanity_check() e0/e1\n");
 
 		/*
@@ -725,4 +744,5 @@
 			return ENOTSUP;
 	}
+	printf("fat_sanity_check() succeeded\n");
 
 	return EOK;
