- hw/nvme: Remove redundant dma_blk_write - tests/avocado/machine_s390_ccw_virtio: Adapt test to new default resolution - edid: set default resolution to 1280x800 (WXGA) - iotests/308: Fix for CAP_DAC_OVERRIDE - hvf: remove unused but set variable - vvfat: Fix vvfat_write() for writes before the root directory - hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT() - hw/pci: Remove unused pci_irq_pulse() method - ui/gtk: fix leaks found wtih fuzzing - target/i386: fix size of EBP writeback in gen_enter() - tests/qtest/fuzz: fix memleak in qos_fuzz.c - hw/core/loader: gunzip(): fix memory leak on error path - migration: fix a typo - scsi: fetch unit attention when creating the request - raw-format: Fix error message for invalid offset/size - tcg: Reset data_gen_ptr correctly - Fix calculation of minimum in colo_compare_tcp - hw/intc: Don't clear pending bits on IRQ lowering - target/arm: Drop user-only special case in sve_stN_r - usb-hub: Fix handling port power control messages - target/ppc: Set ctx->opcode for decode_insn32() - linux-user: Add proper strace format strings for getdents()/getdents64() - linux-user: Fix TARGET_PROT_SEM for XTENSA - linux-user/hppa: Set TASK_UNMAPPED_BASE to 0xfa000000 for hppa arch - linux-user/hppa: Dump IIR on register dump - tests: Fix typo in check-help output - qdev-core.h: Fix wrongly named reference to TYPE_SPLIT_IRQ - hw/scsi/megasas: Simplify using the ldst API - gqa-win: get_pci_info: Clean dev_info if handle is valid - target/ppc: Fix 7448 support - vvfat: Fix size of temporary qcow file - docs: Correct 'vhost-user-blk' spelling - jackaudio: use ifdefs to hide unavailable functions - simplebench: Fix Python syntax error (reported by LGTM) - python: update type hints for mypy 0.930 - Python/aqmp: fix type definitions for mypy 0.920 - tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc() - hw/ppc/e500: Prefer QOM cast - hw/ppc/e500: Remove unused "irqs" parameter - hw/ppc/e500: Add missing device tree properties to i2c controller node - linux-user: Show timespec on strace for futex() - linux-user: Add strace for clock_nanosleep() - linux-user: Fix strace of chmod() if mode == 0 - linux-user: Log failing executable in EXCP_DUMP() - linux-user: Add pidfd_open(), pidfd_send_signal() and pidfd_getfd() syscalls Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com> (cherry picked from commit 87ebac5b5cfb97ddb7ac2af097703758fb0751c4)
100 lines
3.3 KiB
Diff
100 lines
3.3 KiB
Diff
From 64b53f59bccb8ec3251826c06d74adbc7b3cad36 Mon Sep 17 00:00:00 2001
|
|
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
|
|
Date: Mon, 16 Dec 2024 10:27:44 +0800
|
|
Subject: [PATCH] vvfat: Fix vvfat_write() for writes before the root directory
|
|
|
|
cherry picked from commit b9b8860d24676ec59c878d5206ea6bcfc87af798
|
|
|
|
The calculation in sector2cluster() is done relative to the offset of
|
|
the root directory. Any writes to blocks before the start of the root
|
|
directory (in particular, writes to the FAT) result in negative values,
|
|
which are not handled correctly in vvfat_write().
|
|
|
|
This changes sector2cluster() to return a signed value, and makes sure
|
|
that vvfat_write() doesn't try to find mappings for negative cluster
|
|
number. It clarifies the code in vvfat_write() to make it more obvious
|
|
that the cluster numbers can be negative.
|
|
|
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
Message-Id: <20211209152231.23756-1-kwolf@redhat.com>
|
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
|
|
---
|
|
block/vvfat.c | 30 ++++++++++++++++++++++--------
|
|
1 file changed, 22 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/block/vvfat.c b/block/vvfat.c
|
|
index 3691c4774e..935a10bdd3 100644
|
|
--- a/block/vvfat.c
|
|
+++ b/block/vvfat.c
|
|
@@ -882,7 +882,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
|
return 0;
|
|
}
|
|
|
|
-static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
|
|
+static inline int32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
|
|
{
|
|
return (sector_num - s->offset_to_root_dir) / s->sectors_per_cluster;
|
|
}
|
|
@@ -2983,6 +2983,7 @@ static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
|
|
{
|
|
BDRVVVFATState *s = bs->opaque;
|
|
int i, ret;
|
|
+ int first_cluster, last_cluster;
|
|
|
|
DLOG(checkpoint());
|
|
|
|
@@ -3001,9 +3002,20 @@ DLOG(checkpoint());
|
|
if (sector_num < s->offset_to_fat)
|
|
return -1;
|
|
|
|
- for (i = sector2cluster(s, sector_num);
|
|
- i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
|
|
- mapping_t* mapping = find_mapping_for_cluster(s, i);
|
|
+ /*
|
|
+ * Values will be negative for writes to the FAT, which is located before
|
|
+ * the root directory.
|
|
+ */
|
|
+ first_cluster = sector2cluster(s, sector_num);
|
|
+ last_cluster = sector2cluster(s, sector_num + nb_sectors - 1);
|
|
+
|
|
+ for (i = first_cluster; i <= last_cluster;) {
|
|
+ mapping_t *mapping = NULL;
|
|
+
|
|
+ if (i >= 0) {
|
|
+ mapping = find_mapping_for_cluster(s, i);
|
|
+ }
|
|
+
|
|
if (mapping) {
|
|
if (mapping->read_only) {
|
|
fprintf(stderr, "Tried to write to write-protected file %s\n",
|
|
@@ -3043,8 +3055,9 @@ DLOG(checkpoint());
|
|
}
|
|
}
|
|
i = mapping->end;
|
|
- } else
|
|
+ } else {
|
|
i++;
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -3058,10 +3071,11 @@ DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sec
|
|
return ret;
|
|
}
|
|
|
|
- for (i = sector2cluster(s, sector_num);
|
|
- i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
|
|
- if (i >= 0)
|
|
+ for (i = first_cluster; i <= last_cluster; i++) {
|
|
+ if (i >= 0) {
|
|
s->used_clusters[i] |= USED_ALLOCATED;
|
|
+ }
|
|
+ }
|
|
|
|
DLOG(checkpoint());
|
|
/* TODO: add timeout */
|
|
--
|
|
2.41.0.windows.1
|
|
|