Commit 4a28274227d085d77d46709dc94ccc3d69610f53
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>
Showing 1 changed file with 113 additions and 0 deletions Side-by-side Diff
1 | +#!/bin/bash | |
2 | + | |
3 | +# (C) Copyright 2015 Stephen Warren | |
4 | +# | |
5 | +# SPDX-License-Identifier: GPL-2.0+ | |
6 | + | |
7 | +# This script tests U-Boot's FAT filesystem code's ability to read non- | |
8 | +# contiguous files. | |
9 | + | |
10 | +# When porting the ff.c FAT parsing code into U-Boot, it was found that ff.c | |
11 | +# always reads files cluster-by-cluster, which results in poor performance. | |
12 | +# This was solved by adding a patch to ff.c to coalesce reads of adjacent | |
13 | +# clusters. Since this patch needed to correctly handle non-contiguous files, | |
14 | +# this test was written to validate that. | |
15 | +# | |
16 | +# To execute the test, simply run it from the U-Boot source root directory: | |
17 | +# | |
18 | +# cd u-boot | |
19 | +# ./test/fs/fat-noncontig-test.sh | |
20 | +# | |
21 | +# The test will create a FAT filesystem image, record the CRC of a randomly | |
22 | +# generated file in the image, build U-Boot sandbox, invoke U-Boot sandbox to | |
23 | +# read the file and validate that the CRCs match. Expected output is shown | |
24 | +# below. The important part of the log is the penultimate line that contains | |
25 | +# either "PASS" or "FAILURE". | |
26 | +# | |
27 | +# mkfs.fat 3.0.26 (2014-03-07) | |
28 | +# | |
29 | +# | |
30 | +# U-Boot 2015.10-rc4-00018-g4b22a3e5513f (Oct 03 2015 - 13:49:23 -0600) | |
31 | +# | |
32 | +# DRAM: 128 MiB | |
33 | +# Using default environment | |
34 | +# | |
35 | +# In: serial | |
36 | +# Out: lcd | |
37 | +# Err: lcd | |
38 | +# Net: No ethernet found. | |
39 | +# => host bind 0 sandbox/fat-noncontig.img | |
40 | +# => load host 0:0 1000 noncontig.img | |
41 | +# 33584964 bytes read in 18 ms (1.7 GiB/s) | |
42 | +# => crc32 1000 $filesize 0 | |
43 | +# crc32 for 00001000 ... 02008743 ==> 6a080523 | |
44 | +# => if itest.l *0 != 2305086a; then echo FAILURE; else echo PASS; fi | |
45 | +# PASS | |
46 | +# => reset | |
47 | +# | |
48 | +# All temporary files used by this script are created in ./sandbox to avoid | |
49 | +# polluting the source tree. test/fs/fs-test.sh also uses this directory for | |
50 | +# the same purpose. | |
51 | +# | |
52 | +# TODO: Integrate this (and many other corner-cases e.g. different types of | |
53 | +# FAT) with fs-test.sh so that a single script tests everything filesystem- | |
54 | +# related. | |
55 | + | |
56 | +odir=sandbox | |
57 | +img=${odir}/fat-noncontig.img | |
58 | +mnt=${odir}/mnt | |
59 | +fill=/dev/urandom | |
60 | +testfn=noncontig.img | |
61 | +mnttestfn=${mnt}/${testfn} | |
62 | +crcaddr=0 | |
63 | +loadaddr=1000 | |
64 | + | |
65 | +for prereq in fallocate mkfs.fat dd crc32; do | |
66 | + if [ ! -x "`which $prereq`" ]; then | |
67 | + echo "Missing $prereq binary. Exiting!" | |
68 | + exit 1 | |
69 | + fi | |
70 | +done | |
71 | + | |
72 | +make O=${odir} -s sandbox_defconfig && make O=${odir} -s -j8 | |
73 | + | |
74 | +mkdir -p ${mnt} | |
75 | +if [ ! -f ${img} ]; then | |
76 | + fallocate -l 40M ${img} | |
77 | + mkfs.fat ${img} | |
78 | + | |
79 | + sudo mount -o loop,uid=$(id -u) ${img} ${mnt} | |
80 | + | |
81 | + for ((sects=8; sects < 512; sects += 8)); do | |
82 | + fn=${mnt}/keep-${sects}.img | |
83 | + dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 | |
84 | + fn=${mnt}/remove-${sects}.img | |
85 | + dd if=${fill} of=${fn} bs=512 count=${sects} >/dev/null 2>&1 | |
86 | + done | |
87 | + | |
88 | + rm -f ${mnt}/remove-*.img | |
89 | + | |
90 | + # 511 deliberately to trigger a file size that's not a multiple of the | |
91 | + # sector size (ignoring sizes that are multiples of both). | |
92 | + dd if=${fill} of=${mnttestfn} bs=511 >/dev/null 2>&1 | |
93 | + | |
94 | + sudo umount ${mnt} | |
95 | +fi | |
96 | + | |
97 | +sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt} | |
98 | +crc=0x`crc32 ${mnttestfn}` | |
99 | +sudo umount ${mnt} | |
100 | + | |
101 | +crc=`printf %02x%02x%02x%02x \ | |
102 | + $((${crc} & 0xff)) \ | |
103 | + $(((${crc} >> 8) & 0xff)) \ | |
104 | + $(((${crc} >> 16) & 0xff)) \ | |
105 | + $((${crc} >> 24))` | |
106 | + | |
107 | +./sandbox/u-boot << EOF | |
108 | +host bind 0 ${img} | |
109 | +load host 0:0 ${loadaddr} ${testfn} | |
110 | +crc32 ${loadaddr} \$filesize ${crcaddr} | |
111 | +if itest.l *${crcaddr} != ${crc}; then echo FAILURE; else echo PASS; fi | |
112 | +reset | |
113 | +EOF |
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d
-
mentioned in commit 34a60d