* [PATCH 1/3] vvfat: Fix bug in writing to middle of file
2024-03-27 20:11 [PATCH 0/3] vvfat: Fix bugs in writing and reading files Amjad Alsharafi
@ 2024-03-27 20:11 ` Amjad Alsharafi
2024-03-27 20:11 ` [PATCH 2/3] vvfat: Fix usage of `info.file.offset` Amjad Alsharafi
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Amjad Alsharafi @ 2024-03-27 20:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Hanna Reitz, open list:vvfat, Amjad Alsharafi
Before this commit, the behavior when calling `commit_one_file` for
example with `offset=0x2000` (second cluster), what will happen is that
we won't fetch the next cluster from the fat, and instead use the first
cluster for the read operation.
This is due to off-by-one error here, where `i=0x2000 !< offset=0x2000`,
thus not fetching the next cluster.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
---
block/vvfat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/vvfat.c b/block/vvfat.c
index 9d050ba3ae..ab342f0743 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2525,7 +2525,7 @@ commit_one_file(BDRVVVFATState* s, int dir_index, uint32_t offset)
return -1;
}
- for (i = s->cluster_size; i < offset; i += s->cluster_size)
+ for (i = s->cluster_size; i <= offset; i += s->cluster_size)
c = modified_fat_get(s, c);
fd = qemu_open_old(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
--
2.44.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/3] vvfat: Fix usage of `info.file.offset`
2024-03-27 20:11 [PATCH 0/3] vvfat: Fix bugs in writing and reading files Amjad Alsharafi
2024-03-27 20:11 ` [PATCH 1/3] vvfat: Fix bug in writing to middle of file Amjad Alsharafi
@ 2024-03-27 20:11 ` Amjad Alsharafi
2024-03-27 20:11 ` [PATCH 3/3] ffvat: Fix reading files with non-continuous clusters Amjad Alsharafi
2024-04-13 9:51 ` [PATCH 0/3] vvfat: Fix bugs in writing and reading files -- PING Amjad Alsharafi
3 siblings, 0 replies; 7+ messages in thread
From: Amjad Alsharafi @ 2024-03-27 20:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Hanna Reitz, open list:vvfat, Amjad Alsharafi
The field is marked as "the offset in the file (in clusters)", but it
was being used like this
`cluster_size*(nums)+mapping->info.file.offset`, which is incorrect.
Additionally, removed the `abort` when `first_mapping_index` does not
match, as this matches the case when adding new clusters for files, and
its inevitable that we reach this condition when doing that if the
clusters are not after one another, so there is no reason to `abort`
here, execution continues and the new clusters are written to disk
correctly.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
---
block/vvfat.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/block/vvfat.c b/block/vvfat.c
index ab342f0743..cb3ab81e29 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1408,7 +1408,7 @@ read_cluster_directory:
assert(s->current_fd);
- offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
+ offset=s->cluster_size*((cluster_num - s->current_mapping->begin) + s->current_mapping->info.file.offset);
if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
return -3;
s->cluster=s->cluster_buffer;
@@ -1929,8 +1929,8 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const ch
(mapping->mode & MODE_DIRECTORY) == 0) {
/* was modified in qcow */
- if (offset != mapping->info.file.offset + s->cluster_size
- * (cluster_num - mapping->begin)) {
+ if (offset != s->cluster_size
+ * ((cluster_num - mapping->begin) + mapping->info.file.offset)) {
/* offset of this cluster in file chain has changed */
abort();
copy_it = 1;
@@ -1944,7 +1944,6 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, direntry_t* direntry, const ch
if (mapping->first_mapping_index != first_mapping_index
&& mapping->info.file.offset > 0) {
- abort();
copy_it = 1;
}
@@ -2404,7 +2403,7 @@ static int commit_mappings(BDRVVVFATState* s,
(mapping->end - mapping->begin);
} else
next_mapping->info.file.offset = mapping->info.file.offset +
- mapping->end - mapping->begin;
+ (mapping->end - mapping->begin);
mapping = next_mapping;
}
--
2.44.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/3] ffvat: Fix reading files with non-continuous clusters
2024-03-27 20:11 [PATCH 0/3] vvfat: Fix bugs in writing and reading files Amjad Alsharafi
2024-03-27 20:11 ` [PATCH 1/3] vvfat: Fix bug in writing to middle of file Amjad Alsharafi
2024-03-27 20:11 ` [PATCH 2/3] vvfat: Fix usage of `info.file.offset` Amjad Alsharafi
@ 2024-03-27 20:11 ` Amjad Alsharafi
2024-03-29 6:31 ` Amjad Alsharafi
2024-04-13 9:51 ` [PATCH 0/3] vvfat: Fix bugs in writing and reading files -- PING Amjad Alsharafi
3 siblings, 1 reply; 7+ messages in thread
From: Amjad Alsharafi @ 2024-03-27 20:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Hanna Reitz, open list:vvfat, Amjad Alsharafi
When reading with `read_cluster` we get the `mapping` with
`find_mapping_for_cluster` and then we call `open_file` for this
mapping.
The issue appear when its the same file, but a second cluster that is
not immediately after it, imagine clusters `500 -> 503`, this will give
us 2 mappings one has the range `500..501` and another `503..504`, both
point to the same file, but different offsets.
When we don't open the file since the path is the same, we won't assign
`s->current_mapping` and thus accessing way out of bound of the file.
From our example above, after `open_file` (that didn't open anything) we
will get the offset into the file with
`s->cluster_size*(cluster_num-s->current_mapping->begin)`, which will
give us `0x2000 * (504-500)`, which is out of bound for this mapping and
will produce some issues.
Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
---
block/vvfat.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/block/vvfat.c b/block/vvfat.c
index cb3ab81e29..87165abc26 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1360,15 +1360,22 @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping)
{
if(!mapping)
return -1;
+ int new_path = 1;
if(!s->current_mapping ||
- strcmp(s->current_mapping->path,mapping->path)) {
- /* open file */
- int fd = qemu_open_old(mapping->path,
+ s->current_mapping->first_mapping_index!=mapping->first_mapping_index ||
+ (new_path = strcmp(s->current_mapping->path,mapping->path))) {
+
+ if (new_path) {
+ /* open file */
+ int fd = qemu_open_old(mapping->path,
O_RDONLY | O_BINARY | O_LARGEFILE);
- if(fd<0)
- return -1;
- vvfat_close_current_file(s);
- s->current_fd = fd;
+ if(fd<0)
+ return -1;
+ vvfat_close_current_file(s);
+
+ s->current_fd = fd;
+ }
+ assert(s->current_fd);
s->current_mapping = mapping;
}
return 0;
--
2.44.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 3/3] ffvat: Fix reading files with non-continuous clusters
2024-03-27 20:11 ` [PATCH 3/3] ffvat: Fix reading files with non-continuous clusters Amjad Alsharafi
@ 2024-03-29 6:31 ` Amjad Alsharafi
0 siblings, 0 replies; 7+ messages in thread
From: Amjad Alsharafi @ 2024-03-29 6:31 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Hanna Reitz, open list:vvfat
I noticed the issue in the commit message 'ffvat' should be 'vvfat',
I'll fix it in the next version.
On Thu, Mar 28, 2024 at 04:11:27AM +0800, Amjad Alsharafi wrote:
> When reading with `read_cluster` we get the `mapping` with
> `find_mapping_for_cluster` and then we call `open_file` for this
> mapping.
> The issue appear when its the same file, but a second cluster that is
> not immediately after it, imagine clusters `500 -> 503`, this will give
> us 2 mappings one has the range `500..501` and another `503..504`, both
> point to the same file, but different offsets.
>
> When we don't open the file since the path is the same, we won't assign
> `s->current_mapping` and thus accessing way out of bound of the file.
>
> From our example above, after `open_file` (that didn't open anything) we
> will get the offset into the file with
> `s->cluster_size*(cluster_num-s->current_mapping->begin)`, which will
> give us `0x2000 * (504-500)`, which is out of bound for this mapping and
> will produce some issues.
>
> Signed-off-by: Amjad Alsharafi <amjadsharafi10@gmail.com>
> ---
> block/vvfat.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/block/vvfat.c b/block/vvfat.c
> index cb3ab81e29..87165abc26 100644
> --- a/block/vvfat.c
> +++ b/block/vvfat.c
> @@ -1360,15 +1360,22 @@ static int open_file(BDRVVVFATState* s,mapping_t* mapping)
> {
> if(!mapping)
> return -1;
> + int new_path = 1;
> if(!s->current_mapping ||
> - strcmp(s->current_mapping->path,mapping->path)) {
> - /* open file */
> - int fd = qemu_open_old(mapping->path,
> + s->current_mapping->first_mapping_index!=mapping->first_mapping_index ||
> + (new_path = strcmp(s->current_mapping->path,mapping->path))) {
> +
> + if (new_path) {
> + /* open file */
> + int fd = qemu_open_old(mapping->path,
> O_RDONLY | O_BINARY | O_LARGEFILE);
> - if(fd<0)
> - return -1;
> - vvfat_close_current_file(s);
> - s->current_fd = fd;
> + if(fd<0)
> + return -1;
> + vvfat_close_current_file(s);
> +
> + s->current_fd = fd;
> + }
> + assert(s->current_fd);
> s->current_mapping = mapping;
> }
> return 0;
> --
> 2.44.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 0/3] vvfat: Fix bugs in writing and reading files -- PING
2024-03-27 20:11 [PATCH 0/3] vvfat: Fix bugs in writing and reading files Amjad Alsharafi
` (2 preceding siblings ...)
2024-03-27 20:11 ` [PATCH 3/3] ffvat: Fix reading files with non-continuous clusters Amjad Alsharafi
@ 2024-04-13 9:51 ` Amjad Alsharafi
2024-04-30 13:21 ` Amjad Alsharafi
3 siblings, 1 reply; 7+ messages in thread
From: Amjad Alsharafi @ 2024-04-13 9:51 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Hanna Reitz, open list:vvfat
Ping to the vvfat maintainers.
^ permalink raw reply [flat|nested] 7+ messages in thread