Index: .bzrignore
===================================================================
--- .bzrignore	(revision c7faade1e70bec5bf883d616456fdd2644446a49)
+++ .bzrignore	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -46,4 +46,5 @@
 uspace/app/test_serial/test_serial
 uspace/app/tester/tester
+uspace/app/testread/testread
 uspace/app/tetris/tetris
 uspace/app/top/top
@@ -71,4 +72,5 @@
 uspace/dist/app/test_serial
 uspace/dist/app/tester
+uspace/dist/app/testread
 uspace/dist/app/tetris
 uspace/dist/app/top
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision c7faade1e70bec5bf883d616456fdd2644446a49)
+++ boot/Makefile.common	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -136,4 +136,5 @@
 	$(USPACE_PATH)/app/taskdump/taskdump \
 	$(USPACE_PATH)/app/tester/tester \
+	$(USPACE_PATH)/app/testread/testread \
 	$(USPACE_PATH)/app/tetris/tetris \
 	$(USPACE_PATH)/app/trace/trace \
Index: tools/gentestfile.py
===================================================================
--- tools/gentestfile.py	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
+++ tools/gentestfile.py	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2011 Martin Sucha
+# 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.
+#
+
+"""
+Generate a file to be used by app/testread
+"""
+
+import struct
+import sys
+
+if len(sys.argv) < 2:
+	print "Usage: gentestfile.py <count of 64-bit numbers to output>"
+	exit()
+
+m = long(sys.argv[1])
+i = 0
+pow_2_64 = 2 ** 64
+st = struct.Struct('<Q')
+while i < m:
+	sys.stdout.write(st.pack(i))
+	i = (i + 1) % pow_2_64
+
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision c7faade1e70bec5bf883d616456fdd2644446a49)
+++ uspace/Makefile	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -49,4 +49,5 @@
 	app/taskdump \
 	app/tester \
+	app/testread \
 	app/tetris \
 	app/trace \
Index: uspace/app/testread/Makefile
===================================================================
--- uspace/app/testread/Makefile	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
+++ uspace/app/testread/Makefile	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2011 Martin Sucha
+# 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 = ../..
+BINARY = testread
+
+SOURCES = \
+	testread.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/testread/testread.c
===================================================================
--- uspace/app/testread/testread.c	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
+++ uspace/app/testread/testread.c	(revision 6b3e7f7f1ea010da52ad03f26e452a512453cb0e)
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * 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 test
+ * @{
+ */
+
+/**
+ * @file	testread.c
+ * This program checks if the file contains a pattern of increasing
+ * 64 bit unsigned integers (that may overflow at some point)
+ * stored in little endian byte order.
+ * This is to verify that the filesystem reads
+ * the files correctly.
+ * If the file does not contain specified pattern, it stops
+ * at the point where the file does not match and prints
+ * the byte offset at which the error occured.
+ * While checking the file, the program displays how many megabytes
+ * it has already read, how long it took to read the last megabyte
+ * and current and average read speed.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mem.h>
+#include <devmap.h>
+#include <byteorder.h>
+#include <sys/types.h>
+#include <sys/typefmt.h>
+#include <inttypes.h>
+#include <errno.h>
+#include <time.h>
+
+#define NAME	"testread"
+#define BUFELEMS 1024
+#define MBYTE (1024*1024)
+
+static void syntax_print(void);
+
+int main(int argc, char **argv)
+{
+
+	FILE *file;
+	char *file_name;
+	uint64_t *buf;
+	uint64_t expected;
+	aoff64_t offset;
+	aoff64_t next_mark;
+	aoff64_t last_mark;
+	unsigned int i;
+	
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	// Skip program name
+	--argc; ++argv;
+	
+	if (argc != 1) {
+		printf(NAME ": Error, unexpected argument.\n");
+		syntax_print();
+		return 1;
+	}
+	
+	file_name = *argv;
+	
+	buf = calloc(BUFELEMS, sizeof(uint64_t));
+	if (buf == NULL) {
+		printf("Failed allocating buffer\n");
+		return 1;
+	}
+	
+	file = fopen(file_name, "r");
+	if (file == NULL) {
+		printf("Failed opening file\n");
+		return 1;
+	}
+	
+	expected = 0;
+	offset = 0;
+	next_mark = 0;
+	last_mark = 0;
+	struct timeval prev_time;
+	struct timeval start_time;
+	int rc;
+	rc = gettimeofday(&start_time, NULL);
+	if (rc != EOK) {
+		printf("gettimeofday failed\n");
+		fclose(file);
+		free(buf);
+		return 1;
+	}
+	prev_time = start_time;
+	
+	while (!feof(file)) {
+		size_t elems = fread(buf, sizeof(uint64_t), BUFELEMS, file);
+		if (ferror(file)) {
+			printf("Failed reading file\n");
+			fclose(file);
+			free(buf);
+			return 1;
+		}
+		
+		for (i = 0; i < elems; i++) {
+			if (uint64_t_le2host(buf[i]) != expected) {
+				printf("Unexpected value at offset %" PRIuOFF64 "\n", offset);
+				fclose(file);
+				free(buf);
+				return 2;
+			}
+			expected++;
+			offset += sizeof(uint64_t);
+		}
+		
+		if (offset >= next_mark) {
+			struct timeval cur_time;
+			rc = gettimeofday(&cur_time, NULL);
+			if (rc != EOK) {
+				printf("gettimeofday failed\n");
+				fclose(file);
+				free(buf);
+				return 1;
+			}
+			uint32_t last_run = cur_time.tv_sec - prev_time.tv_sec;
+			uint32_t total_time = cur_time.tv_sec - start_time.tv_sec;
+			if (last_run > 0 && total_time > 0) {
+				printf("%" PRIuOFF64 "M - time: %u s, "
+				    "cur: %"PRIuOFF64 " B/s, avg: %" PRIuOFF64 " B/s\n",
+				    offset / MBYTE, last_run,
+				    (offset-last_mark)/last_run,
+				    offset/total_time);
+				prev_time = cur_time;
+				last_mark = offset;
+			}
+			next_mark += MBYTE;
+		}
+	}
+	
+	fclose(file);
+	free(buf);
+
+	return 0;
+}
+
+
+static void syntax_print(void)
+{
+	printf("syntax: testread <filename>\n");
+}
+
+/**
+ * @}
+ */
