[U-Boot,v2,2/6] fat: write: fix broken write at non-zero file offset
diff mbox series

Message ID 20190924131111.1691-3-m.szyprowski@samsung.com
State New
Delegated to: Matthias Brugger
Headers show
Series
  • Raspberry Pi4: add support for DFU over USB
Related show

Commit Message

Marek Szyprowski Sept. 24, 2019, 1:11 p.m. UTC
Handling of the start file offset was broken in the current code. Although
the code skipped the needed clusters, it then tried to continue write with
current cluster set to EOF, what caused assertion. It also lacked adjusting
filesize in case of writing at the end of file and adjusting in-cluster
offset for partial overwrite.

This patch fixes all those issues.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 fs/fat/fat_write.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

Comments

Lukasz Majewski Sept. 24, 2019, 7:47 p.m. UTC | #1
Hi Marek,

> Handling of the start file offset was broken in the current code.
> Although the code skipped the needed clusters, it then tried to
> continue write with current cluster set to EOF, what caused
> assertion. It also lacked adjusting filesize in case of writing at
> the end of file and adjusting in-cluster offset for partial overwrite.
> 
> This patch fixes all those issues.

Reviewed-by: Lukasz Majewski <lukma@denx.de>

> 
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
>  fs/fat/fat_write.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
> index 6cfa5b4565..d7a814eb0c 100644
> --- a/fs/fat/fat_write.c
> +++ b/fs/fat/fat_write.c
> @@ -756,14 +756,12 @@ set_contents(fsdata *mydata, dir_entry
> *dentptr, loff_t pos, __u8 *buffer, /* go to cluster at pos */
>  	cur_pos = bytesperclust;
>  	while (1) {
> +		newclust = get_fatent(mydata, curclust);
>  		if (pos <= cur_pos)
>  			break;
> -		if (IS_LAST_CLUST(curclust, mydata->fatsize))
> +		if (IS_LAST_CLUST(newclust, mydata->fatsize))
>  			break;
> -
> -		newclust = get_fatent(mydata, curclust);
> -		if (!IS_LAST_CLUST(newclust, mydata->fatsize) &&
> -		    CHECK_CLUST(newclust, mydata->fatsize)) {
> +		if (CHECK_CLUST(newclust, mydata->fatsize)) {
>  			debug("curclust: 0x%x\n", curclust);
>  			debug("Invalid FAT entry\n");
>  			return -1;
> @@ -772,8 +770,9 @@ set_contents(fsdata *mydata, dir_entry *dentptr,
> loff_t pos, __u8 *buffer, cur_pos += bytesperclust;
>  		curclust = newclust;
>  	}
> -	if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
> +	if (IS_LAST_CLUST(newclust, mydata->fatsize)) {
>  		assert(pos == cur_pos);
> +		filesize -= pos;
>  		goto set_clusters;
>  	}
>  
> @@ -814,6 +813,7 @@ set_contents(fsdata *mydata, dir_entry *dentptr,
> loff_t pos, __u8 *buffer, else
>  			offset = pos - cur_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");




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de

Patch
diff mbox series

diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 6cfa5b4565..d7a814eb0c 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -756,14 +756,12 @@  set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
 	/* go to cluster at pos */
 	cur_pos = bytesperclust;
 	while (1) {
+		newclust = get_fatent(mydata, curclust);
 		if (pos <= cur_pos)
 			break;
-		if (IS_LAST_CLUST(curclust, mydata->fatsize))
+		if (IS_LAST_CLUST(newclust, mydata->fatsize))
 			break;
-
-		newclust = get_fatent(mydata, curclust);
-		if (!IS_LAST_CLUST(newclust, mydata->fatsize) &&
-		    CHECK_CLUST(newclust, mydata->fatsize)) {
+		if (CHECK_CLUST(newclust, mydata->fatsize)) {
 			debug("curclust: 0x%x\n", curclust);
 			debug("Invalid FAT entry\n");
 			return -1;
@@ -772,8 +770,9 @@  set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
 		cur_pos += bytesperclust;
 		curclust = newclust;
 	}
-	if (IS_LAST_CLUST(curclust, mydata->fatsize)) {
+	if (IS_LAST_CLUST(newclust, mydata->fatsize)) {
 		assert(pos == cur_pos);
+		filesize -= pos;
 		goto set_clusters;
 	}
 
@@ -814,6 +813,7 @@  set_contents(fsdata *mydata, dir_entry *dentptr, loff_t pos, __u8 *buffer,
 		else
 			offset = pos - cur_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");