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>master
parent
7861204c9a
commit
4a28274227
@ -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 |
Loading…
Reference in new issue