Fixed issue in emubd where noop erases start out-of-sync with disk
Because reproducibility is extremely important, emubd always zeros blocks on the first erase, even when erase_value=-1. Well, at least it should be. We were correctly zeroing the blocks in RAM, but if erase_value=-1 we were leaving the disk unzeroed, causing the disk to fall out of sync. Fixed by zeroing disk in lfs_emubd_createcfg, even if erase_value=-1. Also I went ahead and dropped the bd->disk->scratch block. We're already allocating RAM-backed blocks on erase anyways, so keeping scratch around doesn't really gain us anything anymore. Now there is just a temporary allocation in lfs_emubd_createcfg to zero the disk efficiently during initialization.
This commit is contained in:
+20
-27
@@ -138,7 +138,6 @@ int lfs_emubd_createcfg(const struct lfs_config *cfg, const char *path,
|
||||
return LFS_ERR_NOMEM;
|
||||
}
|
||||
bd->disk->rc = 1;
|
||||
bd->disk->scratch = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
bd->disk->fd = open(bd->cfg->disk_path,
|
||||
@@ -153,31 +152,28 @@ int lfs_emubd_createcfg(const struct lfs_config *cfg, const char *path,
|
||||
return err;
|
||||
}
|
||||
|
||||
// if we're emulating erase values, we can keep a block around in
|
||||
// memory of just the erase state to speed up emulated erases
|
||||
if (bd->cfg->erase_value != -1) {
|
||||
bd->disk->scratch = malloc(cfg->block_size);
|
||||
if (!bd->disk->scratch) {
|
||||
LFS_EMUBD_TRACE("lfs_emubd_createcfg -> %d", LFS_ERR_NOMEM);
|
||||
return LFS_ERR_NOMEM;
|
||||
}
|
||||
memset(bd->disk->scratch,
|
||||
bd->cfg->erase_value,
|
||||
cfg->block_size);
|
||||
// go ahead and erase all of the disk, otherwise the file will not
|
||||
// match our internal representation
|
||||
uint8_t *scratch = malloc(cfg->block_size);
|
||||
if (!scratch) {
|
||||
LFS_EMUBD_TRACE("lfs_emubd_createcfg -> %d", LFS_ERR_NOMEM);
|
||||
return LFS_ERR_NOMEM;
|
||||
}
|
||||
memset(scratch,
|
||||
(bd->cfg->erase_value != -1) ? bd->cfg->erase_value : 0,
|
||||
cfg->block_size);
|
||||
|
||||
// go ahead and erase all of the disk, otherwise the file will not
|
||||
// match our internal representation
|
||||
for (size_t i = 0; i < cfg->block_count; i++) {
|
||||
ssize_t res = write(bd->disk->fd,
|
||||
bd->disk->scratch,
|
||||
cfg->block_size);
|
||||
if (res < 0) {
|
||||
int err = -errno;
|
||||
LFS_EMUBD_TRACE("lfs_emubd_create -> %d", err);
|
||||
return err;
|
||||
}
|
||||
for (size_t i = 0; i < cfg->block_count; i++) {
|
||||
ssize_t res = write(bd->disk->fd, scratch, cfg->block_size);
|
||||
if (res < 0) {
|
||||
int err = -errno;
|
||||
free(scratch);
|
||||
LFS_EMUBD_TRACE("lfs_emubd_create -> %d", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
free(scratch);
|
||||
}
|
||||
|
||||
LFS_EMUBD_TRACE("lfs_emubd_createcfg -> %d", 0);
|
||||
@@ -216,7 +212,6 @@ int lfs_emubd_destroy(const struct lfs_config *cfg) {
|
||||
bd->disk->rc -= 1;
|
||||
if (bd->disk->rc == 0) {
|
||||
close(bd->disk->fd);
|
||||
free(bd->disk->scratch);
|
||||
free(bd->disk);
|
||||
}
|
||||
}
|
||||
@@ -418,9 +413,7 @@ int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ssize_t res2 = write(bd->disk->fd,
|
||||
bd->disk->scratch,
|
||||
cfg->block_size);
|
||||
ssize_t res2 = write(bd->disk->fd, b->data, cfg->block_size);
|
||||
if (res2 < 0) {
|
||||
int err = -errno;
|
||||
LFS_EMUBD_TRACE("lfs_emubd_erase -> %d", err);
|
||||
|
||||
+2
-4
@@ -67,9 +67,8 @@ typedef int64_t lfs_emubd_ssleep_t;
|
||||
|
||||
// emubd config, this is required for testing
|
||||
struct lfs_emubd_config {
|
||||
// 8-bit erase value to use for simulating erases. -1 does not simulate
|
||||
// erases, which can speed up testing by avoiding the extra block-device
|
||||
// operations to store the erase value.
|
||||
// 8-bit erase value to use for simulating erases. -1 simulates a noop
|
||||
// erase, which is faster than simulating a fixed erase value.
|
||||
int32_t erase_value;
|
||||
|
||||
// Number of erase cycles before a block becomes "bad". The exact behavior
|
||||
@@ -127,7 +126,6 @@ typedef struct lfs_emubd_block {
|
||||
typedef struct lfs_emubd_disk {
|
||||
uint32_t rc;
|
||||
int fd;
|
||||
uint8_t *scratch;
|
||||
} lfs_emubd_disk_t;
|
||||
|
||||
// emubd state
|
||||
|
||||
Reference in New Issue
Block a user