vvfat: allow some writes to bootsector

'reserved1' field in bootsector is used to mark volume dirty, or need to verify.
Allow writes to bootsector which only changes the 'reserved1' field.

This fixes I/O errors on Windows guests.

Resolves: https://bugs.launchpad.net/qemu/+bug/1889421
Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
Message-Id: <20221010175511.3414357-2-hpoussin@reactos.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Hervé Poussineau 2022-10-10 19:55:10 +02:00 committed by Kevin Wolf
parent 69fbfff95e
commit d0f95b6ca0
1 changed files with 25 additions and 1 deletions

View File

@ -2993,11 +2993,35 @@ DLOG(checkpoint());
vvfat_close_current_file(s);
if (sector_num == s->offset_to_bootsector && nb_sectors == 1) {
/*
* Write on bootsector. Allow only changing the reserved1 field,
* used to mark volume dirtiness
*/
unsigned char *bootsector = s->first_sectors
+ s->offset_to_bootsector * 0x200;
/*
* LATER TODO: if FAT32, this is wrong (see init_directories(),
* which always creates a FAT16 bootsector)
*/
const int reserved1_offset = offsetof(bootsector_t, u.fat16.reserved1);
for (i = 0; i < 0x200; i++) {
if (i != reserved1_offset && bootsector[i] != buf[i]) {
fprintf(stderr, "Tried to write to protected bootsector\n");
return -1;
}
}
/* Update bootsector with the only updatable byte, and return success */
bootsector[reserved1_offset] = buf[reserved1_offset];
return 0;
}
/*
* Some sanity checks:
* - do not allow writing to the boot sector
*/
if (sector_num < s->offset_to_fat)
return -1;