Compare commits
1 Commits
cbeba3fbe9
...
962fc6e71d
| Author | SHA1 | Date | |
|---|---|---|---|
| 962fc6e71d |
+45
-3
@@ -39,6 +39,7 @@
|
|||||||
#include "qemu/ctype.h"
|
#include "qemu/ctype.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "qemu/units.h"
|
||||||
|
|
||||||
#ifndef S_IWGRP
|
#ifndef S_IWGRP
|
||||||
#define S_IWGRP 0
|
#define S_IWGRP 0
|
||||||
@@ -336,6 +337,9 @@ typedef struct BDRVVVFATState {
|
|||||||
int downcase_short_names;
|
int downcase_short_names;
|
||||||
|
|
||||||
Error *migration_blocker;
|
Error *migration_blocker;
|
||||||
|
#ifdef EMSCRIPTEN
|
||||||
|
GHashTable *write_overlay;
|
||||||
|
#endif
|
||||||
} BDRVVVFATState;
|
} BDRVVVFATState;
|
||||||
|
|
||||||
/* take the sector position spos and convert it to Cylinder/Head/Sector position
|
/* 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;
|
s->bs = bs;
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#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. */
|
/* Browser SD Geometry - A larger cluster keeps the synthesized 32 GiB FAT near 4 MiB. */
|
||||||
s->sectors_per_cluster = 0x40;
|
s->sectors_per_cluster = 0x40;
|
||||||
total_sectors = 32ULL * 1024 * 1024 * 1024 / BDRV_SECTOR_SIZE;
|
total_sectors = 32ULL * GiB / BDRV_SECTOR_SIZE;
|
||||||
} else
|
} else
|
||||||
#endif
|
#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++) {
|
for(i=0;i<nb_sectors;i++,sector_num++) {
|
||||||
if (sector_num >= bs->total_sectors)
|
if (sector_num >= bs->total_sectors)
|
||||||
return -1;
|
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) {
|
if (s->qcow) {
|
||||||
int64_t n;
|
int64_t n;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -3027,6 +3046,19 @@ vvfat_write(BlockDriverState *bs, int64_t sector_num,
|
|||||||
|
|
||||||
DLOG(checkpoint());
|
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 */
|
/* Check if we're operating in read-only mode */
|
||||||
if (s->qcow == NULL) {
|
if (s->qcow == NULL) {
|
||||||
return -EACCES;
|
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,
|
ret = bdrv_co_pwrite(s->qcow, sector_num * BDRV_SECTOR_SIZE,
|
||||||
nb_sectors * BDRV_SECTOR_SIZE, buf, 0);
|
nb_sectors * BDRV_SECTOR_SIZE, buf, 0);
|
||||||
if (ret < 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3205,6 +3238,12 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
|
|||||||
int size = sector2cluster(s, s->sector_count);
|
int size = sector2cluster(s, s->sector_count);
|
||||||
QDict *options;
|
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);
|
s->used_clusters = g_malloc0(size);
|
||||||
|
|
||||||
array_init(&(s->commits), sizeof(commit_t));
|
array_init(&(s->commits), sizeof(commit_t));
|
||||||
@@ -3280,6 +3319,9 @@ static void vvfat_close(BlockDriverState *bs)
|
|||||||
if (s->qcow) {
|
if (s->qcow) {
|
||||||
migrate_del_blocker(&s->migration_blocker);
|
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[] = {
|
static const char *const vvfat_strong_runtime_opts[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user