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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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: c30a15e590 ("FAT: Add FAT write feature")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
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>
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: 31a18d570d ("fs: fat: support mkdir")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Using constants instead of anonymous numbers increases code readability.
Fixes: 704df6aa0a ("fs: fat: refactor write interface for a file offset")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
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: 39606d462c ("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>
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: cd2d727fff ("fs: fat: allocate a new cluster for root directory of fat32")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
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>
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>
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>
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>
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>
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>
TPM TEE driver
Various minor sandbox video enhancements
New driver model core utility functions
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAl48iogACgkQfxc6PpAI
reaVzAf/an3/yKe6r3CVWlcRV6H/dVg1ApnnLpX7jS0p0b++oCVvOiy7z1WPXj3k
b1SSgENDeeZ/8EHio+Gf7ZidH/TGEj7L6YEFwd1t60GMkZiWEkNf4Z53tw482YG+
96hoPD+ySTW+ddIdVHWAFG2I4aEiKHANJAp/ItNdD+rLbrEwNQy+eiK5JTOk80B6
/X8AJCLZeAC1s7vs+2+WolgjT78QGzA9HHalMiublcqh0ivKKk0QeQiOKKPe8JYJ
om5YY1TxayQ60Xmo5f39/SBfzEEklxw83sU9o1tBeYzyVUpu7fQdkxiDbWdsij77
DgwLdeYQJGbN+hdSWE0gjTqyhW+lWA==
=KRoA
-----END PGP SIGNATURE-----
Merge tag 'dm-pull-6feb20' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm
sandbox conversion to SDL2
TPM TEE driver
Various minor sandbox video enhancements
New driver model core utility functions
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.
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>
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 f8240ce95d ("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>
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>
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>
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>
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>
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 9b18358dc0 ("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>
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>
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>
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: cb8af8af5b ("fs: fat: support write with non-zero offset")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Release cluster block immediately when no longer use would help to reduce
64KiB memory allocated to the memory pool.
Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
Drop the statically allocated get_contents_vfatname_block and
dynamically allocate a buffer only if required. This saves
64KiB of memory.
Signed-off-by: Stefan Agner <stefan.ag...@toradex.com>
Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
Most of the time SPL only needs very simple FAT reading, so having
CONFIG_IS_ENABLED(FAT_WRITE) to exclude it from SPL build would help
to save 64KiB default max clustersize from memory.
Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
Reviewed-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
This particular commit is causing a regression on stih410-b2260 and
other platforms when reading from FAT16. Noting that I had rebased the
original fix from Thomas onto then-current master, there is also
question from Akashi-san if the change is still needed after other FAT
fixes that have gone in.
This reverts commit a68b0e11ea.
Reported-by: Patrice Chotard <patrice.chotard@st.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Thomas RIENOESSL <thomas.rienoessl@bachmann.info>
Signed-off-by: Tom Rini <trini@konsulko.com>
The long name apparently can be accumulated using multiple
13-byte slots. Unfortunately we never checked how many we
can actually fit in the buffer we are reading to.
Signed-off-by: Patrick Wildt <patrick@blueri.se>
The cluster size specifies how many sectors make up a cluster. A
cluster size of zero makes no sense, as it would mean that the
cluster is made up of no sectors. This will later lead into a
division by zero in sect_to_clust(), so better take care of that
early.
The MAX_CLUSTSIZE define can reduced using a define to make some
room in low-memory system. Unfortunately if the code reads a
filesystem with a bigger cluster size it will overflow the buffer.
Signed-off-by: Patrick Wildt <patrick@blueri.se>
This fixes problems accessing drives formated under
Windows as FAT16.
Signed-off-by: Thomas RIENOESSL <thomas.rienoessl@bachmann.info>
[trini: Rebase on top of f528c140c8]
Signed-off-by: Tom Rini <trini@konsulko.com>