[U-Boot] [PATCH v4 2/6] fat: write: adjust data written in each partial write

Marek Szyprowski m.szyprowski at samsung.com
Mon Dec 2 12:11:14 CET 2019


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 at 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.
---
 fs/fat/fat_write.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index f946030f7d..8e4a235d7c 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -813,7 +813,9 @@ set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
 			offset = 0;
 		else
 			offset = pos - cur_pos;
-		wsize = min(cur_pos + actsize, filesize) - pos;
+		wsize = min_t(unsigned long long, actsize, filesize - cur_pos);
+		wsize -= offset;
+
 		if (get_set_cluster(mydata, curclust, offset,
 				    buffer, wsize, &actsize)) {
 			printf("Error get-and-setting cluster\n");
-- 
2.17.1



More information about the U-Boot mailing list