Skip to content

Commit

Permalink
Readded support for mirror writes to a file in testbd
Browse files Browse the repository at this point in the history
Before this was available implicitly by supporting both rambd and filebd
as backends, but now that testbd is a bit more complicated and no longer
maps directly to a block-device, this needs to be explicitly supported.
  • Loading branch information
geky committed Aug 24, 2022
1 parent 4689678 commit 3f4f859
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 50 deletions.
126 changes: 84 additions & 42 deletions bd/lfs_testbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,17 @@
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "bd/lfs_testbd.h"

#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#ifdef _WIN32
#include <windows.h>
#endif


// access to lazily-allocated/copy-on-write blocks
Expand Down Expand Up @@ -116,10 +124,41 @@ int lfs_testbd_createcfg(const struct lfs_config *cfg, const char *path,

// setup testing things
bd->power_cycles = bd->cfg->power_cycles;
bd->disk_fd = -1;
bd->disk_scratch_block = NULL;

bd->branches = NULL;
bd->branch_capacity = 0;
bd->branch_count = 0;

if (bd->cfg->disk_path) {
#ifdef _WIN32
bd->disk_fd = open(bd->cfg->disk_path,
O_RDWR | O_CREAT | O_BINARY, 0666);
#else
bd->disk_fd = open(bd->cfg->disk_path,
O_RDWR | O_CREAT, 0666);
#endif
if (bd->disk_fd < 0) {
int err = -errno;
LFS_TESTBD_TRACE("lfs_testbd_create -> %d", err);
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_block = malloc(cfg->block_size);
if (!bd->disk_scratch_block) {
LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", LFS_ERR_NOMEM);
return LFS_ERR_NOMEM;
}
memset(bd->disk_scratch_block,
bd->cfg->erase_value,
cfg->block_size);
}
}

LFS_TESTBD_TRACE("lfs_testbd_createcfg -> %d", 0);
return 0;
}
Expand Down Expand Up @@ -154,54 +193,17 @@ int lfs_testbd_destroy(const struct lfs_config *cfg) {
free(bd->blocks);
free(bd->branches);

if (bd->disk_fd >= 0) {
close(bd->disk_fd);
free(bd->disk_scratch_block);
}

LFS_TESTBD_TRACE("lfs_testbd_destroy -> %d", 0);
return 0;
}



///// Internal mapping to block devices ///
//static int lfs_testbd_rawread(const struct lfs_config *cfg, lfs_block_t block,
// lfs_off_t off, void *buffer, lfs_size_t size) {
// lfs_testbd_t *bd = cfg->context;
// if (bd->persist) {
// return lfs_filebd_read(cfg, block, off, buffer, size);
// } else {
// return lfs_rambd_read(cfg, block, off, buffer, size);
// }
//}
//
//static int lfs_testbd_rawprog(const struct lfs_config *cfg, lfs_block_t block,
// lfs_off_t off, const void *buffer, lfs_size_t size) {
// lfs_testbd_t *bd = cfg->context;
// if (bd->persist) {
// return lfs_filebd_prog(cfg, block, off, buffer, size);
// } else {
// return lfs_rambd_prog(cfg, block, off, buffer, size);
// }
//}
//
//static int lfs_testbd_rawerase(const struct lfs_config *cfg,
// lfs_block_t block) {
// lfs_testbd_t *bd = cfg->context;
// if (bd->persist) {
// return lfs_filebd_erase(cfg, block);
// } else {
// return lfs_rambd_erase(cfg, block);
// }
//}
//
//static int lfs_testbd_rawsync(const struct lfs_config *cfg) {
// lfs_testbd_t *bd = cfg->context;
// if (bd->persist) {
// return lfs_filebd_sync(cfg);
// } else {
// return lfs_rambd_sync(cfg);
// }
//}



// block device API

int lfs_testbd_read(const struct lfs_config *cfg, lfs_block_t block,
Expand Down Expand Up @@ -285,6 +287,25 @@ int lfs_testbd_prog(const struct lfs_config *cfg, lfs_block_t block,
// prog data
memcpy(&b->data[off], buffer, size);

// mirror to disk file?
if (bd->disk_fd >= 0) {
off_t res1 = lseek(bd->disk_fd,
(off_t)block*cfg->block_size + (off_t)off,
SEEK_SET);
if (res1 < 0) {
int err = -errno;
LFS_TESTBD_TRACE("lfs_testbd_prog -> %d", err);
return err;
}

ssize_t res2 = write(bd->disk_fd, buffer, size);
if (res2 < 0) {
int err = -errno;
LFS_TESTBD_TRACE("lfs_testbd_prog -> %d", err);
return err;
}
}

// lose power?
if (bd->power_cycles > 0) {
bd->power_cycles -= 1;
Expand Down Expand Up @@ -342,6 +363,27 @@ int lfs_testbd_erase(const struct lfs_config *cfg, lfs_block_t block) {
// emulate an erase value?
if (bd->cfg->erase_value != -1) {
memset(b->data, bd->cfg->erase_value, cfg->block_size);

// mirror to disk file?
if (bd->disk_fd >= 0) {
off_t res1 = lseek(bd->disk_fd,
(off_t)block*cfg->block_size,
SEEK_SET);
if (res1 < 0) {
int err = -errno;
LFS_TESTBD_TRACE("lfs_testbd_erase -> %d", err);
return err;
}

ssize_t res2 = write(bd->disk_fd,
bd->disk_scratch_block,
cfg->block_size);
if (res2 < 0) {
int err = -errno;
LFS_TESTBD_TRACE("lfs_testbd_erase -> %d", err);
return err;
}
}
}

// lose power?
Expand Down
15 changes: 7 additions & 8 deletions bd/lfs_testbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,9 @@ struct lfs_testbd_config {
// heavy memory usage!
bool track_branches;

// // Optional buffer for RAM block device.
// void *buffer;
//
// // Optional buffer for wear.
// void *wear_buffer;
//
// // Optional buffer for scratch memory, needed when erase_value != -1.
// void *scratch_buffer;
// Path to file to use as a mirror of the disk. This provides a way to view
// the current state of the block device.
const char *disk_path;
};

// A reference counted block
Expand All @@ -112,7 +107,11 @@ typedef struct lfs_testbd_block {
typedef struct lfs_testbd {
// array of copy-on-write blocks
lfs_testbd_block_t **blocks;

// some other test state
uint32_t power_cycles;
int disk_fd;
uint8_t *disk_scratch_block;

// array of tracked branches
struct lfs_testbd *branches;
Expand Down
4 changes: 4 additions & 0 deletions runners/test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ static void run_powerloss_none(
.erase_value = ERASE_VALUE,
.erase_cycles = ERASE_CYCLES,
.badblock_behavior = BADBLOCK_BEHAVIOR,
.disk_path = test_disk,
};

int err = lfs_testbd_createcfg(&cfg, test_disk, &bdcfg);
Expand Down Expand Up @@ -672,6 +673,7 @@ static void run_powerloss_linear(
.erase_value = ERASE_VALUE,
.erase_cycles = ERASE_CYCLES,
.badblock_behavior = BADBLOCK_BEHAVIOR,
.disk_path = test_disk,
.power_cycles = i,
.powerloss_behavior = POWERLOSS_BEHAVIOR,
.powerloss_cb = powerloss_longjmp,
Expand Down Expand Up @@ -748,6 +750,7 @@ static void run_powerloss_exponential(
.erase_value = ERASE_VALUE,
.erase_cycles = ERASE_CYCLES,
.badblock_behavior = BADBLOCK_BEHAVIOR,
.disk_path = test_disk,
.power_cycles = i,
.powerloss_behavior = POWERLOSS_BEHAVIOR,
.powerloss_cb = powerloss_longjmp,
Expand Down Expand Up @@ -822,6 +825,7 @@ static void run_powerloss_cycles(
.erase_value = ERASE_VALUE,
.erase_cycles = ERASE_CYCLES,
.badblock_behavior = BADBLOCK_BEHAVIOR,
.disk_path = test_disk,
.power_cycles = (i < cycle_count) ? cycles[i] : 0,
.powerloss_behavior = POWERLOSS_BEHAVIOR,
.powerloss_cb = powerloss_longjmp,
Expand Down

0 comments on commit 3f4f859

Please sign in to comment.