summaryrefslogtreecommitdiffstats
path: root/fs/fat
Commit message (Collapse)AuthorAgeFilesLines
* fs: fat: fix file_fat_detectfs()Heinrich Schuchardt2021-04-101-34/+4
| | | | | | | | | | | | | Up to now file_fat_detectfs() did not detect some interface types like EFI, HOST, VIRTIO. Avoid duplicate code by calling blk_get_if_type_name(). The interface type now will be shown in lower case to match all other use cases. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
* fs: fat: remove trailing periods from long nameHeinrich Schuchardt2021-02-031-2/+28
| | | | | | | | | | | | | | The FAT32 File System Specification [1] requires leading and trailing spaces as well as trailing periods of long names to be ignored. [1] Microsoft Extensible Firmware Initiative FAT32 File System Specification Version 1.03, December 6, 2000 Microsoft Corporation https://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: must not write directory '.' and '..'Heinrich Schuchardt2021-02-031-10/+3
| | | | | | | | Directories or files called '.' or '..' cannot be created or written to in any directory. Move the test to normalize_longname() to check this early. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: usage basename in file_fat_write_at, fat_mkdirHeinrich Schuchardt2021-02-031-14/+13
| | | | | | | | | | | | | | | | | | | | | This patch involves no functional change. It is just about code readability. Both in file_fat_write_at() and fat_mkdir() the incoming file or directory path are split into two parts: the parent directory and the base name. In file_fat_write_at() the value of the variable basename is assigned to the filename parameter and afterwards the variable filename is used instead of basename. It is more readable to use the variable basename and leave filename unchanged. In fat_mkdir() the base name variable is called directory. This is confusing. Call it basename like in file_fat_write_at(). This allows to rename parameter new_directory to directory in the implementation of fat_mkdir() to match the function declaration. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
* fs: fat: remove superfluous assignmentsHeinrich Schuchardt2021-01-292-4/+5
| | | | | | Do not assign a value to a variable if it is not used. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: avoid out of bounds access warningHeinrich Schuchardt2021-01-291-5/+2
| | | | | | | When copying short name plus extension refer to the encapsulating structure and not to the short name element. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: structure for name and extensionHeinrich Schuchardt2021-01-232-27/+25
| | | | | | | | | | | | | The short name and extension of FAT files are stored in adjacent fields of the directory entry. For some operations like calculating a checksum or copying both fields it is preferable to treat both as one structure. Change the definition of the directory entry structure to include a structure comprising the name and the extension field. This resolves Coverity CID 316357, CID 316350, CID 316348. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: consistent error handling for flush_dir()Heinrich Schuchardt2021-01-231-27/+31
| | | | | | | | | | | Provide function description for flush_dir(). Move all error messages for flush_dir() from the callers to the function. Move mapping of errors to -EIO to the function. Always check return value of flush_dir() (Coverity CID 316362). In fat_unlink() return -EIO if flush_dirty_fat_buffer() fails. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs/fat: implement fsuuid commandHeinrich Schuchardt2020-12-311-0/+18
| | | | | | | The FAT file system does not have a UUID but a 4 byte volume ID. Let the fsuuid command show it in XXXX-XXXX format. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: eliminate DIRENTSPERBLOCK() macroHeinrich Schuchardt2020-12-311-3/+2
| | | | | | | | | | | The FAT filesystem implementation uses several marcros referring to a magic variable name mydata which renders the code less readable. Eliminate one of them which is only used for a debug() statement. Use log_debug() instead of debug(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
* fs: fat: deletion of long file namesHeinrich Schuchardt2020-12-101-12/+76
| | | | | | | Long file names are stored in multiple directory entries. When deleting a file we must delete all of them. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: first dentry of long name in FAT iteratorHeinrich Schuchardt2020-12-101-2/+18
| | | | | | | | | | | | | | A long name is split over multiple directory entries. When deleting a file with a long name we need the first directory entry to be able to delete the whole chain. Add the necessary fields to the FAT iterator: * cluster of first directory entry * address of first directory entry * remaining entries in cluster Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: use constant DELETED_FLAGHeinrich Schuchardt2020-12-101-1/+1
| | | | | | | | When deleting a directory entry 0xe5 is written to name[0]. We have a constant for this value and should use it consistently. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: search file should not allocate clusterHeinrich Schuchardt2020-12-101-23/+6
| | | | | | | | | | Searching for a file is not a write operation. So it should not lead to the allocation of a new cluster to the directory. If we reuse deleted entries, we might not even use the new cluster and due to not flushing it the directory could be corrupted. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: reuse deleted directory entriesHeinrich Schuchardt2020-12-101-12/+22
| | | | | | | | | When creating new directory entries try to reuse entries marked as deleted. In fill_dir_slot() do not allocate new clusters as this has already been done in fat_find_empty_dentries(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: fat_find_empty_dentries()Heinrich Schuchardt2020-12-101-1/+61
| | | | | | | | Provide a function to find a series of empty directory entries. The current directory is scanned for deleted entries. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: flush new directory clusterHeinrich Schuchardt2020-12-101-9/+19
| | | | | | | | | | | | When handling long file names directory entries may be split over multiple clusters. We must make sure that new clusters are zero filled on disk. When allocating a new cluster for a directory flush it. The flushing should be executed before updating the FAT. This way if flushing fails, we still have a valid directory structure. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: set start cluster for root directoryHeinrich Schuchardt2020-12-101-1/+3
| | | | | | | | | | | When iterating over a child directory we set itr->start_clust. Do the same when over the root directory. When looking for deleted directory entries or existing short names we will have to iterate over directories a second and third time. With this patch we do not need any special logic for the root directory. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: dentry iterator for fill_dir_slot()Heinrich Schuchardt2020-12-101-1/+1
| | | | | | | | | | | For reusing deleted directory entries we have to adjust the function called to step to the next directory entry. This patch alone is not enough to actually reuse deleted directory entries as the fill_dir_slot() is still called with first never used directory entry. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: generate unique short namesHeinrich Schuchardt2020-12-101-5/+36
| | | | | | | File names must be unique within their directory. So before assigning a short name we must check that it is unique. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: call set_name() only onceHeinrich Schuchardt2020-12-101-33/+54
| | | | | | | | In set_name() we select the short name. Once this is correctly implemented this will be a performance intensive operation because we need to check that the name does not exist yet. So set_name should only be called once. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: pass shortname to fill_dir_slotHeinrich Schuchardt2020-12-101-8/+12
| | | | | | | | | | Currently we pass the short name via the directory iterator. Pass it explicitly as a parameter. This removes the requirement to set the short name in the iterator before writing the long name. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: create correct short namesHeinrich Schuchardt2020-12-101-76/+139
| | | | | | | | | | | | | | | | | | | | The current function set_name() used to create short names has the following deficiencies resolved by this patch: * Long names (e.g. FOO.TXT) are stored even if a short name is enough. * Short names with spaces are created, e.g. "A ~1.TXT". * Short names with illegal characters are created, e.g. "FOO++BAR". * Debug output does not not consider that the short file name has no concluding '\0'. The solution for the following bug is split of into a separate patch: * Short file names must be unique. This patch only provides the loop over possible short file names. Fixes: c30a15e590c ("FAT: Add FAT write feature") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: export fat_next_cluster()Heinrich Schuchardt2020-12-101-32/+74
| | | | | | | | | Rename function next_cluster() to fat_next_cluster() and export it. When creating a new directory entries we should reuse deleted entries. This requires re-scanning the directory. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: correct first cluster for '..'Heinrich Schuchardt2020-12-101-1/+5
| | | | | | | | | | | The FAT specification [1] requires that for a '..' directory entry pointing to the root directory the fields DIR_FstClusHi and DIR_FstClusLo are 0. [1] Microsoft FAT Specification, Microsoft Corporation, August 30 2005 Fixes: 31a18d570d96 ("fs: fat: support mkdir") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
* fs: fat: use ATTR_ARCH instead of anonymous 0x20Heinrich Schuchardt2020-11-291-1/+2
| | | | | | | Using constants instead of anonymous numbers increases code readability. Fixes: 704df6aa0a28 ("fs: fat: refactor write interface for a file offset") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: directory entries starting with 0x05Heinrich Schuchardt2020-11-291-2/+1
| | | | | | | | | | | | 0x05 is used as replacement letter for 0xe5 at the first position of short file names. We must not skip over directory entries starting with 0x05. Cf. Microsoft FAT Specification, August 30 2005 Fixes: 39606d462c97 ("fs: fat: handle deleted directory entries correctly") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org>
* fs: fat: avoid NULL dereference when root dir is fullHeinrich Schuchardt2020-11-291-3/+2
| | | | | | | | | | | When trying to create a file in the full root directory of a FAT32 filesystem a NULL dereference can be observed. When the root directory of a FAT16 filesystem is full fill_dir_slot() must return -1 to signal that a new directory entry could not be allocated. Fixes: cd2d727fff7e ("fs: fat: allocate a new cluster for root directory of fat32") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs/fat/fat.c: Do not perform zero block reads if there are no blocks leftJason Wessel2020-08-041-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While using u-boot with qemu's virtio driver I stumbled across a problem reading files less than sector size. On the real hardware the block reader seems ok with reading zero blocks, and while we could fix the virtio host side of qemu to deal with a zero block read instead of crashing, the u-boot fat driver should not be doing zero block reads in the first place. If you ask hardware to read zero blocks you are just going to get zero data. There may also be other hardware that responds similarly to the virtio interface so this is worth fixing. Without the patch I get the following and have to restart qemu because it dies. --------------------------------- => fatls virtio 0:1 30 cmdline.txt => fatload virtio 0:1 ${loadaddr} cmdline.txt qemu-system-aarch64: virtio: zero sized buffers are not allowed --------------------------------- With the patch I get the expected results. --------------------------------- => fatls virtio 0:1 30 cmdline.txt => fatload virtio 0:1 ${loadaddr} cmdline.txt 30 bytes read in 11 ms (2 KiB/s) => md.b ${loadaddr} 0x1E 40080000: 64 77 63 5f 6f 74 67 2e 6c 70 6d 5f 65 6e 61 62 dwc_otg.lpm_enab 40080010: 6c 65 3d 30 20 72 6f 6f 74 77 61 69 74 0a le=0 rootwait. --------------------------------- Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com> Reviewed-by: Tom Rini <trini@konsulko.com>
* fs/fat: reduce data size for FAT_WRITEHeinrich Schuchardt2020-07-111-2/+7
| | | | | | | | Allocated tmpbuf_cluster dynamically to reduce the data size added by compiling with CONFIG_FAT_WRITE. Reported-by: Tom Rini <trini@konsulko.com> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat_write: fix short name creation.Heinrich Schuchardt2020-07-071-3/+12
| | | | | | | | | | | | | Truncate file names if the buffer size is exceeded to avoid a buffer overflow. Use Sphinx style function description. Add a TODO comment. Reported-by: CID 303779 Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
* fs: fat: fix fat iterationChristian Gmeiner2020-07-071-3/+1
| | | | | | | | | | | According to the FAT specification it is valid to have files with an attribute value of 0x0. This fixes a regression where different U-Boot versions are showing different amount of files on the same storage device. With this change U-Boot shows the same number of files and folders as Linux and Windows. Fixes: 39606d462c ("fs: fat: handle deleted directory entries correctly") Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
* common: Drop log.h from common headerSimon Glass2020-05-182-0/+2
| | | | | | Move this header out of the common header. Signed-off-by: Simon Glass <sjg@chromium.org>
* part: Drop disk_partition_t typedefSimon Glass2020-05-181-3/+3
| | | | | | | We should not be using typedefs and these make it harder to use forward declarations (to reduce header file inclusions). Drop the typedef. Signed-off-by: Simon Glass <sjg@chromium.org>
* common: Drop net.h from common headerSimon Glass2020-05-182-0/+2
| | | | | | | | | | | Move this header out of the common header. Network support is used in quite a few places but it still does not warrant blanket inclusion. Note that this net.h header itself has quite a lot in it. It could be split into the driver-mode support, functions, structures, checksumming, etc. Signed-off-by: Simon Glass <sjg@chromium.org>
* Merge tag 'dm-pull-6feb20' of https://gitlab.denx.de/u-boot/custodians/u-boot-dmTom Rini2020-02-111-0/+1
|\ | | | | | | | | | | | | sandbox conversion to SDL2 TPM TEE driver Various minor sandbox video enhancements New driver model core utility functions
| * dm: core: Create a new header file for 'compat' featuresSimon Glass2020-02-051-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | At present dm/device.h includes the linux-compatible features. This requires including linux/compat.h which in turn includes a lot of headers. One of these is malloc.h which we thus end up including in every file in U-Boot. Apart from the inefficiency of this, it is problematic for sandbox which needs to use the system malloc() in some files. Move the compatibility features into a separate header file. Signed-off-by: Simon Glass <sjg@chromium.org>
* | fat: write: adjust data written in each partial writeMarek Szyprowski2020-02-071-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code for handing file overwrite incorrectly calculated the amount of data to write when writing to the last non-cluster aligned chunk. Fix this by ensuring that no more data than the 'filesize' is written to disk. While touching min()-based calculations, change it to type-safe min_t() function. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> This patch finally fixes the issue revealed by the test script from the previous patch. The correctness of the change has been also verified by the following additional test scripts: --->8-fat_test2.sh--- #!/bin/bash make sandbox_defconfig make dd if=/dev/zero of=/tmp/10M.img bs=1024 count=10k mkfs.vfat -v /tmp/10M.img cat >/tmp/cmds <<EOF x host bind 0 /tmp/10M.img fatls host 0 mw 0x1000000 0x0a434241 0x1000 # "ABC\n" mw 0x1100000 0x0a464544 0x8000 # "DEF\n" fatwrite host 0 0x1000000 file0001.raw 0x1000 fatwrite host 0 0x1000000 file0002.raw 0x1000 fatwrite host 0 0x1000000 file0003.raw 0x1000 fatwrite host 0 0x1000000 file0004.raw 0x1000 fatwrite host 0 0x1000000 file0005.raw 0x1000 fatrm host 0 file0002.raw fatrm host 0 file0004.raw fatls host 0 fatwrite host 0 0x1100000 file0007.raw 0x2000 fatwrite host 0 0x1100000 file0007.raw 0x1f00 reset EOF ./u-boot </tmp/cmds #verify rm -r /tmp/result /tmp/model mkdir /tmp/result mkdir /tmp/model yes ABC | head -c 4096 >/tmp/model/file0001.raw yes ABC | head -c 4096 >/tmp/model/file0003.raw yes ABC | head -c 4096 >/tmp/model/file0005.raw yes DEF | head -c 7936 >/tmp/model/file0007.raw mcopy -n -i /tmp/10M.img ::file0001.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0003.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0005.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0007.raw /tmp/result hd /tmp/10M.img if diff -urq /tmp/model /tmp/result then echo Test okay else echo Test fail fi --->8-fat_test3.sh--- #!/bin/bash make sandbox_defconfig make dd if=/dev/zero of=/tmp/10M.img bs=1024 count=10k mkfs.vfat -v /tmp/10M.img cat >/tmp/cmds <<EOF x host bind 0 /tmp/10M.img fatls host 0 mw 0x1000000 0x0a434241 0x1000 # "ABC\n" mw 0x1100000 0x0a464544 0x8000 # "DEF\n" fatwrite host 0 0x1000000 file0001.raw 0x1000 fatwrite host 0 0x1000000 file0002.raw 0x1000 fatwrite host 0 0x1000000 file0003.raw 0x1000 fatwrite host 0 0x1000000 file0004.raw 0x1000 fatwrite host 0 0x1000000 file0005.raw 0x1000 fatrm host 0 file0002.raw fatrm host 0 file0004.raw fatls host 0 fatwrite host 0 0x1100000 file0007.raw 0x2000 fatwrite host 0 0x1100000 file0007.raw 0x2100 reset EOF ./u-boot </tmp/cmds #verify rm -r /tmp/result /tmp/model mkdir /tmp/result mkdir /tmp/model yes ABC | head -c 4096 >/tmp/model/file0001.raw yes ABC | head -c 4096 >/tmp/model/file0003.raw yes ABC | head -c 4096 >/tmp/model/file0005.raw yes DEF | head -c 8448 >/tmp/model/file0007.raw mcopy -n -i /tmp/10M.img ::file0001.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0003.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0005.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0007.raw /tmp/result hd /tmp/10M.img if diff -urq /tmp/model /tmp/result then echo Test okay else echo Test fail fi --->8-fat_test4.sh--- #!/bin/bash make sandbox_defconfig make dd if=/dev/zero of=/tmp/10M.img bs=1024 count=10k mkfs.vfat -v /tmp/10M.img cat >/tmp/cmds <<EOF x host bind 0 /tmp/10M.img fatls host 0 mw 0x1000000 0x0a434241 0x1000 # "ABC\n" mw 0x1100000 0x0a464544 0x8000 # "DEF\n" mw 0x1200000 0x0a494847 0x8000 # "GHI\n" fatwrite host 0 0x1000000 file0001.raw 0x1000 fatwrite host 0 0x1000000 file0002.raw 0x1000 fatwrite host 0 0x1000000 file0003.raw 0x1000 fatwrite host 0 0x1000000 file0004.raw 0x1000 fatwrite host 0 0x1000000 file0005.raw 0x1000 fatrm host 0 file0002.raw fatrm host 0 file0004.raw fatls host 0 fatwrite host 0 0x1100000 file0007.raw 0x900 fatwrite host 0 0x1200000 file0007.raw 0x900 0x900 fatwrite host 0 0x1100000 file0007.raw 0x900 0x1200 fatwrite host 0 0x1200000 file0007.raw 0x900 0x1b00 reset EOF ./u-boot </tmp/cmds #verify rm -r /tmp/result /tmp/model mkdir /tmp/result mkdir /tmp/model yes ABC | head -c 4096 >/tmp/model/file0001.raw yes ABC | head -c 4096 >/tmp/model/file0003.raw yes ABC | head -c 4096 >/tmp/model/file0005.raw yes DEF | head -c 2304 >/tmp/model/file0007.raw yes GHI | head -c 2304 >>/tmp/model/file0007.raw yes DEF | head -c 2304 >>/tmp/model/file0007.raw yes GHI | head -c 2304 >>/tmp/model/file0007.raw mcopy -n -i /tmp/10M.img ::file0001.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0003.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0005.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0007.raw /tmp/result hd /tmp/10M.img if diff -urq /tmp/model /tmp/result then echo Test okay else echo Test fail fi --->8--- Feel free to prepare a proper sandbox/py_test based tests based on the provided test scripts.
* | fat: write: fix broken write to fragmented filesMarek Szyprowski2020-02-071-2/+2
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The code for handing file overwrite incorrectly assumed that the file on disk is always contiguous. This resulted in corrupting disk structure every time when write to existing fragmented file happened. Fix this by adding proper check for cluster discontinuity and adjust chunk size on each partial write. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> This patch partially fixes the issue revealed by the following test script: --->8-fat_test1.sh--- #!/bin/bash make sandbox_defconfig make dd if=/dev/zero of=/tmp/10M.img bs=1024 count=10k mkfs.vfat -v /tmp/10M.img cat >/tmp/cmds <<EOF x host bind 0 /tmp/10M.img fatls host 0 mw 0x1000000 0x0a434241 0x1000 # "ABC\n" mw 0x1100000 0x0a464544 0x8000 # "DEF\n" fatwrite host 0 0x1000000 file0001.raw 0x1000 fatwrite host 0 0x1000000 file0002.raw 0x1000 fatwrite host 0 0x1000000 file0003.raw 0x1000 fatwrite host 0 0x1000000 file0004.raw 0x1000 fatwrite host 0 0x1000000 file0005.raw 0x1000 fatrm host 0 file0002.raw fatrm host 0 file0004.raw fatls host 0 fatwrite host 0 0x1100000 file0007.raw 0x4000 fatwrite host 0 0x1100000 file0007.raw 0x4000 reset EOF ./u-boot </tmp/cmds #verify rm -r /tmp/result /tmp/model mkdir /tmp/result mkdir /tmp/model yes ABC | head -c 4096 >/tmp/model/file0001.raw yes ABC | head -c 4096 >/tmp/model/file0003.raw yes ABC | head -c 4096 >/tmp/model/file0005.raw yes DEF | head -c 16384 >/tmp/model/file0007.raw mcopy -n -i /tmp/10M.img ::file0001.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0003.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0005.raw /tmp/result mcopy -n -i /tmp/10M.img ::file0007.raw /tmp/result hd /tmp/10M.img if diff -urq /tmp/model /tmp/result then echo Test okay else echo Test fail fi --->8--- Overwritting a discontiguous test file (file0007.raw) no longer causes corruption to file0003.raw, which's data lies between the chunks of the test file. The amount of data written to disk is still incorrect, what causes damage to the file (file0005.raw), which's data lies next to the test file. This will be fixed by the next patch. Feel free to prepare a proper sandbox/py_test based tests based on the provided test scripts.
* fs: fat: handle deleted directory entries correctlyAKASHI Takahiro2019-12-051-1/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Unlink test for FAT file system seems to fail at test_unlink2. (When I added this test, I haven't seen any errors though.) for example, ===8<=== fs_obj_unlink = ['fat', '/home/akashi/tmp/uboot_sandbox_test/128MB.fat32.img'] def test_unlink2(self, u_boot_console, fs_obj_unlink): """ Test Case 2 - delete many files """ fs_type,fs_img = fs_obj_unlink with u_boot_console.log.section('Test Case 2 - unlink (many)'): output = u_boot_console.run_command('host bind 0 %s' % fs_img) for i in range(0, 20): output = u_boot_console.run_command_list([ '%srm host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i), '%sls host 0:0 dir2/0123456789abcdef%02x' % (fs_type, i)]) assert('' == ''.join(output)) output = u_boot_console.run_command( '%sls host 0:0 dir2' % fs_type) > assert('0 file(s), 2 dir(s)' in output) E AssertionError: assert '0 file(s), 2 dir(s)' in ' ./\r\r\n ../\r\r\n 0 0123456789abcdef11\r\r\n\r\r\n1 file(s), 2 dir(s)' test/py/tests/test_fs/test_unlink.py:52: AssertionError ===>8=== This can happen when fat_itr_next() wrongly detects an already- deleted directory entry. File deletion, which was added in the commit f8240ce95d64 ("fs: fat: support unlink"), is implemented by marking its entry for a short name with DELETED_FLAG, but related entry slots for a long file name are kept unmodified. (So entries will never be actually deleted from media.) To handle this case correctly, an additional check for a directory slot will be needed in fat_itr_next(). In addition, I added extra comments about long file name and short file name format in FAT file system. Although they are not directly related to the issue, I hope it will be helpful for better understandings in general. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
* fs: fat: get_contents() always returns -1 for errorsHeinrich Schuchardt2019-10-111-1/+1
| | | | | | If out of memory, return -1 and not -ENOMEM from get_contents(). Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: treat invalid FAT clusters as errorsHeinrich Schuchardt2019-10-111-10/+20
| | | | | | | When hitting an invalid FAT cluster while reading a file always print an error message and return an error code. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fat: FAT filesystem premature release of info struct.Martin Vystrčil2019-08-261-4/+0
| | | | | | | | | | | File was found on specified location. Info about file was read, but then immediately destroyed using 'free' call. As a result file size was set to 0, hence fat process didn't read any data. Premature 'free' call removed. Resources are freed right before function return. File is read correctly. Signed-off-by: Martin Vystrcil <martin.vystrcil@m-linux.cz>
* fs: fat: allocate a new cluster for root directory of fat32AKASHI Takahiro2019-05-281-2/+8
| | | | | | | | | | | | | Contrary to fat12/16, fat32 can have root directory at any location and its size can be expanded. Without this patch, root directory won't grow properly and so we will eventually fail to add files under root directory. Please note that this can happen even if you delete many files as deleted directory entries are not reclaimed but just marked as "deleted" under the current implementation. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: flush a directory cluster properlyAKASHI Takahiro2019-05-281-19/+14
| | | | | | | | | | | | | When a long name directory entry is created, multiple directory entries may be occupied across a directory cluster boundary. Since only one directory cluster is cached in a directory iterator, a first cluster must be written back to device before switching over a second cluster. Without this patch, some added files may be lost even if you don't see any failures on write operation. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: write to non-cluster-aligned root directoryAKASHI Takahiro2019-05-281-25/+53
| | | | | | | | | | | | With the commit below, fat now correctly handles a file read under a non-cluster-aligned root directory of fat12/16. Write operation should be fixed in the same manner. Fixes: commit 9b18358dc05d ("fs: fat: fix reading non-cluster-aligned root directory") Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Cc: Anssi Hannula <anssi.hannula@bitwise.fi> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: Fix possible double free of fatbufAndrew F. Davis2019-05-281-4/+5
| | | | | | | | fat_itr_root() allocates fatbuf so we free it on the exit path, if the function fails we should not free it, check the return value and skip freeing if the function fails. Signed-off-by: Andrew F. Davis <afd@ti.com>
* fs: fat: correct file name normalizationHeinrich Schuchardt2019-05-281-28/+20
| | | | | | | File names may not contain control characters (< 0x20). Simplify the coding. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
* fs: fat: fix reading non-cluster-aligned root directoryAnssi Hannula2019-04-091-13/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A FAT12/FAT16 root directory location is specified by a sector offset and it might not start at a cluster boundary. It also resides before the data area (before cluster 2). However, the current code assumes that the root directory is located at a beginning of a cluster, causing no files to be found if that is not the case. Since the FAT12/FAT16 root directory is located before the data area and is not aligned to clusters, using unsigned cluster numbers to refer to the root directory does not work well (the "cluster number" may be negative, and even allowing it be signed would not make it properly aligned). Modify the code to not use the normal cluster numbering when referring to the root directory of FAT12/FAT16 and instead use a cluster-sized offsets counted from the root directory start sector. This is a relatively common case as at least the filesystem formatter on Win7 seems to create such filesystems by default on 2GB USB sticks when "FAT" is selected (cluster size 64 sectors, rootdir size 32 sectors, rootdir starts at half a cluster before cluster 2). dosfstools mkfs.vfat does not seem to create affected filesystems. Signed-off-by: Anssi Hannula <anssi.hannula@bitwise.fi> Reviewed-by: Bernhard Messerklinger <bernhard.messerklinger@br-automation.com> Tested-by: Bernhard Messerklinger <bernhard.messerklinger@br-automation.com>
* fs: fat: fix link error when building with DEBUG=1Heinrich Schuchardt2019-02-281-3/+3
| | | | | | | | | | | | | | When compiling with DEBUG=1 an error fs/fat/fat_write.c:831: undefined reference to `__aeabi_ldivmod' occurred. We should use do_div() instead of the modulus operator. filesize and cur_pos cannot be negative. So let's use u64 to avoid warnings. Fixes: cb8af8af5ba0 ("fs: fat: support write with non-zero offset") Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>