get_fatent_value(...) flushes changed FAT entries to disk when fetching
the next FAT blocks, in every other aspect it is identical to
get_fatent(...).
Provide a stub implementation for flush_dirty_fat_buffer if
CONFIG_FAT_WRITE is not set. Calling flush_dirty_fat_buffer during read
only operation is fine as it checks if any buffers needs flushing.
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
The FAT is read/flushed in segments of 6 (FATBUFBLOCKS) disk sectors. The
last segment may be less than 6 sectors, cap the length.
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
The u-boot command fatwrite empties FAT clusters from the beginning
till the end of the file.
Specifically for FAT12 it fails to detect the end of the file and goes
beyond the file bounds thus corrupting the file system.
Additionally, FAT entry chaining-up into a file is not implemented
for FAT12.
The users normally workaround this by re-formatting the partition as
FAT16/FAT32, like here:
https://github.com/FEDEVEL/openrex-uboot-v2015.10/issues/1
The patch fixes the bounds of a file and FAT12 entries chaining into
a file, including EOF markup.
Signed-off-by: Philipp Skadorov <philipp.skadorov@savoirfairelinux.com>
fill_dir_slot use get_contents_vfatname_block as a temporary buffer for
constructing a list of dir_slot entries. To save the memory and providing
correct type of memory for above usage, a local buffer with accurate size
declaration is introduced.
The local array size 640 is used because for long file name entry,
each entry use 32 bytes, one entry can store up to 13 characters.
The maximum number of entry possible is 20. So, total size is
32*20=640bytes.
Signed-off-by: Genevieve Chan <ccheauya@altera.com>
Signed-off-by: Tien Fong Chee <tfchee@altera.com>
Current description does not match the function behaviour.
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Acked-by: Lukasz Majewski <l.majewski@samsung.com>
The code caches 6 sectors of the FAT. On FAT traversal, the old contents
needs to be flushed to disk, but only if any FAT entries had been modified.
Explicitly flag the buffer on modification.
Currently, creating a new file traverses the whole FAT up to the first
free cluster and rewrites the on-disk blocks.
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
fatlength is a local variable which is no more used after the assignment.
s_name is not used in the function, save the strncpy.
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Acked-by: Lukasz Majewski <l.majewski@samsung.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
To ease conversion to driver model, add helper functions which deal with
calling each block device method. With driver model we can reimplement these
functions with the same arguments.
Use inline functions to avoid increasing code size on some boards.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
This will allow the implementation to make use of data in the block_dev
structure beyond the base device number. This will be useful so that eMMC
block devices can encompass the HW partition ID rather than treating this
out-of-band. Equally, the existence of the priv field is crying out for
this patch to exist.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Overwriting an empty file not created by U-Boot did not work, and it
could even corrupt the FAT. Moreover, creating empty files or emptying
existing files allocated a cluster, which is not standard.
Fix this by always keeping empty files clusterless as specified by
Microsoft (the start cluster must be set to 0 in the directory entry in
that case), and by supporting overwriting such files.
Signed-off-by: Benoît Thébaudeau <benoit@wsystem.com>
curclust was used instead of newclust in the debug() calls and in one
CHECK_CLUST() call, which could skip a failure case.
Signed-off-by: Benoît Thébaudeau <benoit@wsystem.com>
set_contents() had uselessly split calls to set_cluster(). Merge these
calls, which removes some cases of set_cluster() being called with a
size of zero.
Signed-off-by: Benoît Thébaudeau <benoit@wsystem.com>
set_cluster() was using a temporary buffer without enforcing its
alignment for DMA and cache. Moreover, it did not check the alignment of
the passed buffer, which can come directly from applicative code or from
the user.
This could cause random data corruption, which has been observed on
i.MX25 writing to an SD card.
Fix this by only passing ARCH_DMA_MINALIGN-aligned buffers to
disk_write(), which requires the introduction of a buffer bouncing
mechanism for the misaligned buffers passed to set_cluster().
By the way, improve the handling of the corresponding return values from
disk_write():
- print them with debug() in case of error,
- consider that there is an error is disk_write() returns a smaller
block count than the requested one, not only if its return value is
negative.
After this change, set_cluster() and get_cluster() are almost
symmetrical.
Signed-off-by: Benoît Thébaudeau <benoit@wsystem.com>
It is very common that FAT code is using following pattern:
if (disk_{read|write}() < 0)
return -1;
Up till now the above code was dead, since disk_{read|write) could only
return value >= 0.
As a result some errors from medium layer (i.e. eMMC/SD) were not caught.
The above behavior was caused by block_{read|write|erase} declared at
struct block_dev_desc (@part.h). It returns unsigned long, where 0
indicates error and > 0 indicates that medium operation was correct.
This patch as error regards 0 returned from block_{read|write|erase}
when nr_blocks is grater than zero. Read/Write operation with nr_blocks=0
should return 0 and hence is not considered as an error.
Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Test HW: Odroid XU3 - Exynos 5433
The changes to introduce loff_t into filesize means that we need to do
64bit math on 32bit platforms. Make sure we use the right wrappers for
these operations.
Cc: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Cc: Suriyan Ramasami <suriyan.r@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Rini <trini@ti.com>
Tested-by: Pierre Aubert <p.aubert@staubli.com>
Change the internal FAT functions to use loff_t for offsets.
Signed-off-by: Suriyan Ramasami <suriyan.r@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
[trini: Fix fs/fat/fat.c for min3 updates]
Signed-off-by: Tom Rini <trini@ti.com>
- update the comments regarding lbaint_t usage
- cleanup casting of values related to the lbaint_t type
- cleanup of a type that requires a u64
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae <srae@broadcom.com>
When write a file into FAT file system, it will search a match file in
root dir. So the find_directory_entry() will get the first cluster of
root dir content and search the directory item one by one. If the file
is not found, we will call get_fatent_value() to get next cluster of root
dir via lookup the FAT table and continue the search.
The issue is in FAT16/12 system, we cannot get root dir's next clust
from FAT table. The FAT table only be use to find the clust of data
aera in FAT16/12.
In FAT16/12 if the clust is in root dir, the clust number is a negative
number or 0, 1. Since root dir is located in front of the data area.
Data area start clust #2. So the root dir clust number should < 2.
This patch will check above situation before call get_fatenv_value().
If curclust is < 2, include minus number, we just increase one on the
curclust since root dir is in continous cluster.
The patch also add a sanity check for entry in get_fatenv_value().
Signed-off-by: Josh Wu <josh.wu@atmel.com>
In fat_write.c, the last clust condition check is incorrect:
if ((curclust >= 0xffffff8) || (curclust >= 0xfff8)) {
... ...
}
For example, in FAT32 if curclust is 0x11000. It is a valid clust.
But on above condition check, it will be think as a last clust.
So the correct last clust check should be:
in fat32, curclust >= 0xffffff8
in fat16, curclust >= 0xfff8
in fat12, curclust >= 0xff8
This patch correct the last clust check.
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Use of malloc of do_fat_write() causes cache error on ARM v7 platforms.
Perhaps, the same problem will occur at any other CPUs.
This replaces malloc with memalign to fix cache buffer alignment.
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Signed-off-by: Yoshiyuki Ito <yoshiyuki.ito.ub@renesas.com>
Tested-by: Hector Palacios <hector.palacios@digi.com>
Curently memcpy copies string without null terminating char because
function strlen returns only number of characters excluding
null terminating character. Replace memcpy with strcpy.
Signed-off-by: Piotr Wilczek <p.wilczek@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
CC: Tom Rini <trini@ti.com>
In the set_cluster() function, it will convert the buffer size to sector
numbers. Then call disk_write() to write by sector.
For remaining buffer, the size is less than a sector, call disk_write()
again to write them in one sector.
But if the total buffer size is less then one sector, the original code
will call disk_write() with zero sector number. It is unnecessary.
So this patch fix this. Now it will not call disk_write() if total buffer size
is less than one sector.
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Bugfix:
Here at this place we need the fat size in sectors not bytes.
This was found during code review when adding support for storage
devices with blocksizes != 512.
Signed-off-by: Egbert Eich <eich@suse.com>
ifdefs in the code are making it harder to read.
The use of simple if(vfat_enabled) makes no more code and is cleaner.
(the code is discarded by the compiler instead of the preprocessor.)
NB: if -O0 is used, the code won't be discarded
and bonus, now the code compiles even if CONFIG_SUPPORT_VFAT is not
defined.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
toupper/tolower function are already declared, so use them.
Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
Acked-by: Marek Vasut <marex@denx.de>
Acked-by: Stefano Babic <sbabic@denx.de>
The mkcksum() function now takes one parameter, the pointer to
11-byte wide character array, which it then operates on.
Currently, the function is wrongly passed (dir_entry)->name, which
is only 8-byte wide character array. Though by further inspecting
the dir_entry structure, it can be noticed that the name[8] entry
is immediatelly followed by ext[3] entry. Thus, name[8] and ext[3]
in the dir_entry structure actually work as this 11-byte wide array
since they're placed right next to each other by current compiler
behavior.
Depending on this is obviously wrong, thus fix this by correctly
passing both (dir_entry)->name and (dir_entry)->ext to the mkcksum()
function and adjust the function appropriately.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Tom Rini <trini@ti.com>
When storage devices contain files larger than the embedded RAM, it is
useful to be able to read these files by chunks, e.g. for a software
update to the embedded NAND Flash from an external storage device (USB
stick, SD card, etc.).
Hence, this patch makes it possible by adding a new FAT API to read
files from a given position. This patch also adds this feature to the
fatload command.
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Cc: Wolfgang Denk <wd@denx.de>
Signed-off-by: Tom Rini <trini@ti.com>
Fix:
fat_write.c: In function 'find_directory_entry':
fat_write.c:826:8: warning: variable 'prevcksum' set but not used
[-Wunused-but-set-variable]
fat_write.c: In function 'do_fat_write':
fat_write.c:933:6: warning: variable 'root_cluster' set but not used
[-Wunused-but-set-variable]
fat_write.c:925:12: warning: variable 'slotptr' set but not used
[-Wunused-but-set-variable]
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Donggeun Kim <dg77.kim@samsung.com>
Acked-by: Maximilian Schwerin <mvs@tigris.de>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
This patch removes compile errors introduced by
commit 9813b750f3
'fs/fat: Fix FAT detection to support non-DOS partition tables'
fat_write.c: In function 'disk_write':
fat_write.c:54: error: 'part_offset' undeclared (first use in this function)
fat_write.c:54: error: (Each undeclared identifier is reported only once
fat_write.c:54: error: for each function it appears in.)
fat_write.c: In function 'do_fat_write':
fat_write.c:950: error: 'part_size' undeclared (first use in this function)
These errors only appear when this code is enabled by
defining CONFIG_FAT_WRITE option.
This patch was originally part of
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/121847
Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Maximilian Schwerin <mvs@tigris.de>
Fixed patch author and added all needed SoB from the original patch
and also submitter's SoB. Extended commit log.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
After susccessful write to the FAT partition,
fsck program may print warning message due to different FAT,
provided that the filesystem supports two FATs.
This patch makes the second FAT to be same with the first one
when writing a file.
Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Writing a file to the FAT partition didn't work while a
test using a CF card. The test was done on mpc5200 based
board (powerpc). There is a number of problems in FAT
write code:
Compiler warning:
fat_write.c: In function 'file_fat_write':
fat_write.c:326: warning: 'counter' may be used uninitialized
in this function
fat_write.c:326: note: 'counter' was declared here
'l_filename' string is not terminated, so a file name
with garbage at the end is used as a file name as shown
by debug code.
Return value of set_contents() is not checked properly
so actually a file won't be written at all (as checked
using 'fatls' after a write attempt with 'fatwrite'
command).
do_fat_write() doesn't return the number of written bytes
if no error happened. However the return value of this
function is used to show the number of written bytes
in do_fat_fswrite().
The patch adds some debug code and fixes above mentioned
problems and also fixes a typo in error output.
NOTE: after a successful write to the FAT partition (under
U-Boot) the partition was checked under Linux using fsck.
The partition needed fixing FATs:
-bash-3.2# fsck -a /dev/sda1
fsck 1.39 (29-May-2006)
dosfsck 2.11, 12 Mar 2005, FAT32, LFN
FATs differ but appear to be intact. Using first FAT.
Performing changes.
Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Donggeun Kim <dg77.kim@samsung.com>
Cc: Aaron Williams <Aaron.Williams@cavium.com>
Acked-by: Donggeun Kim <dg77.kim@samsung.com>
In some cases, saving data in RAM as a file with FAT format is required.
This patch allows the file to be written in FAT formatted partition.
The usage is similar with reading a file.
First, fat_register_device function is called before file_fat_write function
in order to set target partition.
Then, file_fat_write function is invoked with desired file name,
start ram address for writing data, and file size.
Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>