summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Warren <swarren@wwwdotorg.org>2015-10-03 13:56:47 -0600
committerTom Rini <trini@konsulko.com>2015-10-24 13:50:34 -0400
commit4a28274227d085d77d46709dc94ccc3d69610f53 (patch)
tree3f8d07a1e4ab9cf7b938a36cdeb145d9287d380b
parent7861204c9af7fec1ea9b41541c272516235a6c93 (diff)
downloadu-boot-4a28274227d085d77d46709dc94ccc3d69610f53.tar.gz
u-boot-4a28274227d085d77d46709dc94ccc3d69610f53.tar.bz2
u-boot-4a28274227d085d77d46709dc94ccc3d69610f53.zip
test: fat: add test of non-contiguous file reads
In my patch series to replace fs/fat with "ff.c", I enhanced ff.c to optimize file reading, so that reads of contiguous clusters are submitted to the IO device as a single read. This test attempts to torture-test edge-cases of that enhancement. BTW, the only way I found to validate that this script actually does create non-contiguous files was to manually inspect the FAT bitmap in a hex dump of the FAT image. hdparm --fibmap doesn't work on loop-mounted filesystems. filefrag -v -e seems to lie about files being contiguous when they aren't. Signed-off-by: Stephen Warren <swarren@wwwdotorg.org> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>
-rwxr-xr-xtest/fs/fat-noncontig-test.sh113
1 files changed, 113 insertions, 0 deletions
diff --git a/test/fs/fat-noncontig-test.sh b/test/fs/fat-noncontig-test.sh
new file mode 100755
index 0000000000..f153c97bbf
--- /dev/null
+++ b/test/fs/fat-noncontig-test.sh
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+# (C) Copyright 2015 Stephen Warren
+#
+# SPDX-License-Identifier: GPL-2.0+
+
+# This script tests U-Boot's FAT filesystem code's ability to read non-
+# contiguous files.
+
+# When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c
+# always reads files cluster-by-cluster, which results in poor performance.
+# This was solved by adding a patch to ff.c to coalesce reads of adjacent
+# clusters. Since this patch needed to correctly handle non-contiguous files,
+# this test was written to validate that.
+#
+# To execute the test, simply run it from the U-Boot source root directory:
+#
+# cd u-boot
+# ./test/fs/fat-noncontig-test.sh
+#
+# The test will create a FAT filesystem image, record the CRC of a randomly
+# generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to
+# read the file and validate that the CRCs match. Expected output is shown
+# below. The important part of the log is the penultimate line that contains
+# either "PASS" or "FAILURE".
+#
+# mkfs.fat 3.0.26 (2014-03-07)
+#
+#
+# U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600)
+#
+# DRAM: 128 MiB
+# Using default environment
+#
+# In: serial
+# Out: lcd
+# Err: lcd
+# Net: No ethernet found.
+# => host bind 0 sandbox/fat-noncontig.img
+# => load host 0:0 1000 noncontig.img
+# 33584964 bytes read in 18 ms (1.7 GiB/s)
+# => crc32 1000 $filesize 0
+# crc32 for 00001000 ... 02008743 ==> 6a080523
+# => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi
+# PASS
+# => reset
+#
+# All temporary files used by this script are created in ./sandbox to avoid
+# polluting the source tree. test/fs/fs-test.sh also uses this directory for
+# the same purpose.
+#
+# TODO: Integrate this (and many other corner-cases e.g. different types of
+# FAT) with fs-test.sh so that a single script tests everything filesystem-
+# related.
+
+odir=sandbox
+img=${odir}/fat-noncontig.img
+mnt=${odir}/mnt
+fill=/dev/urandom
+testfn=noncontig.img
+mnttestfn=${mnt}/${testfn}
+crcaddr=0
+loadaddr=1000
+
+for prereq in fallocate mkfs.fat dd crc32; do
+ if [ ! -x "`which $prereq`" ]; then
+ echo "Missing $prereq binary. Exiting!"
+ exit 1
+ fi
+done
+
+make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8
+
+mkdir -p ${mnt}
+if [ ! -f ${img} ]; then
+ fallocate -l 40M ${img}
+ mkfs.fat ${img}
+
+ sudo mount -o loop,uid=$(id -u) ${img} ${mnt}
+
+ for ((sects=8; sects < 512; sects += 8)); do
+ fn=${mnt}/keep-${sects}.img
+ dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
+ fn=${mnt}/remove-${sects}.img
+ dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1
+ done
+
+ rm -f ${mnt}/remove-*.img
+
+ # 511 deliberately to trigger a file size that's not a multiple of the
+ # sector size (ignoring sizes that are multiples of both).
+ dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1
+
+ sudo umount ${mnt}
+fi
+
+sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt}
+crc=0x`crc32 ${mnttestfn}`
+sudo umount ${mnt}
+
+crc=`printf %02x%02x%02x%02x \
+ $((${crc} & 0xff)) \
+ $(((${crc} >> 8) & 0xff)) \
+ $(((${crc} >> 16) & 0xff)) \
+ $((${crc} >> 24))`
+
+./sandbox/u-boot << EOF
+host bind 0 ${img}
+load host 0:0 ${loadaddr} ${testfn}
+crc32 ${loadaddr} \$filesize ${crcaddr}
+if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi
+reset
+EOF