Compare commits
1 Commits
cbeba3fbe9
...
962fc6e71d
| Author | SHA1 | Date | |
|---|---|---|---|
| 962fc6e71d |
+45
-3
@@ -39,6 +39,7 @@
|
||||
#include "qemu/ctype.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/units.h"
|
||||
|
||||
#ifndef S_IWGRP
|
||||
#define S_IWGRP 0
|
||||
@@ -336,6 +337,9 @@ typedef struct BDRVVVFATState {
|
||||
int downcase_short_names;
|
||||
|
||||
Error *migration_blocker;
|
||||
#ifdef EMSCRIPTEN
|
||||
GHashTable *write_overlay;
|
||||
#endif
|
||||
} BDRVVVFATState;
|
||||
|
||||
/* take the sector position spos and convert it to Cylinder/Head/Sector position
|
||||
@@ -1246,10 +1250,13 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
s->bs = bs;
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
if (!floppy && s->fat_type == 32) {
|
||||
if (!floppy && s->fat_type == 16) {
|
||||
s->sectors_per_cluster = 0x10;
|
||||
total_sectors = 32ULL * MiB / BDRV_SECTOR_SIZE;
|
||||
} else if (!floppy && s->fat_type == 32) {
|
||||
/* Browser SD Geometry - A larger cluster keeps the synthesized 32 GiB FAT near 4 MiB. */
|
||||
s->sectors_per_cluster = 0x40;
|
||||
total_sectors = 32ULL * 1024 * 1024 * 1024 / BDRV_SECTOR_SIZE;
|
||||
total_sectors = 32ULL * GiB / BDRV_SECTOR_SIZE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -1516,6 +1523,18 @@ vvfat_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sector
|
||||
for(i=0;i<nb_sectors;i++,sector_num++) {
|
||||
if (sector_num >= bs->total_sectors)
|
||||
return -1;
|
||||
#ifdef EMSCRIPTEN
|
||||
if (s->write_overlay) {
|
||||
int64_t key = sector_num;
|
||||
const uint8_t *overlay = g_hash_table_lookup(s->write_overlay,
|
||||
&key);
|
||||
if (overlay) {
|
||||
memcpy(buf + i * BDRV_SECTOR_SIZE, overlay,
|
||||
BDRV_SECTOR_SIZE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (s->qcow) {
|
||||
int64_t n;
|
||||
int ret;
|
||||
@@ -3027,6 +3046,19 @@ vvfat_write(BlockDriverState *bs, int64_t sector_num,
|
||||
|
||||
DLOG(checkpoint());
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
if (s->write_overlay) {
|
||||
for (i = 0; i < nb_sectors; i++) {
|
||||
int64_t *key = g_new(int64_t, 1);
|
||||
uint8_t *sector = g_malloc(BDRV_SECTOR_SIZE);
|
||||
*key = sector_num + i;
|
||||
memcpy(sector, buf + i * BDRV_SECTOR_SIZE, BDRV_SECTOR_SIZE);
|
||||
g_hash_table_replace(s->write_overlay, key, sector);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if we're operating in read-only mode */
|
||||
if (s->qcow == NULL) {
|
||||
return -EACCES;
|
||||
@@ -3129,7 +3161,8 @@ DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sec
|
||||
ret = bdrv_co_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE,
|
||||
nb_sectors * BDRV_SECTOR_SIZE, buf, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error writing to qcow backend\n");
|
||||
fprintf(stderr, "Error writing to qcow backend: %s (%d)\n",
|
||||
strerror(-ret), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3205,6 +3238,12 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
|
||||
int size = sector2cluster(s, s->sector_count);
|
||||
QDict *options;
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
s->write_overlay = g_hash_table_new_full(g_int64_hash, g_int64_equal,
|
||||
g_free, g_free);
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
s->used_clusters = g_malloc0(size);
|
||||
|
||||
array_init(&(s->commits), sizeof(commit_t));
|
||||
@@ -3280,6 +3319,9 @@ static void vvfat_close(BlockDriverState *bs)
|
||||
if (s->qcow) {
|
||||
migrate_del_blocker(&s->migration_blocker);
|
||||
}
|
||||
#ifdef EMSCRIPTEN
|
||||
g_clear_pointer(&s->write_overlay, g_hash_table_destroy);
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *const vvfat_strong_runtime_opts[] = {
|
||||
|
||||
Reference in New Issue
Block a user