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