Index: uspace/app/ext2info/ext2info.c
===================================================================
--- uspace/app/ext2info/ext2info.c	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/app/ext2info/ext2info.c	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -92,5 +92,5 @@
 	}
 
-	rc = ext2_superblock_read_direct(&superblock, handle);
+	rc = ext2_superblock_read_direct(handle, &superblock);
 	if (rc != EOK)  {
 		printf(NAME ": Error reading superblock.\n");
Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/lib/block/libblock.c	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -2,4 +2,5 @@
  * Copyright (c) 2008 Jakub Jermar
  * Copyright (c) 2008 Martin Decky
+ * Copyright (c) 2011 Martin Sucha
  * All rights reserved.
  *
@@ -809,4 +810,56 @@
 }
 
+/** Read bytes directly from the device (bypass cache)
+ * 
+ * @param devmap_handle	Device handle of the block device.
+ * @param abs_offset	Absolute offset in bytes where to start reading
+ * @param bytes			Number of bytes to read
+ * @param data			Buffer that receives the data
+ * 
+ * @return		EOK on success or negative error code on failure.
+ */
+int block_read_bytes_direct(devmap_handle_t devmap_handle, aoff64_t abs_offset,
+    size_t bytes, void *data)
+{
+	int rc;
+	size_t phys_block_size;
+	size_t buf_size;
+	void *buffer;
+	aoff64_t first_block;
+	aoff64_t last_block;
+	size_t blocks;
+	size_t offset;
+	
+	rc = block_get_bsize(devmap_handle, &phys_block_size);
+	if (rc != EOK) {
+		return rc;
+	}
+	
+	// calculate data position and required space
+	first_block = abs_offset / phys_block_size;
+	offset = abs_offset % phys_block_size;
+	last_block = (abs_offset + bytes - 1) / phys_block_size;
+	blocks = last_block - first_block + 1;
+	buf_size = blocks * phys_block_size;
+	
+	// read the data into memory
+	buffer = malloc(buf_size);
+	if (buffer == NULL) {
+		return ENOMEM;
+	}
+	
+	rc = block_read_direct(devmap_handle, first_block, blocks, buffer);
+	if (rc != EOK) {
+		free(buffer);
+		return rc;
+	}
+	
+	// copy the data from the buffer
+	memcpy(data, buffer + offset, bytes);
+	free(buffer);
+	
+	return EOK;
+}
+
 /** Read blocks from block device.
  *
Index: uspace/lib/block/libblock.h
===================================================================
--- uspace/lib/block/libblock.h	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/lib/block/libblock.h	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -2,4 +2,5 @@
  * Copyright (c) 2008 Jakub Jermar
  * Copyright (c) 2008 Martin Decky 
+ * Copyright (c) 2011 Martin Sucha 
  * All rights reserved.
  *
@@ -113,4 +114,5 @@
 extern int block_get_nblocks(devmap_handle_t, aoff64_t *);
 extern int block_read_direct(devmap_handle_t, aoff64_t, size_t, void *);
+extern int block_read_bytes_direct(devmap_handle_t, aoff64_t, size_t, void *);
 extern int block_write_direct(devmap_handle_t, aoff64_t, size_t, const void *);
 
Index: uspace/lib/ext2/libext2.h
===================================================================
--- uspace/lib/ext2/libext2.h	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/lib/ext2/libext2.h	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -75,6 +75,5 @@
 inline uint32_t	ext2_superblock_get_fragments_per_group(ext2_superblock_t *sb);
 
-int ext2_superblock_read_direct(ext2_superblock_t **superblock,
-								devmap_handle_t dev);
+int ext2_superblock_read_direct(devmap_handle_t, ext2_superblock_t **);
 
 int ext2_filesystem_init(ext2_filesystem_t *fs, devmap_handle_t dev);
Index: uspace/lib/ext2/libext2_filesystem.c
===================================================================
--- uspace/lib/ext2/libext2_filesystem.c	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/lib/ext2/libext2_filesystem.c	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -37,58 +37,5 @@
 #include <errno.h>
 #include <libblock.h>
-#include <mem.h>
 #include <malloc.h>
-
-int ext2_superblock_read_direct(ext2_superblock_t **superblock,
-								devmap_handle_t dev) {
-	int rc;
-	size_t phys_block_size;
-	size_t buf_size;
-	uint8_t *buffer;
-	size_t first_block;
-	size_t last_block;
-	size_t blocks;
-	size_t offset;
-	ext2_superblock_t *tmp_superblock;
-	
-	rc = block_get_bsize(dev, &phys_block_size);
-	if (rc != EOK) {
-		return rc;
-	}
-	
-	// calculate superblock position and required space
-	first_block = EXT2_SUPERBLOCK_OFFSET / phys_block_size;
-	offset = EXT2_SUPERBLOCK_OFFSET % phys_block_size;
-	last_block = EXT2_SUPERBLOCK_LAST_BYTE / phys_block_size;
-	blocks = last_block - first_block + 1;
-	buf_size = blocks * phys_block_size;
-	
-	// read the superblock into memory
-	buffer = malloc(buf_size);
-	if (buffer == NULL) {
-		return ENOMEM;
-	}
-	
-	rc = block_read_direct(dev, first_block, blocks, buffer);
-	if (rc != EOK) {
-		free(buffer);
-		return rc;
-	}
-	
-	// copy the superblock from the buffer
-	// as it may not be at the start of the block
-	// (i.e. blocks larger than 1K)
-	tmp_superblock = malloc(EXT2_SUPERBLOCK_SIZE);
-	if (tmp_superblock == NULL) {
-		free(buffer);
-		return ENOMEM;
-	}
-	
-	memcpy(tmp_superblock, buffer + offset, EXT2_SUPERBLOCK_SIZE);
-	free(buffer);
-	(*superblock) = tmp_superblock;
-	
-	return EOK;
-}
 
 /**
@@ -108,5 +55,5 @@
 	}
 	
-	rc = ext2_superblock_read_direct(&temp_superblock, dev);
+	rc = ext2_superblock_read_direct(dev, &temp_superblock);
 	if (rc != EOK) {
 		block_fini(dev);
Index: uspace/lib/ext2/libext2_superblock.c
===================================================================
--- uspace/lib/ext2/libext2_superblock.c	(revision 36bca8ebd67f3523f829bd02ddf87f9c8f0640b1)
+++ uspace/lib/ext2/libext2_superblock.c	(revision e2729490c49a14c12cbf5fc99e4232c52c784203)
@@ -35,4 +35,7 @@
 
 #include "libext2.h"
+#include <errno.h>
+#include <malloc.h>
+#include <libblock.h>
 
 /**
@@ -104,4 +107,34 @@
 
 
+/** Read a superblock directly from device (i.e. no libblock cache)
+ * 
+ * @param devmap_handle	Device handle of the block device.
+ * @param superblock	Pointer where to store pointer to new superblock
+ * 
+ * @return		EOK on success or negative error code on failure.
+ */
+int ext2_superblock_read_direct(devmap_handle_t devmap_handle,
+    ext2_superblock_t **superblock)
+{
+	void *data;
+	int rc;
+	
+	data = malloc(EXT2_SUPERBLOCK_SIZE);
+	if (data == NULL) {
+		return ENOMEM;
+	}
+	
+	rc = block_read_bytes_direct(devmap_handle, EXT2_SUPERBLOCK_OFFSET,
+	    EXT2_SUPERBLOCK_SIZE, data);
+	if (rc != EOK) {
+		free(data);
+		return rc;
+	}
+	
+	(*superblock) = data;
+	return EOK;
+}
+
+
 /** @}
  */
