aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorMarek Szyprowski2019-12-02 12:11:13 +0100
committerTom Rini2020-02-07 13:59:58 -0500
commit5e615b74e8c8dedcc1ad9a49a04b01a1c216d8bc (patch)
tree8f35eaafade23f43ff561127b350e21c6a6ed2af /fs
parent4dbc107f4683e45749045b97f0b529d5eb5178a9 (diff)
fat: write: fix broken write to fragmented files
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.
Diffstat (limited to 'fs')
-rw-r--r--fs/fat/fat_write.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 729cf39630d..f946030f7d8 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -794,6 +794,8 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
newclust = get_fatent(mydata, endclust);
+ if (newclust != endclust + 1)
+ break;
if (IS_LAST_CLUST(newclust, mydata->fatsize))
break;
if (CHECK_CLUST(newclust, mydata->fatsize)) {
@@ -824,8 +826,6 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
if (filesize <= cur_pos)
break;
- /* CHECK: newclust = get_fatent(mydata, endclust); */
-
if (IS_LAST_CLUST(newclust, mydata->fatsize))
/* no more clusters */
break;