summaryrefslogtreecommitdiffstats
path: root/test/fs/fat-noncontig-test.sh
blob: 65ed9a54bd055563dd15b5f807c1597e2f29fb66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/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}
    if [ $? -ne 0 ]; then
        echo fallocate failed - using dd instead
        dd if=/dev/zero of=${img} bs=1024 count=$((40 * 1024))
        if [ $? -ne 0 ]; then
            echo Could not create empty disk image
            exit $?
        fi
    fi
    mkfs.fat ${img}
    if [ $? -ne 0 ]; then
        echo Could not create FAT filesystem
        exit $?
    fi

    sudo mount -o loop,uid=$(id -u) ${img} ${mnt}
    if [ $? -ne 0 ]; then
        echo Could not mount test filesystem
        exit $?
    fi

    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}
    if [ $? -ne 0 ]; then
        echo Could not unmount test filesystem
        exit $?
    fi
fi

sudo mount -o ro,loop,uid=$(id -u) ${img} ${mnt}
if [ $? -ne 0 ]; then
    echo Could not mount test filesystem
    exit $?
fi
crc=0x`crc32 ${mnttestfn}`
sudo umount ${mnt}
if [ $? -ne 0 ]; then
    echo Could not unmount test filesystem
    exit $?
fi

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
if [ $? -ne 0 ]; then
    echo U-Boot exit status indicates an error
    exit $?
fi