Big rename! Renamed lfs -> lfs3 and lfsr -> lfs3

This commit is contained in:
Christopher Haster
2025-05-28 15:00:04 -05:00
parent 3413f125d8
commit 6eba1180c8
50 changed files with 52278 additions and 52111 deletions
+11 -11
View File
@@ -9,21 +9,21 @@
*.gcno *.gcno
*.gcda *.gcda
*.perf *.perf
lfs lfs3
liblfs.a liblfs3.a
# Testing things # Testing things
runners/test_runner runners/test_runner
runners/bench_runner runners/bench_runner
lfs.code.csv lfs3.code.csv
lfs.data.csv lfs3.data.csv
lfs.stack.csv lfs3.stack.csv
lfs.structs.csv lfs3.structs.csv
lfs.cov.csv lfs3.cov.csv
lfs.perf.csv lfs3.perf.csv
lfs.perfbd.csv lfs3.perfbd.csv
lfs.test.csv lfs3.test.csv
lfs.bench.csv lfs3.bench.csv
# Misc # Misc
tags tags
+69 -69
View File
@@ -2,9 +2,9 @@
BUILDDIR ?= . BUILDDIR ?= .
# overrideable target, default to building a library # overrideable target, default to building a library
ifneq ($(wildcard test.c main.c),) ifneq ($(wildcard test.c main.c),)
TARGET ?= $(BUILDDIR)/lfs TARGET ?= $(BUILDDIR)/lfs3
else else
TARGET ?= $(BUILDDIR)/liblfs.a TARGET ?= $(BUILDDIR)/liblfs3.a
endif endif
@@ -82,7 +82,7 @@ else
CFLAGS += -Os CFLAGS += -Os
endif endif
ifdef TRACE ifdef TRACE
CFLAGS += -DLFS_YES_TRACE CFLAGS += -DLFS3_YES_TRACE
endif endif
ifdef COVGEN ifdef COVGEN
CFLAGS += --coverage CFLAGS += --coverage
@@ -94,8 +94,8 @@ ifdef PERFBDGEN
CFLAGS += -fno-omit-frame-pointer CFLAGS += -fno-omit-frame-pointer
endif endif
# also forward all LFS_* environment variables # also forward all LFS3_* environment variables
CFLAGS += $(foreach D,$(filter LFS_%,$(.VARIABLES)),-D$D=$($D)) CFLAGS += $(foreach D,$(filter LFS3_%,$(.VARIABLES)),-D$D=$($D))
TEST_CFLAGS += -Wno-unused-function TEST_CFLAGS += -Wno-unused-function
TEST_CFLAGS += -Wno-format-overflow TEST_CFLAGS += -Wno-format-overflow
@@ -231,12 +231,12 @@ code: $(OBJ)
## Save the per-function code size ## Save the per-function code size
.PHONY: code-csv .PHONY: code-csv
code-csv: $(BUILDDIR)/lfs.code.csv code-csv: $(BUILDDIR)/lfs3.code.csv
## Compare per-function code size ## Compare per-function code size
.PHONY: code-diff .PHONY: code-diff
code-diff: $(OBJ) code-diff: $(OBJ)
./scripts/code.py $^ $(CODEFLAGS) -d $(BUILDDIR)/lfs.code.csv ./scripts/code.py $^ $(CODEFLAGS) -d $(BUILDDIR)/lfs3.code.csv
## Find the per-function data size ## Find the per-function data size
.PHONY: data .PHONY: data
@@ -246,12 +246,12 @@ data: $(OBJ)
## Save the per-function data size ## Save the per-function data size
.PHONY: data-csv .PHONY: data-csv
data-csv: $(BUILDDIR)/lfs.data.csv data-csv: $(BUILDDIR)/lfs3.data.csv
## Compare per-function data size ## Compare per-function data size
.PHONY: data-diff .PHONY: data-diff
data-diff: $(OBJ) data-diff: $(OBJ)
./scripts/data.py $^ $(DATAFLAGS) -d $(BUILDDIR)/lfs.data.csv ./scripts/data.py $^ $(DATAFLAGS) -d $(BUILDDIR)/lfs3.data.csv
## Find the per-function stack usage ## Find the per-function stack usage
.PHONY: stack .PHONY: stack
@@ -261,12 +261,12 @@ stack: $(CI)
## Save the per-function stack usage ## Save the per-function stack usage
.PHONY: stack-csv .PHONY: stack-csv
stack-csv: $(BUILDDIR)/lfs.stack.csv stack-csv: $(BUILDDIR)/lfs3.stack.csv
## Compare per-function stack usage ## Compare per-function stack usage
.PHONY: stack-diff .PHONY: stack-diff
stack-diff: $(CI) stack-diff: $(CI)
./scripts/stack.py $^ $(STACKFLAGS) -d $(BUILDDIR)/lfs.stack.csv ./scripts/stack.py $^ $(STACKFLAGS) -d $(BUILDDIR)/lfs3.stack.csv
## Find the per-function context ## Find the per-function context
.PHONY: ctx .PHONY: ctx
@@ -276,12 +276,12 @@ ctx: $(OBJ)
## Save the per-function context ## Save the per-function context
.PHONY: ctx-csv .PHONY: ctx-csv
ctx-csv: $(BUILDDIR)/lfs.ctx.csv ctx-csv: $(BUILDDIR)/lfs3.ctx.csv
## Compare per-function context ## Compare per-function context
.PHONY: ctx-diff .PHONY: ctx-diff
ctx-diff: $(CI) ctx-diff: $(CI)
./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs.ctx.csv ./scripts/ctx.py $^ $(CTXFLAGS) -d $(BUILDDIR)/lfs3.ctx.csv
## Find function sizes ## Find function sizes
.PHONY: funcs .PHONY: funcs
@@ -302,9 +302,9 @@ funcs: $(OBJ) $(CI)
.PHONY: funcs-csv .PHONY: funcs-csv
funcs-csv: SHELL=/bin/bash funcs-csv: SHELL=/bin/bash
funcs-csv: \ funcs-csv: \
$(BUILDDIR)/lfs.code.csv \ $(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs.stack.csv \ $(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs.ctx.csv $(BUILDDIR)/lfs3.ctx.csv
## Compare function sizes ## Compare function sizes
.PHONY: funcs-diff .PHONY: funcs-diff
@@ -319,9 +319,9 @@ funcs-diff: $(OBJ) $(CI)
-fstack='max(stack_limit)' \ -fstack='max(stack_limit)' \
-fctx='max(ctx_size)' \ -fctx='max(ctx_size)' \
-d <(./scripts/csv.py \ -d <(./scripts/csv.py \
$(BUILDDIR)/lfs.code.csv \ $(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs.stack.csv \ $(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs.ctx.csv \ $(BUILDDIR)/lfs3.ctx.csv \
-fcode_size=code_size \ -fcode_size=code_size \
-fstack_limit='max(stack_limit)' \ -fstack_limit='max(stack_limit)' \
-fctx_size='max(ctx_size)' \ -fctx_size='max(ctx_size)' \
@@ -336,12 +336,12 @@ structs: $(OBJ)
## Save struct sizes ## Save struct sizes
.PHONY: structs-csv .PHONY: structs-csv
structs-csv: $(BUILDDIR)/lfs.structs.csv structs-csv: $(BUILDDIR)/lfs3.structs.csv
## Compare struct sizes ## Compare struct sizes
.PHONY: structs-diff .PHONY: structs-diff
structs-diff: $(OBJ) structs-diff: $(OBJ)
./scripts/structs.py $^ $(STRUCTSFLAGS) -d $(BUILDDIR)/lfs.structs.csv ./scripts/structs.py $^ $(STRUCTSFLAGS) -d $(BUILDDIR)/lfs3.structs.csv
## Find the line/branch coverage after a test run ## Find the line/branch coverage after a test run
.PHONY: cov .PHONY: cov
@@ -353,14 +353,14 @@ cov: $(GCDA)
## Save line/branch coverage ## Save line/branch coverage
.PHONY: cov-csv .PHONY: cov-csv
cov-csv: $(BUILDDIR)/lfs.cov.csv cov-csv: $(BUILDDIR)/lfs3.cov.csv
## Compare line/branch coverage ## Compare line/branch coverage
.PHONY: cov-diff .PHONY: cov-diff
cov-diff: $(GCDA) cov-diff: $(GCDA)
$(strip ./scripts/cov.py $^ \ $(strip ./scripts/cov.py $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(COVFLAGS) -d $(BUILDDIR)/lfs.cov.csv) $(COVFLAGS) -d $(BUILDDIR)/lfs3.cov.csv)
## Find the perf results after bench run with PERFGEN ## Find the perf results after bench run with PERFGEN
.PHONY: perf .PHONY: perf
@@ -372,14 +372,14 @@ perf: $(BENCH_PERF)
## Save perf results ## Save perf results
.PHONY: perf-csv .PHONY: perf-csv
perf-csv: $(BUILDDIR)/lfs.perf.csv perf-csv: $(BUILDDIR)/lfs3.perf.csv
## Compare perf results ## Compare perf results
.PHONY: perf-diff .PHONY: perf-diff
perf-diff: $(BENCH_PERF) perf-diff: $(BENCH_PERF)
$(strip ./scripts/perf.py $^ \ $(strip ./scripts/perf.py $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(PERFFLAGS) -d $(BUILDDIR)/lfs.perf.csv) $(PERFFLAGS) -d $(BUILDDIR)/lfs3.perf.csv)
## Find the perfbd results after a bench run ## Find the perfbd results after a bench run
.PHONY: perfbd .PHONY: perfbd
@@ -391,14 +391,14 @@ perfbd: $(BENCH_TRACE)
## Save perfbd results ## Save perfbd results
.PHONY: perfbd-csv .PHONY: perfbd-csv
perfbd-csv: $(BUILDDIR)/lfs.perfbd.csv perfbd-csv: $(BUILDDIR)/lfs3.perfbd.csv
## Compare perfbd results ## Compare perfbd results
.PHONY: perfbd-diff .PHONY: perfbd-diff
perfbd-diff: $(BENCH_TRACE) perfbd-diff: $(BENCH_TRACE)
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \ $(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(PERFBDFLAGS) -d $(BUILDDIR)/lfs.perfbd.csv) $(PERFBDFLAGS) -d $(BUILDDIR)/lfs3.perfbd.csv)
## Find a summary of compile-time sizes ## Find a summary of compile-time sizes
.PHONY: summary sizes .PHONY: summary sizes
@@ -420,10 +420,10 @@ summary sizes: $(OBJ) $(CI)
.PHONY: summary-csv sizes-csv .PHONY: summary-csv sizes-csv
summary-csv sizes-csv: SHELL=/bin/bash summary-csv sizes-csv: SHELL=/bin/bash
summary-csv sizes-csv: \ summary-csv sizes-csv: \
$(BUILDDIR)/lfs.code.csv \ $(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs.data.csv \ $(BUILDDIR)/lfs3.data.csv \
$(BUILDDIR)/lfs.stack.csv \ $(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs.ctx.csv $(BUILDDIR)/lfs3.ctx.csv
## Compare compile-time sizes ## Compare compile-time sizes
.PHONY: summary-diff sizes-diff .PHONY: summary-diff sizes-diff
@@ -442,10 +442,10 @@ summary-diff sizes-diff: $(OBJ) $(CI)
-fctx='max(ctx_size)' \ -fctx='max(ctx_size)' \
-o-) \ -o-) \
<(./scripts/csv.py \ <(./scripts/csv.py \
$(BUILDDIR)/lfs.code.csv \ $(BUILDDIR)/lfs3.code.csv \
$(BUILDDIR)/lfs.data.csv \ $(BUILDDIR)/lfs3.data.csv \
$(BUILDDIR)/lfs.stack.csv \ $(BUILDDIR)/lfs3.stack.csv \
$(BUILDDIR)/lfs.ctx.csv \ $(BUILDDIR)/lfs3.ctx.csv \
-bbuild=BEFORE \ -bbuild=BEFORE \
-fcode=code_size \ -fcode=code_size \
-fdata=data_size \ -fdata=data_size \
@@ -458,12 +458,12 @@ summary-diff sizes-diff: $(OBJ) $(CI)
## Generate a codemap svg ## Generate a codemap svg
.PHONY: codemap .PHONY: codemap
codemap: CODEMAPFLAGS+=-W1400 -H750 --dark codemap: CODEMAPFLAGS+=-W1400 -H750 --dark
codemap: $(BUILDDIR)/lfs.codemap.svg codemap: $(BUILDDIR)/lfs3.codemap.svg
## Generate a tiny codemap, where 1 pixel ~= 1 byte ## Generate a tiny codemap, where 1 pixel ~= 1 byte
.PHONY: codemap-tiny .PHONY: codemap-tiny
codemap-tiny: CODEMAPFLAGS+=--dark codemap-tiny: CODEMAPFLAGS+=--dark
codemap-tiny: $(BUILDDIR)/lfs.codemap_tiny.svg codemap-tiny: $(BUILDDIR)/lfs3.codemap_tiny.svg
## Build the test-runner ## Build the test-runner
@@ -504,7 +504,7 @@ testmarks: $(TEST_CSV)
## Save the test results ## Save the test results
.PHONY: testmarks-csv .PHONY: testmarks-csv
testmarks-csv: $(BUILDDIR)/lfs.test.csv testmarks-csv: $(BUILDDIR)/lfs3.test.csv
## Compare test results against a previous run ## Compare test results against a previous run
.PHONY: testmarks-diff .PHONY: testmarks-diff
@@ -513,7 +513,7 @@ testmarks-diff: $(TEST_CSV)
-bsuite \ -bsuite \
-fpassed=test_passed \ -fpassed=test_passed \
-ftime=test_time \ -ftime=test_time \
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.test.csv) $(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.test.csv)
## Build the bench-runner ## Build the bench-runner
.PHONY: bench-runner build-benches .PHONY: bench-runner build-benches
@@ -554,7 +554,7 @@ benchmarks: $(BENCH_CSV)
## Save the bench results ## Save the bench results
.PHONY: benchmarks-csv .PHONY: benchmarks-csv
benchmarks-csv: $(BUILDDIR)/lfs.bench.csv benchmarks-csv: $(BUILDDIR)/lfs3.bench.csv
## Compare bench results against a previous run ## Compare bench results against a previous run
.PHONY: benchmarks-diff .PHONY: benchmarks-diff
@@ -564,7 +564,7 @@ benchmarks-diff: $(BENCH_CSV)
-freaded=bench_readed \ -freaded=bench_readed \
-fproged=bench_proged \ -fproged=bench_proged \
-ferased=bench_erased \ -ferased=bench_erased \
$(SUMMARYFLAGS) -d $(BUILDDIR)/lfs.bench.csv) $(SUMMARYFLAGS) -d $(BUILDDIR)/lfs3.bench.csv)
@@ -575,54 +575,54 @@ benchmarks-diff: $(BENCH_CSV)
.SUFFIXES: .SUFFIXES:
.SECONDARY: .SECONDARY:
$(BUILDDIR)/lfs: $(OBJ) $(BUILDDIR)/lfs3: $(OBJ)
$(CC) $(CFLAGS) $^ $(LFLAGS) -o$@ $(CC) $(CFLAGS) $^ $(LFLAGS) -o$@
$(BUILDDIR)/liblfs.a: $(OBJ) $(BUILDDIR)/liblfs3.a: $(OBJ)
$(AR) rcs $@ $^ $(AR) rcs $@ $^
$(BUILDDIR)/lfs.code.csv: $(OBJ) $(BUILDDIR)/lfs3.code.csv: $(OBJ)
./scripts/code.py $^ $(CODEFLAGS) -o$@ ./scripts/code.py $^ $(CODEFLAGS) -o$@
$(BUILDDIR)/lfs.data.csv: $(OBJ) $(BUILDDIR)/lfs3.data.csv: $(OBJ)
./scripts/data.py $^ $(DATAFLAGS) -o$@ ./scripts/data.py $^ $(DATAFLAGS) -o$@
$(BUILDDIR)/lfs.stack.csv: $(CI) $(BUILDDIR)/lfs3.stack.csv: $(CI)
./scripts/stack.py $^ $(STACKFLAGS) -o$@ ./scripts/stack.py $^ $(STACKFLAGS) -o$@
$(BUILDDIR)/lfs.ctx.csv: $(OBJ) $(BUILDDIR)/lfs3.ctx.csv: $(OBJ)
./scripts/ctx.py $^ $(CTXFLAGS) -o$@ ./scripts/ctx.py $^ $(CTXFLAGS) -o$@
$(BUILDDIR)/lfs.structs.csv: $(OBJ) $(BUILDDIR)/lfs3.structs.csv: $(OBJ)
./scripts/structs.py $^ $(STRUCTSFLAGS) -o$@ ./scripts/structs.py $^ $(STRUCTSFLAGS) -o$@
$(BUILDDIR)/lfs.cov.csv: $(GCDA) $(BUILDDIR)/lfs3.cov.csv: $(GCDA)
$(strip ./scripts/cov.py $^ \ $(strip ./scripts/cov.py $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(COVFLAGS) -o$@) $(COVFLAGS) -o$@)
$(BUILDDIR)/lfs.perf.csv: $(BENCH_PERF) $(BUILDDIR)/lfs3.perf.csv: $(BENCH_PERF)
$(strip ./scripts/perf.py $^ \ $(strip ./scripts/perf.py $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(PERFFLAGS) -o$@) $(PERFFLAGS) -o$@)
$(BUILDDIR)/lfs.perfbd.csv: $(BENCH_TRACE) $(BUILDDIR)/lfs3.perfbd.csv: $(BENCH_TRACE)
$(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \ $(strip ./scripts/perfbd.py $(BENCH_RUNNER) $^ \
$(patsubst %,-F%,$(SRC)) \ $(patsubst %,-F%,$(SRC)) \
$(PERFBDFLAGS) -o$@) $(PERFBDFLAGS) -o$@)
$(BUILDDIR)/lfs.codemap.svg: $(OBJ) $(CI) $(BUILDDIR)/lfs3.codemap.svg: $(OBJ) $(CI)
$(strip ./scripts/codemapsvg.py $^ $(CODEMAPFLAGS) -o$@ \ $(strip ./scripts/codemapsvg.py $^ $(CODEMAPFLAGS) -o$@ \
&& ./scripts/codemap.py $^ --no-header) && ./scripts/codemap.py $^ --no-header)
$(BUILDDIR)/lfs.codemap_tiny.svg: $(OBJ) $(CI) $(BUILDDIR)/lfs3.codemap_tiny.svg: $(OBJ) $(CI)
$(strip ./scripts/codemapsvg.py $^ --tiny $(CODEMAPFLAGS) -o$@ \ $(strip ./scripts/codemapsvg.py $^ --tiny $(CODEMAPFLAGS) -o$@ \
&& ./scripts/codemap.py $^ --no-header) && ./scripts/codemap.py $^ --no-header)
$(BUILDDIR)/lfs.test.csv: $(TEST_CSV) $(BUILDDIR)/lfs3.test.csv: $(TEST_CSV)
cp $^ $@ cp $^ $@
$(BUILDDIR)/lfs.bench.csv: $(BENCH_CSV) $(BUILDDIR)/lfs3.bench.csv: $(BENCH_CSV)
cp $^ $@ cp $^ $@
$(BUILDDIR)/runners/test_runner: $(TEST_OBJ) $(BUILDDIR)/runners/test_runner: $(TEST_OBJ)
@@ -666,20 +666,20 @@ $(BUILDDIR)/%.b.c: %.c $(BENCHES)
## Clean everything ## Clean everything
.PHONY: clean .PHONY: clean
clean: clean:
rm -f $(BUILDDIR)/lfs rm -f $(BUILDDIR)/lfs3
rm -f $(BUILDDIR)/liblfs.a rm -f $(BUILDDIR)/liblfs3.a
rm -f $(BUILDDIR)/lfs.code.csv rm -f $(BUILDDIR)/lfs3.code.csv
rm -f $(BUILDDIR)/lfs.data.csv rm -f $(BUILDDIR)/lfs3.data.csv
rm -f $(BUILDDIR)/lfs.stack.csv rm -f $(BUILDDIR)/lfs3.stack.csv
rm -f $(BUILDDIR)/lfs.ctx.csv rm -f $(BUILDDIR)/lfs3.ctx.csv
rm -f $(BUILDDIR)/lfs.structs.csv rm -f $(BUILDDIR)/lfs3.structs.csv
rm -f $(BUILDDIR)/lfs.cov.csv rm -f $(BUILDDIR)/lfs3.cov.csv
rm -f $(BUILDDIR)/lfs.perf.csv rm -f $(BUILDDIR)/lfs3.perf.csv
rm -f $(BUILDDIR)/lfs.perfbd.csv rm -f $(BUILDDIR)/lfs3.perfbd.csv
rm -f $(BUILDDIR)/lfs.codemap.svg rm -f $(BUILDDIR)/lfs3.codemap.svg
rm -f $(BUILDDIR)/lfs.codemap_tiny.svg rm -f $(BUILDDIR)/lfs3.codemap_tiny.svg
rm -f $(BUILDDIR)/lfs.test.csv rm -f $(BUILDDIR)/lfs3.test.csv
rm -f $(BUILDDIR)/lfs.bench.csv rm -f $(BUILDDIR)/lfs3.bench.csv
rm -f $(OBJ) rm -f $(OBJ)
rm -f $(DEP) rm -f $(DEP)
rm -f $(ASM) rm -f $(ASM)
File diff suppressed because it is too large Load Diff
+265
View File
@@ -0,0 +1,265 @@
/*
* Emulating block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_EMUBD_H
#define LFS3_EMUBD_H
#include "lfs3.h"
#include "lfs3_util.h"
#include "bd/lfs3_rambd.h"
#include "bd/lfs3_filebd.h"
// Block device specific tracing
#ifndef LFS3_EMUBD_TRACE
#ifdef LFS3_EMUBD_YES_TRACE
#define LFS3_EMUBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_EMUBD_TRACE(...)
#endif
#endif
// Mode determining how "bad-blocks" behave during testing. This simulates
// some real-world circumstances such as progs not sticking (prog-noop),
// a readonly disk (erase-noop), ECC failures (read-error), and of course,
// random bit failures (prog-flip, read-flip)
typedef enum lfs3_emubd_badblock_behavior {
LFS3_EMUBD_BADBLOCK_PROGERROR = 0, // Error on prog
LFS3_EMUBD_BADBLOCK_ERASEERROR = 1, // Error on erase
LFS3_EMUBD_BADBLOCK_READERROR = 2, // Error on read
LFS3_EMUBD_BADBLOCK_PROGNOOP = 3, // Prog does nothing silently
LFS3_EMUBD_BADBLOCK_ERASENOOP = 4, // Erase does nothing silently
LFS3_EMUBD_BADBLOCK_PROGFLIP = 5, // Prog flips a bit
LFS3_EMUBD_BADBLOCK_READFLIP = 6, // Read flips a bit sometimes
LFS3_EMUBD_BADBLOCK_MANUAL = 7, // Bits require manual flipping
} lfs3_emubd_badblock_behavior_t;
// Mode determining how power-loss behaves during testing.
typedef enum lfs3_emubd_powerloss_behavior {
LFS3_EMUBD_POWERLOSS_ATOMIC = 0, // Progs are atomic
LFS3_EMUBD_POWERLOSS_SOMEBITS = 1, // One bit is progged
LFS3_EMUBD_POWERLOSS_MOSTBITS = 2, // All-but-one bit is progged
LFS3_EMUBD_POWERLOSS_OOO = 3, // Blocks are written out-of-order
LFS3_EMUBD_POWERLOSS_METASTABLE = 4, // Reads may flip a bit
} lfs3_emubd_powerloss_behavior_t;
// Type for measuring read/program/erase operations
typedef uint64_t lfs3_emubd_io_t;
typedef int64_t lfs3_emubd_sio_t;
// Type for measuring wear
typedef uint32_t lfs3_emubd_wear_t;
typedef int32_t lfs3_emubd_swear_t;
// Type for tracking power-cycles
typedef uint32_t lfs3_emubd_powercycles_t;
typedef int32_t lfs3_emubd_spowercycles_t;
// Type for delays in nanoseconds
typedef uint64_t lfs3_emubd_sleep_t;
typedef int64_t lfs3_emubd_ssleep_t;
// emubd config, this is required for testing
struct lfs3_emubd_config {
// 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
// of bad blocks is controlled by badblock_behavior.
uint32_t erase_cycles;
// The mode determining how bad-blocks fail
lfs3_emubd_badblock_behavior_t badblock_behavior;
// Number of write operations (erase/prog) before triggering a power-loss.
// power_cycles=0 disables this. The exact behavior of power-loss is
// controlled by a combination of powerloss_behavior and powerloss_cb.
lfs3_emubd_powercycles_t power_cycles;
// The mode determining how power-loss affects disk
lfs3_emubd_powerloss_behavior_t powerloss_behavior;
// Function to call to emulate power-loss. The exact behavior of power-loss
// is up to the runner to provide.
void (*powerloss_cb)(void*);
// Data for power-loss callback
void *powerloss_data;
// Seed for prng, which may be used for emulating failed progs. This does
// not affect normal operation.
uint32_t seed;
// 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;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t read_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t prog_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs3_emubd_sleep_t erase_sleep;
};
// A reference counted block
typedef struct lfs3_emubd_block {
uint32_t rc;
lfs3_emubd_wear_t wear;
bool metastable;
// sign(bad_bit)=0 => randomized on erase
// sign(bad_bit)=1 => fixed
lfs3_size_t bad_bit;
uint8_t data[];
} lfs3_emubd_block_t;
// Disk mirror
typedef struct lfs3_emubd_disk {
uint32_t rc;
int fd;
uint8_t *scratch;
} lfs3_emubd_disk_t;
// emubd state
typedef struct lfs3_emubd {
// array of copy-on-write blocks
lfs3_emubd_block_t **blocks;
// some other test state
lfs3_emubd_io_t readed;
lfs3_emubd_io_t proged;
lfs3_emubd_io_t erased;
uint32_t prng;
lfs3_emubd_powercycles_t power_cycles;
lfs3_emubd_block_t **ooo_before;
lfs3_emubd_block_t **ooo_after;
lfs3_emubd_disk_t *disk;
const struct lfs3_emubd_config *cfg;
} lfs3_emubd_t;
/// Block device API ///
// Create an emulating block device using the geometry in lfs3_config
//
// Note that filebd is used if a path is provided, if path is NULL
// emubd will use rambd which can be much faster.
int lfs3_emubd_create(const struct lfs3_config *cfg, const char *path);
int lfs3_emubd_createcfg(const struct lfs3_config *cfg, const char *path,
const struct lfs3_emubd_config *bdcfg);
// Clean up memory associated with block device
int lfs3_emubd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_emubd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs3_emubd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs3_emubd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_emubd_sync(const struct lfs3_config *cfg);
/// Additional extended API for driving test features ///
// Set the current prng state
void lfs3_emubd_seed(const struct lfs3_config *cfg, uint32_t seed);
// Get a pseudo-random number from emubd's internal prng
uint32_t lfs3_emubd_prng(const struct lfs3_config *cfg);
// Get total amount of bytes read
lfs3_emubd_sio_t lfs3_emubd_readed(const struct lfs3_config *cfg);
// Get total amount of bytes programmed
lfs3_emubd_sio_t lfs3_emubd_proged(const struct lfs3_config *cfg);
// Get total amount of bytes erased
lfs3_emubd_sio_t lfs3_emubd_erased(const struct lfs3_config *cfg);
// Manually set amount of bytes read
int lfs3_emubd_setreaded(const struct lfs3_config *cfg,
lfs3_emubd_io_t readed);
// Manually set amount of bytes programmed
int lfs3_emubd_setproged(const struct lfs3_config *cfg,
lfs3_emubd_io_t proged);
// Manually set amount of bytes erased
int lfs3_emubd_seterased(const struct lfs3_config *cfg,
lfs3_emubd_io_t erased);
// Get simulated wear on a given block
lfs3_emubd_swear_t lfs3_emubd_wear(const struct lfs3_config *cfg,
lfs3_block_t block);
// Manually set simulated wear on a given block
int lfs3_emubd_setwear(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_emubd_wear_t wear);
// Mark a block as bad, this is equivalent to setting wear to maximum
int lfs3_emubd_markbad(const struct lfs3_config *cfg, lfs3_block_t block);
// Clear any simulated wear on a given block
int lfs3_emubd_markgood(const struct lfs3_config *cfg, lfs3_block_t block);
// Get which bit failed, this changes on erase/power-loss unless manually set
lfs3_ssize_t lfs3_emubd_badbit(const struct lfs3_config *cfg,
lfs3_block_t block);
// Set which bit should fail in a given block
int lfs3_emubd_setbadbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Randomize the bad bit on erase (the default)
int lfs3_emubd_randomizebadbit(const struct lfs3_config *cfg,
lfs3_block_t block);
// Mark a block as bad and which bit should fail
int lfs3_emubd_markbadbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Flip a bit in a given block, intended for emulating bit errors
int lfs3_emubd_flipbit(const struct lfs3_config *cfg,
lfs3_block_t block, lfs3_size_t bit);
// Flip all bits marked as bad
int lfs3_emubd_flip(const struct lfs3_config *cfg);
// Get the remaining power-cycles
lfs3_emubd_spowercycles_t lfs3_emubd_powercycles(
const struct lfs3_config *cfg);
// Manually set the remaining power-cycles
int lfs3_emubd_setpowercycles(const struct lfs3_config *cfg,
lfs3_emubd_powercycles_t power_cycles);
// Create a copy-on-write copy of the state of this block device
int lfs3_emubd_cpy(const struct lfs3_config *cfg, lfs3_emubd_t *copy);
#endif
+42 -42
View File
@@ -5,7 +5,7 @@
* Copyright (c) 2017, Arm Limited. All rights reserved. * Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include "bd/lfs_filebd.h" #include "bd/lfs3_filebd.h"
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
@@ -15,8 +15,8 @@
#include <windows.h> #include <windows.h>
#endif #endif
int lfs_filebd_create(const struct lfs_config *cfg, const char *path) { int lfs3_filebd_create(const struct lfs3_config *cfg, const char *path) {
LFS_FILEBD_TRACE("lfs_filebd_create(%p {.context=%p, " LFS3_FILEBD_TRACE("lfs3_filebd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, " ".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
@@ -26,7 +26,7 @@ int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
path, (void*)bdcfg, bdcfg->erase_value); path, (void*)bdcfg, bdcfg->erase_value);
lfs_filebd_t *bd = cfg->context; lfs3_filebd_t *bd = cfg->context;
// open file // open file
#ifdef _WIN32 #ifdef _WIN32
@@ -37,39 +37,39 @@ int lfs_filebd_create(const struct lfs_config *cfg, const char *path) {
if (bd->fd < 0) { if (bd->fd < 0) {
int err = -errno; int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", err);
return err; return err;
} }
LFS_FILEBD_TRACE("lfs_filebd_create -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_create -> %d", 0);
return 0; return 0;
} }
int lfs_filebd_destroy(const struct lfs_config *cfg) { int lfs3_filebd_destroy(const struct lfs3_config *cfg) {
LFS_FILEBD_TRACE("lfs_filebd_destroy(%p)", (void*)cfg); LFS3_FILEBD_TRACE("lfs3_filebd_destroy(%p)", (void*)cfg);
lfs_filebd_t *bd = cfg->context; lfs3_filebd_t *bd = cfg->context;
int err = close(bd->fd); int err = close(bd->fd);
if (err < 0) { if (err < 0) {
err = -errno; err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", err);
return err; return err;
} }
LFS_FILEBD_TRACE("lfs_filebd_destroy -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_destroy -> %d", 0);
return 0; return 0;
} }
int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block, int lfs3_filebd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) { lfs3_off_t off, void *buffer, lfs3_size_t size) {
LFS_FILEBD_TRACE("lfs_filebd_read(%p, " LFS3_FILEBD_TRACE("lfs3_filebd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size); (void*)cfg, block, off, buffer, size);
lfs_filebd_t *bd = cfg->context; lfs3_filebd_t *bd = cfg->context;
// check if read is valid // check if read is valid
LFS_ASSERT(block < cfg->block_count); LFS3_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->read_size == 0); LFS3_ASSERT(off % cfg->read_size == 0);
LFS_ASSERT(size % cfg->read_size == 0); LFS3_ASSERT(size % cfg->read_size == 0);
LFS_ASSERT(off+size <= cfg->block_size); LFS3_ASSERT(off+size <= cfg->block_size);
// zero for reproducibility (in case file is truncated) // zero for reproducibility (in case file is truncated)
memset(buffer, 0, size); memset(buffer, 0, size);
@@ -79,73 +79,73 @@ int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET); (off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
if (res1 < 0) { if (res1 < 0) {
int err = -errno; int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
return err; return err;
} }
ssize_t res2 = read(bd->fd, buffer, size); ssize_t res2 = read(bd->fd, buffer, size);
if (res2 < 0) { if (res2 < 0) {
int err = -errno; int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", err);
return err; return err;
} }
LFS_FILEBD_TRACE("lfs_filebd_read -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_read -> %d", 0);
return 0; return 0;
} }
int lfs_filebd_prog(const struct lfs_config *cfg, lfs_block_t block, int lfs3_filebd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size) { lfs3_off_t off, const void *buffer, lfs3_size_t size) {
LFS_FILEBD_TRACE("lfs_filebd_prog(%p, " LFS3_FILEBD_TRACE("lfs3_filebd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")", "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size); (void*)cfg, block, off, buffer, size);
lfs_filebd_t *bd = cfg->context; lfs3_filebd_t *bd = cfg->context;
// check if write is valid // check if write is valid
LFS_ASSERT(block < cfg->block_count); LFS3_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->prog_size == 0); LFS3_ASSERT(off % cfg->prog_size == 0);
LFS_ASSERT(size % cfg->prog_size == 0); LFS3_ASSERT(size % cfg->prog_size == 0);
LFS_ASSERT(off+size <= cfg->block_size); LFS3_ASSERT(off+size <= cfg->block_size);
// program data // program data
off_t res1 = lseek(bd->fd, off_t res1 = lseek(bd->fd,
(off_t)block*cfg->block_size + (off_t)off, SEEK_SET); (off_t)block*cfg->block_size + (off_t)off, SEEK_SET);
if (res1 < 0) { if (res1 < 0) {
int err = -errno; int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
return err; return err;
} }
ssize_t res2 = write(bd->fd, buffer, size); ssize_t res2 = write(bd->fd, buffer, size);
if (res2 < 0) { if (res2 < 0) {
int err = -errno; int err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", err); LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", err);
return err; return err;
} }
LFS_FILEBD_TRACE("lfs_filebd_prog -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_prog -> %d", 0);
return 0; return 0;
} }
int lfs_filebd_erase(const struct lfs_config *cfg, lfs_block_t block) { int lfs3_filebd_erase(const struct lfs3_config *cfg, lfs3_block_t block) {
LFS_FILEBD_TRACE("lfs_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))", LFS3_FILEBD_TRACE("lfs3_filebd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size); (void*)cfg, block, cfg->block_size);
// check if erase is valid // check if erase is valid
LFS_ASSERT(block < cfg->block_count); LFS3_ASSERT(block < cfg->block_count);
// erase is a noop // erase is a noop
(void)block; (void)block;
LFS_FILEBD_TRACE("lfs_filebd_erase -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_erase -> %d", 0);
return 0; return 0;
} }
int lfs_filebd_sync(const struct lfs_config *cfg) { int lfs3_filebd_sync(const struct lfs3_config *cfg) {
LFS_FILEBD_TRACE("lfs_filebd_sync(%p)", (void*)cfg); LFS3_FILEBD_TRACE("lfs3_filebd_sync(%p)", (void*)cfg);
// file sync // file sync
lfs_filebd_t *bd = cfg->context; lfs3_filebd_t *bd = cfg->context;
#ifdef _WIN32 #ifdef _WIN32
int err = FlushFileBuffers((HANDLE) _get_osfhandle(bd->fd)) ? 0 : -1; int err = FlushFileBuffers((HANDLE) _get_osfhandle(bd->fd)) ? 0 : -1;
#else #else
@@ -153,10 +153,10 @@ int lfs_filebd_sync(const struct lfs_config *cfg) {
#endif #endif
if (err) { if (err) {
err = -errno; err = -errno;
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
return err; return err;
} }
LFS_FILEBD_TRACE("lfs_filebd_sync -> %d", 0); LFS3_FILEBD_TRACE("lfs3_filebd_sync -> %d", 0);
return 0; return 0;
} }
+56
View File
@@ -0,0 +1,56 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_FILEBD_H
#define LFS3_FILEBD_H
#include "lfs3.h"
#include "lfs3_util.h"
// Block device specific tracing
#ifndef LFS3_FILEBD_TRACE
#ifdef LFS3_FILEBD_YES_TRACE
#define LFS3_FILEBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_FILEBD_TRACE(...)
#endif
#endif
// filebd state
typedef struct lfs3_filebd {
int fd;
} lfs3_filebd_t;
// Create a file block device using the geometry in lfs3_config
int lfs3_filebd_create(const struct lfs3_config *cfg, const char *path);
// Clean up memory associated with block device
int lfs3_filebd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_filebd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs3_filebd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs3_filebd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_filebd_sync(const struct lfs3_config *cfg);
#endif
+131
View File
@@ -0,0 +1,131 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bd/lfs3_rambd.h"
int lfs3_rambd_createcfg(const struct lfs3_config *cfg,
const struct lfs3_rambd_config *bdcfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
"%p {.buffer=%p})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
(void*)bdcfg, bdcfg->buffer);
lfs3_rambd_t *bd = cfg->context;
bd->cfg = bdcfg;
// allocate buffer?
if (bd->cfg->buffer) {
bd->buffer = bd->cfg->buffer;
} else {
bd->buffer = lfs3_malloc(cfg->block_size * cfg->block_count);
if (!bd->buffer) {
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg -> %d", LFS3_ERR_NOMEM);
return LFS3_ERR_NOMEM;
}
}
// zero for reproducibility
memset(bd->buffer, 0, cfg->block_size * cfg->block_count);
LFS3_RAMBD_TRACE("lfs3_rambd_createcfg -> %d", 0);
return 0;
}
int lfs3_rambd_create(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count);
static const struct lfs3_rambd_config defaults = {0};
int err = lfs3_rambd_createcfg(cfg, &defaults);
LFS3_RAMBD_TRACE("lfs3_rambd_create -> %d", err);
return err;
}
int lfs3_rambd_destroy(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_destroy(%p)", (void*)cfg);
// clean up memory
lfs3_rambd_t *bd = cfg->context;
if (!bd->cfg->buffer) {
lfs3_free(bd->buffer);
}
LFS3_RAMBD_TRACE("lfs3_rambd_destroy -> %d", 0);
return 0;
}
int lfs3_rambd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size) {
LFS3_RAMBD_TRACE("lfs3_rambd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs3_rambd_t *bd = cfg->context;
// check if read is valid
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->read_size == 0);
LFS3_ASSERT(size % cfg->read_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// read data
memcpy(buffer, &bd->buffer[block*cfg->block_size + off], size);
LFS3_RAMBD_TRACE("lfs3_rambd_read -> %d", 0);
return 0;
}
int lfs3_rambd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size) {
LFS3_RAMBD_TRACE("lfs3_rambd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs3_rambd_t *bd = cfg->context;
// check if write is valid
LFS3_ASSERT(block < cfg->block_count);
LFS3_ASSERT(off % cfg->prog_size == 0);
LFS3_ASSERT(size % cfg->prog_size == 0);
LFS3_ASSERT(off+size <= cfg->block_size);
// program data
memcpy(&bd->buffer[block*cfg->block_size + off], buffer, size);
LFS3_RAMBD_TRACE("lfs3_rambd_prog -> %d", 0);
return 0;
}
int lfs3_rambd_erase(const struct lfs3_config *cfg, lfs3_block_t block) {
LFS3_RAMBD_TRACE("lfs3_rambd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size);
// check if erase is valid
LFS3_ASSERT(block < cfg->block_count);
// erase is a noop
(void)block;
LFS3_RAMBD_TRACE("lfs3_rambd_erase -> %d", 0);
return 0;
}
int lfs3_rambd_sync(const struct lfs3_config *cfg) {
LFS3_RAMBD_TRACE("lfs3_rambd_sync(%p)", (void*)cfg);
// sync is a noop
(void)cfg;
LFS3_RAMBD_TRACE("lfs3_rambd_sync -> %d", 0);
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS3_RAMBD_H
#define LFS3_RAMBD_H
#include "lfs3.h"
#include "lfs3_util.h"
// Block device specific tracing
#ifndef LFS3_RAMBD_TRACE
#ifdef LFS3_RAMBD_YES_TRACE
#define LFS3_RAMBD_TRACE(...) LFS3_TRACE(__VA_ARGS__)
#else
#define LFS3_RAMBD_TRACE(...)
#endif
#endif
// rambd config (optional)
struct lfs3_rambd_config {
// Optional statically allocated buffer for the block device.
void *buffer;
};
// rambd state
typedef struct lfs3_rambd {
uint8_t *buffer;
const struct lfs3_rambd_config *cfg;
} lfs3_rambd_t;
// Create a RAM block device using the geometry in lfs3_config
int lfs3_rambd_create(const struct lfs3_config *cfg);
int lfs3_rambd_createcfg(const struct lfs3_config *cfg,
const struct lfs3_rambd_config *bdcfg);
// Clean up memory associated with block device
int lfs3_rambd_destroy(const struct lfs3_config *cfg);
// Read a block
int lfs3_rambd_read(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, void *buffer, lfs3_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs3_rambd_prog(const struct lfs3_config *cfg, lfs3_block_t block,
lfs3_off_t off, const void *buffer, lfs3_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs3_rambd_erase(const struct lfs3_config *cfg, lfs3_block_t block);
// Sync the block device
int lfs3_rambd_sync(const struct lfs3_config *cfg);
#endif
-262
View File
@@ -1,262 +0,0 @@
/*
* Emulating block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_EMUBD_H
#define LFS_EMUBD_H
#include "lfs.h"
#include "lfs_util.h"
#include "bd/lfs_rambd.h"
#include "bd/lfs_filebd.h"
// Block device specific tracing
#ifndef LFS_EMUBD_TRACE
#ifdef LFS_EMUBD_YES_TRACE
#define LFS_EMUBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_EMUBD_TRACE(...)
#endif
#endif
// Mode determining how "bad-blocks" behave during testing. This simulates
// some real-world circumstances such as progs not sticking (prog-noop),
// a readonly disk (erase-noop), ECC failures (read-error), and of course,
// random bit failures (prog-flip, read-flip)
typedef enum lfs_emubd_badblock_behavior {
LFS_EMUBD_BADBLOCK_PROGERROR = 0, // Error on prog
LFS_EMUBD_BADBLOCK_ERASEERROR = 1, // Error on erase
LFS_EMUBD_BADBLOCK_READERROR = 2, // Error on read
LFS_EMUBD_BADBLOCK_PROGNOOP = 3, // Prog does nothing silently
LFS_EMUBD_BADBLOCK_ERASENOOP = 4, // Erase does nothing silently
LFS_EMUBD_BADBLOCK_PROGFLIP = 5, // Prog flips a bit
LFS_EMUBD_BADBLOCK_READFLIP = 6, // Read flips a bit sometimes
LFS_EMUBD_BADBLOCK_MANUAL = 7, // Bits require manual flipping
} lfs_emubd_badblock_behavior_t;
// Mode determining how power-loss behaves during testing.
typedef enum lfs_emubd_powerloss_behavior {
LFS_EMUBD_POWERLOSS_ATOMIC = 0, // Progs are atomic
LFS_EMUBD_POWERLOSS_SOMEBITS = 1, // One bit is progged
LFS_EMUBD_POWERLOSS_MOSTBITS = 2, // All-but-one bit is progged
LFS_EMUBD_POWERLOSS_OOO = 3, // Blocks are written out-of-order
LFS_EMUBD_POWERLOSS_METASTABLE = 4, // Reads may flip a bit
} lfs_emubd_powerloss_behavior_t;
// Type for measuring read/program/erase operations
typedef uint64_t lfs_emubd_io_t;
typedef int64_t lfs_emubd_sio_t;
// Type for measuring wear
typedef uint32_t lfs_emubd_wear_t;
typedef int32_t lfs_emubd_swear_t;
// Type for tracking power-cycles
typedef uint32_t lfs_emubd_powercycles_t;
typedef int32_t lfs_emubd_spowercycles_t;
// Type for delays in nanoseconds
typedef uint64_t lfs_emubd_sleep_t;
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 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
// of bad blocks is controlled by badblock_behavior.
uint32_t erase_cycles;
// The mode determining how bad-blocks fail
lfs_emubd_badblock_behavior_t badblock_behavior;
// Number of write operations (erase/prog) before triggering a power-loss.
// power_cycles=0 disables this. The exact behavior of power-loss is
// controlled by a combination of powerloss_behavior and powerloss_cb.
lfs_emubd_powercycles_t power_cycles;
// The mode determining how power-loss affects disk
lfs_emubd_powerloss_behavior_t powerloss_behavior;
// Function to call to emulate power-loss. The exact behavior of power-loss
// is up to the runner to provide.
void (*powerloss_cb)(void*);
// Data for power-loss callback
void *powerloss_data;
// Seed for prng, which may be used for emulating failed progs. This does
// not affect normal operation.
uint32_t seed;
// 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;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t read_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t prog_sleep;
// Artificial delay in nanoseconds, there is no purpose for this other
// than slowing down the simulation.
lfs_emubd_sleep_t erase_sleep;
};
// A reference counted block
typedef struct lfs_emubd_block {
uint32_t rc;
lfs_emubd_wear_t wear;
bool metastable;
// sign(bad_bit)=0 => randomized on erase
// sign(bad_bit)=1 => fixed
lfs_size_t bad_bit;
uint8_t data[];
} lfs_emubd_block_t;
// Disk mirror
typedef struct lfs_emubd_disk {
uint32_t rc;
int fd;
uint8_t *scratch;
} lfs_emubd_disk_t;
// emubd state
typedef struct lfs_emubd {
// array of copy-on-write blocks
lfs_emubd_block_t **blocks;
// some other test state
lfs_emubd_io_t readed;
lfs_emubd_io_t proged;
lfs_emubd_io_t erased;
uint32_t prng;
lfs_emubd_powercycles_t power_cycles;
lfs_emubd_block_t **ooo_before;
lfs_emubd_block_t **ooo_after;
lfs_emubd_disk_t *disk;
const struct lfs_emubd_config *cfg;
} lfs_emubd_t;
/// Block device API ///
// Create an emulating block device using the geometry in lfs_config
//
// Note that filebd is used if a path is provided, if path is NULL
// emubd will use rambd which can be much faster.
int lfs_emubd_create(const struct lfs_config *cfg, const char *path);
int lfs_emubd_createcfg(const struct lfs_config *cfg, const char *path,
const struct lfs_emubd_config *bdcfg);
// Clean up memory associated with block device
int lfs_emubd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_emubd_sync(const struct lfs_config *cfg);
/// Additional extended API for driving test features ///
// Set the current prng state
void lfs_emubd_seed(const struct lfs_config *cfg, uint32_t seed);
// Get a pseudo-random number from emubd's internal prng
uint32_t lfs_emubd_prng(const struct lfs_config *cfg);
// Get total amount of bytes read
lfs_emubd_sio_t lfs_emubd_readed(const struct lfs_config *cfg);
// Get total amount of bytes programmed
lfs_emubd_sio_t lfs_emubd_proged(const struct lfs_config *cfg);
// Get total amount of bytes erased
lfs_emubd_sio_t lfs_emubd_erased(const struct lfs_config *cfg);
// Manually set amount of bytes read
int lfs_emubd_setreaded(const struct lfs_config *cfg, lfs_emubd_io_t readed);
// Manually set amount of bytes programmed
int lfs_emubd_setproged(const struct lfs_config *cfg, lfs_emubd_io_t proged);
// Manually set amount of bytes erased
int lfs_emubd_seterased(const struct lfs_config *cfg, lfs_emubd_io_t erased);
// Get simulated wear on a given block
lfs_emubd_swear_t lfs_emubd_wear(const struct lfs_config *cfg,
lfs_block_t block);
// Manually set simulated wear on a given block
int lfs_emubd_setwear(const struct lfs_config *cfg,
lfs_block_t block, lfs_emubd_wear_t wear);
// Mark a block as bad, this is equivalent to setting wear to maximum
int lfs_emubd_markbad(const struct lfs_config *cfg, lfs_block_t block);
// Clear any simulated wear on a given block
int lfs_emubd_markgood(const struct lfs_config *cfg, lfs_block_t block);
// Get which bit failed, this changes on erase/power-loss unless manually set
lfs_ssize_t lfs_emubd_badbit(const struct lfs_config *cfg,
lfs_block_t block);
// Set which bit should fail in a given block
int lfs_emubd_setbadbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Randomize the bad bit on erase (the default)
int lfs_emubd_randomizebadbit(const struct lfs_config *cfg,
lfs_block_t block);
// Mark a block as bad and which bit should fail
int lfs_emubd_markbadbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Flip a bit in a given block, intended for emulating bit errors
int lfs_emubd_flipbit(const struct lfs_config *cfg,
lfs_block_t block, lfs_size_t bit);
// Flip all bits marked as bad
int lfs_emubd_flip(const struct lfs_config *cfg);
// Get the remaining power-cycles
lfs_emubd_spowercycles_t lfs_emubd_powercycles(
const struct lfs_config *cfg);
// Manually set the remaining power-cycles
int lfs_emubd_setpowercycles(const struct lfs_config *cfg,
lfs_emubd_powercycles_t power_cycles);
// Create a copy-on-write copy of the state of this block device
int lfs_emubd_cpy(const struct lfs_config *cfg, lfs_emubd_t *copy);
#endif
-56
View File
@@ -1,56 +0,0 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_FILEBD_H
#define LFS_FILEBD_H
#include "lfs.h"
#include "lfs_util.h"
// Block device specific tracing
#ifndef LFS_FILEBD_TRACE
#ifdef LFS_FILEBD_YES_TRACE
#define LFS_FILEBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_FILEBD_TRACE(...)
#endif
#endif
// filebd state
typedef struct lfs_filebd {
int fd;
} lfs_filebd_t;
// Create a file block device using the geometry in lfs_config
int lfs_filebd_create(const struct lfs_config *cfg, const char *path);
// Clean up memory associated with block device
int lfs_filebd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_filebd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_filebd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_filebd_sync(const struct lfs_config *cfg);
#endif
-131
View File
@@ -1,131 +0,0 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "bd/lfs_rambd.h"
int lfs_rambd_createcfg(const struct lfs_config *cfg,
const struct lfs_rambd_config *bdcfg) {
LFS_RAMBD_TRACE("lfs_rambd_createcfg(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"}, "
"%p {.buffer=%p})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count,
(void*)bdcfg, bdcfg->buffer);
lfs_rambd_t *bd = cfg->context;
bd->cfg = bdcfg;
// allocate buffer?
if (bd->cfg->buffer) {
bd->buffer = bd->cfg->buffer;
} else {
bd->buffer = lfs_malloc(cfg->block_size * cfg->block_count);
if (!bd->buffer) {
LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", LFS_ERR_NOMEM);
return LFS_ERR_NOMEM;
}
}
// zero for reproducibility
memset(bd->buffer, 0, cfg->block_size * cfg->block_count);
LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", 0);
return 0;
}
int lfs_rambd_create(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_create(%p {.context=%p, "
".read=%p, .prog=%p, .erase=%p, .sync=%p, "
".read_size=%"PRIu32", .prog_size=%"PRIu32", "
".block_size=%"PRIu32", .block_count=%"PRIu32"})",
(void*)cfg, cfg->context,
(void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog,
(void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync,
cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count);
static const struct lfs_rambd_config defaults = {0};
int err = lfs_rambd_createcfg(cfg, &defaults);
LFS_RAMBD_TRACE("lfs_rambd_create -> %d", err);
return err;
}
int lfs_rambd_destroy(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_destroy(%p)", (void*)cfg);
// clean up memory
lfs_rambd_t *bd = cfg->context;
if (!bd->cfg->buffer) {
lfs_free(bd->buffer);
}
LFS_RAMBD_TRACE("lfs_rambd_destroy -> %d", 0);
return 0;
}
int lfs_rambd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) {
LFS_RAMBD_TRACE("lfs_rambd_read(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_rambd_t *bd = cfg->context;
// check if read is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->read_size == 0);
LFS_ASSERT(size % cfg->read_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
// read data
memcpy(buffer, &bd->buffer[block*cfg->block_size + off], size);
LFS_RAMBD_TRACE("lfs_rambd_read -> %d", 0);
return 0;
}
int lfs_rambd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size) {
LFS_RAMBD_TRACE("lfs_rambd_prog(%p, "
"0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
(void*)cfg, block, off, buffer, size);
lfs_rambd_t *bd = cfg->context;
// check if write is valid
LFS_ASSERT(block < cfg->block_count);
LFS_ASSERT(off % cfg->prog_size == 0);
LFS_ASSERT(size % cfg->prog_size == 0);
LFS_ASSERT(off+size <= cfg->block_size);
// program data
memcpy(&bd->buffer[block*cfg->block_size + off], buffer, size);
LFS_RAMBD_TRACE("lfs_rambd_prog -> %d", 0);
return 0;
}
int lfs_rambd_erase(const struct lfs_config *cfg, lfs_block_t block) {
LFS_RAMBD_TRACE("lfs_rambd_erase(%p, 0x%"PRIx32" (%"PRIu32"))",
(void*)cfg, block, cfg->block_size);
// check if erase is valid
LFS_ASSERT(block < cfg->block_count);
// erase is a noop
(void)block;
LFS_RAMBD_TRACE("lfs_rambd_erase -> %d", 0);
return 0;
}
int lfs_rambd_sync(const struct lfs_config *cfg) {
LFS_RAMBD_TRACE("lfs_rambd_sync(%p)", (void*)cfg);
// sync is a noop
(void)cfg;
LFS_RAMBD_TRACE("lfs_rambd_sync -> %d", 0);
return 0;
}
-65
View File
@@ -1,65 +0,0 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS_RAMBD_H
#define LFS_RAMBD_H
#include "lfs.h"
#include "lfs_util.h"
// Block device specific tracing
#ifndef LFS_RAMBD_TRACE
#ifdef LFS_RAMBD_YES_TRACE
#define LFS_RAMBD_TRACE(...) LFS_TRACE(__VA_ARGS__)
#else
#define LFS_RAMBD_TRACE(...)
#endif
#endif
// rambd config (optional)
struct lfs_rambd_config {
// Optional statically allocated buffer for the block device.
void *buffer;
};
// rambd state
typedef struct lfs_rambd {
uint8_t *buffer;
const struct lfs_rambd_config *cfg;
} lfs_rambd_t;
// Create a RAM block device using the geometry in lfs_config
int lfs_rambd_create(const struct lfs_config *cfg);
int lfs_rambd_createcfg(const struct lfs_config *cfg,
const struct lfs_rambd_config *bdcfg);
// Clean up memory associated with block device
int lfs_rambd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs_rambd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a block
//
// The block must have previously been erased.
int lfs_rambd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
int lfs_rambd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs_rambd_sync(const struct lfs_config *cfg);
#endif
+5213 -5209
View File
File diff suppressed because it is too large Load Diff
+426 -419
View File
File diff suppressed because it is too large Load Diff
+43 -43
View File
@@ -1,22 +1,22 @@
/* /*
* lfs util functions * lfs3 util functions
* *
* Copyright (c) 2022, The littlefs authors. * Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved. * Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include "lfs_util.h" #include "lfs3_util.h"
// Only compile if user does not provide custom config // Only compile if user does not provide custom config
#ifndef LFS_CONFIG #ifndef LFS3_CONFIG
// Need lfs.h for error codes // Need lfs3.h for error codes
// TODO should we actually move the error codes to lfs_util.h? // TODO should we actually move the error codes to lfs3_util.h?
#include "lfs.h" #include "lfs3.h"
// Convert to/from leb128 encoding // Convert to/from leb128 encoding
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size) { ssize_t lfs3_toleb128(uint32_t word, void *buffer, size_t size) {
uint8_t *data = buffer; uint8_t *data = buffer;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
@@ -31,10 +31,10 @@ ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size) {
} }
// buffer overflow? // buffer overflow?
LFS_UNREACHABLE(); LFS3_UNREACHABLE();
} }
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) { ssize_t lfs3_fromleb128(uint32_t *word, const void *buffer, size_t size) {
const uint8_t *data = buffer; const uint8_t *data = buffer;
int32_t word_ = 0; int32_t word_ = 0;
@@ -44,7 +44,7 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
if (!(dat & 0x80)) { if (!(dat & 0x80)) {
// did we overflow? // did we overflow?
if ((word_ >> 7*i) != dat) { if ((word_ >> 7*i) != dat) {
return LFS_ERR_CORRUPT; return LFS3_ERR_CORRUPT;
} }
*word = word_; *word = word_;
@@ -53,15 +53,15 @@ ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size) {
} }
// truncated? // truncated?
return LFS_ERR_CORRUPT; return LFS3_ERR_CORRUPT;
} }
// crc32c tables (see lfs_crc32c for more info) // crc32c tables (see lfs3_crc32c for more info)
#if !defined(LFS_SMALLER_CRC32C) \ #if !defined(LFS3_SMALLER_CRC32C) \
&& !defined(LFS_FASTER_CRC32C) \ && !defined(LFS3_FASTER_CRC32C) \
&& !defined(LFS_PMUL_CRC32C) && !defined(LFS3_PMUL_CRC32C)
static const uint32_t lfs_crc32c_table[16] = { static const uint32_t lfs3_crc32c_table[16] = {
0x00000000, 0x105ec76f, 0x20bd8ede, 0x30e349b1, 0x00000000, 0x105ec76f, 0x20bd8ede, 0x30e349b1,
0x417b1dbc, 0x5125dad3, 0x61c69362, 0x7198540d, 0x417b1dbc, 0x5125dad3, 0x61c69362, 0x7198540d,
0x82f63b78, 0x92a8fc17, 0xa24bb5a6, 0xb21572c9, 0x82f63b78, 0x92a8fc17, 0xa24bb5a6, 0xb21572c9,
@@ -69,10 +69,10 @@ static const uint32_t lfs_crc32c_table[16] = {
}; };
#endif #endif
#if defined(LFS_FASTER_CRC32C) \ #if defined(LFS3_FASTER_CRC32C) \
&& !defined(LFS_SMALLER_CRC32C) \ && !defined(LFS3_SMALLER_CRC32C) \
&& !defined(LFS_PMUL_CRC32C) && !defined(LFS3_PMUL_CRC32C)
static const uint32_t lfs_crc32c_table[256] = { static const uint32_t lfs3_crc32c_table[256] = {
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
@@ -142,7 +142,7 @@ static const uint32_t lfs_crc32c_table[256] = {
// Calculate crc32c incrementally // Calculate crc32c incrementally
uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) { uint32_t lfs3_crc32c(uint32_t crc, const void *buffer, size_t size) {
// init with 0xffffffff so prefixed zeros affect the crc // init with 0xffffffff so prefixed zeros affect the crc
const uint8_t *buffer_ = buffer; const uint8_t *buffer_ = buffer;
crc ^= 0xffffffff; crc ^= 0xffffffff;
@@ -179,7 +179,7 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
// PCLMULQDQ Instruction whitepaper is an excellent resource on this // PCLMULQDQ Instruction whitepaper is an excellent resource on this
// topic. // topic.
// //
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C) #if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// naive reduce // naive reduce
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
crc = crc ^ buffer_[i]; crc = crc ^ buffer_[i];
@@ -188,36 +188,36 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
} }
} }
#elif !defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C) #elif !defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via small table // reduce via small table
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
crc = (crc >> 4) ^ lfs_crc32c_table[0xf & (crc ^ (buffer_[i] >> 0))]; crc = (crc >> 4) ^ lfs3_crc32c_table[0xf & (crc ^ (buffer_[i] >> 0))];
crc = (crc >> 4) ^ lfs_crc32c_table[0xf & (crc ^ (buffer_[i] >> 4))]; crc = (crc >> 4) ^ lfs3_crc32c_table[0xf & (crc ^ (buffer_[i] >> 4))];
} }
#elif defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C) #elif defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via big table // reduce via big table
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
crc = (crc >> 8) ^ lfs_crc32c_table[0xff & (crc ^ buffer_[i])]; crc = (crc >> 8) ^ lfs3_crc32c_table[0xff & (crc ^ buffer_[i])];
} }
#elif defined(LFS_PMUL_CRC32C) #elif defined(LFS3_PMUL_CRC32C)
// reduce via Barret reduction // reduce via Barret reduction
for (size_t i = 0; i < size;) { for (size_t i = 0; i < size;) {
// align to 32-bits // align to 32-bits
if ((uintptr_t)&buffer_[i] % sizeof(uint32_t) == 0 if ((uintptr_t)&buffer_[i] % sizeof(uint32_t) == 0
&& i+sizeof(uint32_t) < size) { && i+sizeof(uint32_t) < size) {
crc = crc ^ lfs_fromle32_(&buffer_[i]); crc = crc ^ lfs3_fromle32_(&buffer_[i]);
crc = lfs_pmul( crc = lfs3_pmul(
lfs_pmul(crc, 0xdea713f1), lfs3_pmul(crc, 0xdea713f1),
0x82f63b78) 0x82f63b78)
>> 31; >> 31;
i += 4; i += 4;
} else { } else {
crc = crc ^ buffer_[i]; crc = crc ^ buffer_[i];
crc = (crc >> 8) crc = (crc >> 8)
^ (lfs_pmul( ^ (lfs3_pmul(
lfs_pmul(crc << 24, 0xdea713f1), lfs3_pmul(crc << 24, 0xdea713f1),
0x82f63b78) 0x82f63b78)
>> 31); >> 31);
i += 1; i += 1;
@@ -232,7 +232,7 @@ uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size) {
} }
// Multiply two crc32cs in the crc32c ring // Multiply two crc32cs in the crc32c ring
uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b) { uint32_t lfs3_crc32c_mul(uint32_t a, uint32_t b) {
// Multiplication in a crc32c ring involves polynomial // Multiplication in a crc32c ring involves polynomial
// multiplication modulo the crc32c polynomial to keep things // multiplication modulo the crc32c polynomial to keep things
// finite: // finite:
@@ -247,33 +247,33 @@ uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b) {
// This gets a bit funky because crc32cs are little-endian, but // This gets a bit funky because crc32cs are little-endian, but
// fortunately pmul is symmetric. Though the result is awkwardly // fortunately pmul is symmetric. Though the result is awkwardly
// 63-bits, so we need to shift by 1. // 63-bits, so we need to shift by 1.
uint64_t r = lfs_pmul(a, b) << 1; uint64_t r = lfs3_pmul(a, b) << 1;
// We can accelerate our module with crc32c tables if present, these // We can accelerate our module with crc32c tables if present, these
// loops may look familiar. // loops may look familiar.
#if defined(LFS_SMALLER_CRC32C) && !defined(LFS_PMUL_CRC32C) #if defined(LFS3_SMALLER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// naive reduce // naive reduce
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
r = (r >> 1) ^ ((r & 1) ? 0x82f63b78 : 0); r = (r >> 1) ^ ((r & 1) ? 0x82f63b78 : 0);
} }
#elif !defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C) #elif !defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via small table // reduce via small table
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
r = (r >> 4) ^ lfs_crc32c_table[0xf & r]; r = (r >> 4) ^ lfs3_crc32c_table[0xf & r];
} }
#elif defined(LFS_FASTER_CRC32C) && !defined(LFS_PMUL_CRC32C) #elif defined(LFS3_FASTER_CRC32C) && !defined(LFS3_PMUL_CRC32C)
// reduce via big table // reduce via big table
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
r = (r >> 8) ^ lfs_crc32c_table[0xff & r]; r = (r >> 8) ^ lfs3_crc32c_table[0xff & r];
} }
#elif defined(LFS_PMUL_CRC32C) #elif defined(LFS3_PMUL_CRC32C)
// reduce via Barret reduction // reduce via Barret reduction
r = (r >> 32) r = (r >> 32)
^ (lfs_pmul( ^ (lfs3_pmul(
lfs_pmul(r, 0xdea713f1), lfs3_pmul(r, 0xdea713f1),
0x82f63b78) 0x82f63b78)
>> 31); >> 31);
#endif #endif
+211 -211
View File
@@ -1,93 +1,93 @@
/* /*
* lfs utility functions * lfs3 utility functions
* *
* Copyright (c) 2022, The littlefs authors. * Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved. * Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#ifndef LFS_UTIL_H #ifndef LFS3_UTIL_H
#define LFS_UTIL_H #define LFS3_UTIL_H
// Users can override lfs_util.h with their own configuration by defining // Users can override lfs3_util.h with their own configuration by defining
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h). // LFS3_CONFIG as a header file to include (-DLFS_CONFIG=lfs3_config.h).
// //
// If LFS_CONFIG is used, none of the default utils will be emitted and must be // If LFS3_CONFIG is used, none of the default utils will be emitted and must be
// provided by the config file. To start, I would suggest copying lfs_util.h // provided by the config file. To start, I would suggest copying lfs3_util.h
// and modifying as needed. // and modifying as needed.
#ifdef LFS_CONFIG #ifdef LFS3_CONFIG
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x) #define LFS3_STRINGIZE(x) LFS3_STRINGIZE2(x)
#define LFS_STRINGIZE2(x) #x #define LFS3_STRINGIZE2(x) #x
#include LFS_STRINGIZE(LFS_CONFIG) #include LFS3_STRINGIZE(LFS3_CONFIG)
#else #else
// Some convenient macro aliases // Some convenient macro aliases
// TODO move these to something like lfs_cfg.h? // TODO move these to something like lfs3_cfg.h?
// LFS_BIGGEST enables all opt-in features // LFS3_BIGGEST enables all opt-in features
#ifdef LFS_BIGGEST #ifdef LFS3_BIGGEST
#ifndef LFS_REVDBG #ifndef LFS3_REVDBG
#define LFS_REVDBG #define LFS3_REVDBG
#endif #endif
#ifndef LFS_REVNOISE #ifndef LFS3_REVNOISE
#define LFS_REVNOISE #define LFS3_REVNOISE
#endif #endif
#ifndef LFS_CKPROGS #ifndef LFS3_CKPROGS
#define LFS_CKPROGS #define LFS3_CKPROGS
#endif #endif
#ifndef LFS_CKFETCHES #ifndef LFS3_CKFETCHES
#define LFS_CKFETCHES #define LFS3_CKFETCHES
#endif #endif
#ifndef LFS_CKMETAPARITY #ifndef LFS3_CKMETAPARITY
#define LFS_CKMETAPARITY #define LFS3_CKMETAPARITY
#endif #endif
#ifndef LFS_CKDATACKSUMREADS #ifndef LFS3_CKDATACKSUMREADS
#define LFS_CKDATACKSUMREADS #define LFS3_CKDATACKSUMREADS
#endif #endif
#ifndef LFS_GC #ifndef LFS3_GC
#define LFS_GC #define LFS3_GC
#endif #endif
#endif #endif
// LFS_YES_* variants imply the relevant LFS_* macro // LFS3_YES_* variants imply the relevant LFS3_* macro
#ifdef LFS_YES_RDONLY #ifdef LFS3_YES_RDONLY
#define LFS_RDONLY #define LFS3_RDONLY
#endif #endif
#ifdef LFS_YES_REVDBG #ifdef LFS3_YES_REVDBG
#define LFS_REVDBG #define LFS3_REVDBG
#endif #endif
#ifdef LFS_YES_REVNOISE #ifdef LFS3_YES_REVNOISE
#define LFS_REVNOISE #define LFS3_REVNOISE
#endif #endif
#ifdef LFS_YES_CKPROGS #ifdef LFS3_YES_CKPROGS
#define LFS_CKPROGS #define LFS3_CKPROGS
#endif #endif
#ifdef LFS_YES_CKFETCHES #ifdef LFS3_YES_CKFETCHES
#define LFS_CKFETCHES #define LFS3_CKFETCHES
#endif #endif
#ifdef LFS_YES_CKMETAPARITY #ifdef LFS3_YES_CKMETAPARITY
#define LFS_CKMETAPARITY #define LFS3_CKMETAPARITY
#endif #endif
#ifdef LFS_YES_CKDATACKSUMREADS #ifdef LFS3_YES_CKDATACKSUMREADS
#define LFS_CKDATACKSUMREADS #define LFS3_CKDATACKSUMREADS
#endif #endif
#ifdef LFS_YES_GC #ifdef LFS3_YES_GC
#define LFS_GC #define LFS3_GC
#endif #endif
// LFS_NO_LOG disables all logging macros // LFS3_NO_LOG disables all logging macros
#ifdef LFS_NO_LOG #ifdef LFS3_NO_LOG
#ifndef LFS_NO_DEBUG #ifndef LFS3_NO_DEBUG
#define LFS_NO_DEBUG #define LFS3_NO_DEBUG
#endif #endif
#ifndef LFS_NO_INFO #ifndef LFS3_NO_INFO
#define LFS_NO_INFO #define LFS3_NO_INFO
#endif #endif
#ifndef LFS_NO_WARN #ifndef LFS3_NO_WARN
#define LFS_NO_WARN #define LFS3_NO_WARN
#endif #endif
#ifndef LFS_NO_ERROR #ifndef LFS3_NO_ERROR
#define LFS_NO_ERROR #define LFS3_NO_ERROR
#endif #endif
#endif #endif
@@ -97,20 +97,20 @@
#include <stdbool.h> #include <stdbool.h>
#include <sys/types.h> #include <sys/types.h>
#include <inttypes.h> #include <inttypes.h>
#ifndef LFS_NO_STRINGH #ifndef LFS3_NO_STRINGH
#include <string.h> #include <string.h>
#endif #endif
#ifndef LFS_NO_MALLOC #ifndef LFS3_NO_MALLOC
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#ifndef LFS_NO_ASSERT #ifndef LFS3_NO_ASSERT
#include <assert.h> #include <assert.h>
#endif #endif
#if !defined(LFS_NO_DEBUG) || \ #if !defined(LFS3_NO_DEBUG) || \
!defined(LFS_NO_INFO) || \ !defined(LFS3_NO_INFO) || \
!defined(LFS_NO_WARN) || \ !defined(LFS3_NO_WARN) || \
!defined(LFS_NO_ERROR) || \ !defined(LFS3_NO_ERROR) || \
defined(LFS_YES_TRACE) defined(LFS3_YES_TRACE)
#include <stdio.h> #include <stdio.h>
#endif #endif
@@ -120,139 +120,139 @@
// code footprint // code footprint
// Logging functions // Logging functions
#ifndef LFS_TRACE #ifndef LFS3_TRACE
#ifdef LFS_YES_TRACE #ifdef LFS3_YES_TRACE
#define LFS_TRACE_(fmt, ...) \ #define LFS3_TRACE_(fmt, ...) \
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") #define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#else #else
#define LFS_TRACE(...) #define LFS3_TRACE(...)
#endif #endif
#endif #endif
#ifndef LFS_DEBUG #ifndef LFS3_DEBUG
#ifndef LFS_NO_DEBUG #ifndef LFS3_NO_DEBUG
#define LFS_DEBUG_(fmt, ...) \ #define LFS3_DEBUG_(fmt, ...) \
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "") #define LFS3_DEBUG(...) LFS3_DEBUG_(__VA_ARGS__, "")
#else #else
#define LFS_DEBUG(...) #define LFS3_DEBUG(...)
#endif #endif
#endif #endif
#ifndef LFS_INFO #ifndef LFS3_INFO
#ifndef LFS_NO_INFO #ifndef LFS3_NO_INFO
#define LFS_INFO_(fmt, ...) \ #define LFS3_INFO_(fmt, ...) \
printf("%s:%d:info: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) printf("%s:%d:info: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_INFO(...) LFS_INFO_(__VA_ARGS__, "") #define LFS3_INFO(...) LFS3_INFO_(__VA_ARGS__, "")
#else #else
#define LFS_INFO(...) #define LFS3_INFO(...)
#endif #endif
#endif #endif
#ifndef LFS_WARN #ifndef LFS3_WARN
#ifndef LFS_NO_WARN #ifndef LFS3_NO_WARN
#define LFS_WARN_(fmt, ...) \ #define LFS3_WARN_(fmt, ...) \
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "") #define LFS3_WARN(...) LFS3_WARN_(__VA_ARGS__, "")
#else #else
#define LFS_WARN(...) #define LFS3_WARN(...)
#endif #endif
#endif #endif
#ifndef LFS_ERROR #ifndef LFS3_ERROR
#ifndef LFS_NO_ERROR #ifndef LFS3_NO_ERROR
#define LFS_ERROR_(fmt, ...) \ #define LFS3_ERROR_(fmt, ...) \
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "") #define LFS3_ERROR(...) LFS3_ERROR_(__VA_ARGS__, "")
#else #else
#define LFS_ERROR(...) #define LFS3_ERROR(...)
#endif #endif
#endif #endif
// Runtime assertions // Runtime assertions
#ifndef LFS_ASSERT #ifndef LFS3_ASSERT
#ifndef LFS_NO_ASSERT #ifndef LFS3_NO_ASSERT
#define LFS_ASSERT(test) assert(test) #define LFS3_ASSERT(test) assert(test)
#else #else
#define LFS_ASSERT(test) #define LFS3_ASSERT(test)
#endif #endif
#endif #endif
#ifndef LFS_UNREACHABLE #ifndef LFS3_UNREACHABLE
#ifndef LFS_NO_ASSERT #ifndef LFS3_NO_ASSERT
#define LFS_UNREACHABLE() LFS_ASSERT(false) #define LFS3_UNREACHABLE() LFS3_ASSERT(false)
#elif !defined(LFS_NO_BUILTINS) #elif !defined(LFS3_NO_BUILTINS)
#define LFS_UNREACHABLE() __builtin_unreachable() #define LFS3_UNREACHABLE() __builtin_unreachable()
#else #else
#define LFS_UNREACHABLE() #define LFS3_UNREACHABLE()
#endif #endif
#endif #endif
// Some ifdef conveniences // Some ifdef conveniences
#ifdef LFS_REVDBG #ifdef LFS3_REVDBG
#define LFS_IFDEF_REVDBG(a, b) (a) #define LFS3_IFDEF_REVDBG(a, b) (a)
#else #else
#define LFS_IFDEF_REVDBG(a, b) (b) #define LFS3_IFDEF_REVDBG(a, b) (b)
#endif #endif
#ifdef LFS_REVNOISE #ifdef LFS3_REVNOISE
#define LFS_IFDEF_REVNOISE(a, b) (a) #define LFS3_IFDEF_REVNOISE(a, b) (a)
#else #else
#define LFS_IFDEF_REVNOISE(a, b) (b) #define LFS3_IFDEF_REVNOISE(a, b) (b)
#endif #endif
#ifdef LFS_CKPROGS #ifdef LFS3_CKPROGS
#define LFS_IFDEF_CKPROGS(a, b) (a) #define LFS3_IFDEF_CKPROGS(a, b) (a)
#else #else
#define LFS_IFDEF_CKPROGS(a, b) (b) #define LFS3_IFDEF_CKPROGS(a, b) (b)
#endif #endif
#ifdef LFS_CKFETCHES #ifdef LFS3_CKFETCHES
#define LFS_IFDEF_CKFETCHES(a, b) (a) #define LFS3_IFDEF_CKFETCHES(a, b) (a)
#else #else
#define LFS_IFDEF_CKFETCHES(a, b) (b) #define LFS3_IFDEF_CKFETCHES(a, b) (b)
#endif #endif
#ifdef LFS_CKMETAPARITY #ifdef LFS3_CKMETAPARITY
#define LFS_IFDEF_CKMETAPARITY(a, b) (a) #define LFS3_IFDEF_CKMETAPARITY(a, b) (a)
#else #else
#define LFS_IFDEF_CKMETAPARITY(a, b) (b) #define LFS3_IFDEF_CKMETAPARITY(a, b) (b)
#endif #endif
#ifdef LFS_CKDATACKSUMREADS #ifdef LFS3_CKDATACKSUMREADS
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (a) #define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (a)
#else #else
#define LFS_IFDEF_CKDATACKSUMREADS(a, b) (b) #define LFS3_IFDEF_CKDATACKSUMREADS(a, b) (b)
#endif #endif
#ifdef LFS_GC #ifdef LFS3_GC
#define LFS_IFDEF_GC(a, b) (a) #define LFS3_IFDEF_GC(a, b) (a)
#else #else
#define LFS_IFDEF_GC(a, b) (b) #define LFS3_IFDEF_GC(a, b) (b)
#endif #endif
// Some function attributes, no way around these // Some function attributes, no way around these
// Force a function to be inlined // Force a function to be inlined
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__) #if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
#define LFS_FORCEINLINE __attribute__((always_inline)) #define LFS3_FORCEINLINE __attribute__((always_inline))
#else #else
#define LFS_FORCEINLINE #define LFS3_FORCEINLINE
#endif #endif
// Force a function to _not_ be inlined // Force a function to _not_ be inlined
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__) #if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
#define LFS_NOINLINE __attribute__((noinline)) #define LFS3_NOINLINE __attribute__((noinline))
#else #else
#define LFS_NOINLINE #define LFS3_NOINLINE
#endif #endif
// Builtin functions, these may be replaced by more efficient // Builtin functions, these may be replaced by more efficient
// toolchain-specific implementations. LFS_NO_BUILTINS falls back to a more // toolchain-specific implementations. LFS3_NO_BUILTINS falls back to a more
// expensive basic C implementation for debugging purposes // expensive basic C implementation for debugging purposes
// //
// Most of the backup implementations are based on the infamous Bit // Most of the backup implementations are based on the infamous Bit
@@ -261,33 +261,33 @@
// //
// Compile time min/max // Compile time min/max
#define LFS_MIN(a, b) ((a < b) ? a : b) #define LFS3_MIN(a, b) ((a < b) ? a : b)
#define LFS_MAX(a, b) ((a > b) ? a : b) #define LFS3_MAX(a, b) ((a > b) ? a : b)
// Min/max functions for unsigned 32-bit numbers // Min/max functions for unsigned 32-bit numbers
static inline uint32_t lfs_min(uint32_t a, uint32_t b) { static inline uint32_t lfs3_min(uint32_t a, uint32_t b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
static inline uint32_t lfs_max(uint32_t a, uint32_t b) { static inline uint32_t lfs3_max(uint32_t a, uint32_t b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
static inline int32_t lfs_smin(int32_t a, int32_t b) { static inline int32_t lfs3_smin(int32_t a, int32_t b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
static inline int32_t lfs_smax(int32_t a, int32_t b) { static inline int32_t lfs3_smax(int32_t a, int32_t b) {
return (a > b) ? a : b; return (a > b) ? a : b;
} }
// Absolute value of signed numbers // Absolute value of signed numbers
static inline int32_t lfs_abs(int32_t a) { static inline int32_t lfs3_abs(int32_t a) {
return (a < 0) ? -a : a; return (a < 0) ? -a : a;
} }
// Swap two variables // Swap two variables
#define LFS_SWAP(_t, _a, _b) \ #define LFS3_SWAP(_t, _a, _b) \
do { \ do { \
_t *a = _a; \ _t *a = _a; \
_t *b = _b; \ _t *b = _b; \
@@ -297,22 +297,22 @@ static inline int32_t lfs_abs(int32_t a) {
} while (0) } while (0)
// Align to nearest multiple of a size // Align to nearest multiple of a size
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) { static inline uint32_t lfs3_aligndown(uint32_t a, uint32_t alignment) {
return a - (a % alignment); return a - (a % alignment);
} }
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) { static inline uint32_t lfs3_alignup(uint32_t a, uint32_t alignment) {
return lfs_aligndown(a + alignment-1, alignment); return lfs3_aligndown(a + alignment-1, alignment);
} }
// Find the smallest power of 2 greater than or equal to a // Find the smallest power of 2 greater than or equal to a
static inline uint32_t lfs_nlog2(uint32_t a) { static inline uint32_t lfs3_nlog2(uint32_t a) {
// __builtin_clz of zero is undefined, so treat both 0 and 1 specially // __builtin_clz of zero is undefined, so treat both 0 and 1 specially
if (a <= 1) { if (a <= 1) {
return a; return a;
} }
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM)) #if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return 32 - __builtin_clz(a-1); return 32 - __builtin_clz(a-1);
#else #else
uint32_t r = 0; uint32_t r = 0;
@@ -327,18 +327,18 @@ static inline uint32_t lfs_nlog2(uint32_t a) {
} }
// Count the number of trailing binary zeros in a // Count the number of trailing binary zeros in a
// lfs_ctz(0) may be undefined // lfs3_ctz(0) may be undefined
static inline uint32_t lfs_ctz(uint32_t a) { static inline uint32_t lfs3_ctz(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && defined(__GNUC__) #if !defined(LFS3_NO_BUILTINS) && defined(__GNUC__)
return __builtin_ctz(a); return __builtin_ctz(a);
#else #else
return lfs_nlog2((a & -a) + 1) - 1; return lfs3_nlog2((a & -a) + 1) - 1;
#endif #endif
} }
// Count the number of binary ones in a // Count the number of binary ones in a
static inline uint32_t lfs_popc(uint32_t a) { static inline uint32_t lfs3_popc(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM)) #if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_popcount(a); return __builtin_popcount(a);
#else #else
a = a - ((a >> 1) & 0x55555555); a = a - ((a >> 1) & 0x55555555);
@@ -349,8 +349,8 @@ static inline uint32_t lfs_popc(uint32_t a) {
} }
// Returns true if there is an odd number of binary ones in a // Returns true if there is an odd number of binary ones in a
static inline bool lfs_parity(uint32_t a) { static inline bool lfs3_parity(uint32_t a) {
#if !defined(LFS_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM)) #if !defined(LFS3_NO_BUILTINS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_parity(a); return __builtin_parity(a);
#else #else
a ^= a >> 16; a ^= a >> 16;
@@ -362,7 +362,7 @@ static inline bool lfs_parity(uint32_t a) {
// Find the sequence comparison of a and b, this is the distance // Find the sequence comparison of a and b, this is the distance
// between a and b ignoring overflow // between a and b ignoring overflow
static inline int lfs_scmp(uint32_t a, uint32_t b) { static inline int lfs3_scmp(uint32_t a, uint32_t b) {
return (int)(unsigned)(a - b); return (int)(unsigned)(a - b);
} }
@@ -371,7 +371,7 @@ static inline int lfs_scmp(uint32_t a, uint32_t b) {
// This is a multiply where all adds are replaced with xors. If we view // This is a multiply where all adds are replaced with xors. If we view
// a and b as binary polynomials, xor is polynomial addition and pmul is // a and b as binary polynomials, xor is polynomial addition and pmul is
// polynomial multiplication. // polynomial multiplication.
static inline uint64_t lfs_pmul(uint32_t a, uint32_t b) { static inline uint64_t lfs3_pmul(uint32_t a, uint32_t b) {
uint64_t r = 0; uint64_t r = 0;
uint64_t a_ = a; uint64_t a_ = a;
while (b) { while (b) {
@@ -386,14 +386,14 @@ static inline uint64_t lfs_pmul(uint32_t a, uint32_t b) {
// Convert to/from 32-bit little-endian // Convert to/from 32-bit little-endian
static inline void lfs_tole32(uint32_t word, void *buffer) { static inline void lfs3_tole32(uint32_t word, void *buffer) {
((uint8_t*)buffer)[0] = word >> 0; ((uint8_t*)buffer)[0] = word >> 0;
((uint8_t*)buffer)[1] = word >> 8; ((uint8_t*)buffer)[1] = word >> 8;
((uint8_t*)buffer)[2] = word >> 16; ((uint8_t*)buffer)[2] = word >> 16;
((uint8_t*)buffer)[3] = word >> 24; ((uint8_t*)buffer)[3] = word >> 24;
} }
static inline uint32_t lfs_fromle32(const void *buffer) { static inline uint32_t lfs3_fromle32(const void *buffer) {
return (((uint8_t*)buffer)[0] << 0) return (((uint8_t*)buffer)[0] << 0)
| (((uint8_t*)buffer)[1] << 8) | (((uint8_t*)buffer)[1] << 8)
| (((uint8_t*)buffer)[2] << 16) | (((uint8_t*)buffer)[2] << 16)
@@ -401,19 +401,19 @@ static inline uint32_t lfs_fromle32(const void *buffer) {
} }
// Convert to/from leb128 encoding // Convert to/from leb128 encoding
// TODO should we really be using ssize_t here and not lfs_ssize_t? // TODO should we really be using ssize_t here and not lfs3_ssize_t?
ssize_t lfs_toleb128(uint32_t word, void *buffer, size_t size); ssize_t lfs3_toleb128(uint32_t word, void *buffer, size_t size);
ssize_t lfs_fromleb128(uint32_t *word, const void *buffer, size_t size); ssize_t lfs3_fromleb128(uint32_t *word, const void *buffer, size_t size);
// Compare n bytes of memory // Compare n bytes of memory
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_memcmp memcmp #define lfs3_memcmp memcmp
#elif !defined(LFS_NO_BUILTINS) #elif !defined(LFS3_NO_BUILTINS)
#define lfs_memcmp __builtin_memcmp #define lfs3_memcmp __builtin_memcmp
#else #else
static inline int lfs_memcmp(const void *a, const void *b, size_t size) { static inline int lfs3_memcmp(const void *a, const void *b, size_t size) {
const uint8_t *a_ = a; const uint8_t *a_ = a;
const uint8_t *b_ = b; const uint8_t *b_ = b;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
@@ -427,12 +427,12 @@ static inline int lfs_memcmp(const void *a, const void *b, size_t size) {
#endif #endif
// Copy n bytes from src to dst, src and dst must not overlap // Copy n bytes from src to dst, src and dst must not overlap
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_memcpy memcpy #define lfs3_memcpy memcpy
#elif !defined(LFS_NO_BUILTINS) #elif !defined(LFS3_NO_BUILTINS)
#define lfs_memcpy __builtin_memcpy #define lfs3_memcpy __builtin_memcpy
#else #else
static inline void *lfs_memcpy( static inline void *lfs3_memcpy(
void *restrict dst, const void *restrict src, size_t size) { void *restrict dst, const void *restrict src, size_t size) {
uint8_t *dst_ = dst; uint8_t *dst_ = dst;
const uint8_t *src_ = src; const uint8_t *src_ = src;
@@ -445,12 +445,12 @@ static inline void *lfs_memcpy(
#endif #endif
// Copy n bytes from src to dst, src and dst may overlap // Copy n bytes from src to dst, src and dst may overlap
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_memmove memmove #define lfs3_memmove memmove
#elif !defined(LFS_NO_BUILTINS) #elif !defined(LFS3_NO_BUILTINS)
#define lfs_memmove __builtin_memmove #define lfs3_memmove __builtin_memmove
#else #else
static inline void *lfs_memmove(void *dst, const void *src, size_t size) { static inline void *lfs3_memmove(void *dst, const void *src, size_t size) {
uint8_t *dst_ = dst; uint8_t *dst_ = dst;
const uint8_t *src_ = src; const uint8_t *src_ = src;
if (dst_ < src_) { if (dst_ < src_) {
@@ -468,12 +468,12 @@ static inline void *lfs_memmove(void *dst, const void *src, size_t size) {
#endif #endif
// Set n bytes to c // Set n bytes to c
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_memset memset #define lfs3_memset memset
#elif !defined(LFS_NO_BUILTINS) #elif !defined(LFS3_NO_BUILTINS)
#define lfs_memset __builtin_memset #define lfs3_memset __builtin_memset
#else #else
static inline void *lfs_memset(void *dst, int c, size_t size) { static inline void *lfs3_memset(void *dst, int c, size_t size) {
uint8_t *dst_ = dst; uint8_t *dst_ = dst;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
dst_[i] = c; dst_[i] = c;
@@ -484,10 +484,10 @@ static inline void *lfs_memset(void *dst, int c, size_t size) {
#endif #endif
// Find the first occurrence of c or NULL // Find the first occurrence of c or NULL
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_memchr memchr #define lfs3_memchr memchr
#else #else
static inline void *lfs_memchr(const void *a, int c, size_t size) { static inline void *lfs3_memchr(const void *a, int c, size_t size) {
const uint8_t *a_ = a; const uint8_t *a_ = a;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if (a_[i] == c) { if (a_[i] == c) {
@@ -500,7 +500,7 @@ static inline void *lfs_memchr(const void *a, int c, size_t size) {
#endif #endif
// Find the first occurrence of anything not c or NULL // Find the first occurrence of anything not c or NULL
static inline void *lfs_memcchr(const void *a, int c, size_t size) { static inline void *lfs3_memcchr(const void *a, int c, size_t size) {
const uint8_t *a_ = a; const uint8_t *a_ = a;
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if (a_[i] != c) { if (a_[i] != c) {
@@ -512,7 +512,7 @@ static inline void *lfs_memcchr(const void *a, int c, size_t size) {
} }
// Find the minimum length that includes all non-zero bytes // Find the minimum length that includes all non-zero bytes
static inline size_t lfs_memlen(const void *a, size_t size) { static inline size_t lfs3_memlen(const void *a, size_t size) {
const uint8_t *a_ = a; const uint8_t *a_ = a;
while (size > 0 && a_[size-1] == 0) { while (size > 0 && a_[size-1] == 0) {
size -= 1; size -= 1;
@@ -522,7 +522,7 @@ static inline size_t lfs_memlen(const void *a, size_t size) {
} }
// Xor n bytes from b into a // Xor n bytes from b into a
static inline void *lfs_memxor( static inline void *lfs3_memxor(
void *restrict a, const void *restrict b, size_t size) { void *restrict a, const void *restrict b, size_t size) {
uint8_t *a_ = a; uint8_t *a_ = a;
const uint8_t *b_ = b; const uint8_t *b_ = b;
@@ -535,10 +535,10 @@ static inline void *lfs_memxor(
// Find the length of a null-terminated string // Find the length of a null-terminated string
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_strlen strlen #define lfs3_strlen strlen
#else #else
static inline size_t lfs_strlen(const char *a) { static inline size_t lfs3_strlen(const char *a) {
const char *a_ = a; const char *a_ = a;
while (*a_) { while (*a_) {
a_++; a_++;
@@ -549,10 +549,10 @@ static inline size_t lfs_strlen(const char *a) {
#endif #endif
// Compare two null-terminated strings // Compare two null-terminated strings
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_strcmp strcmp #define lfs3_strcmp strcmp
#else #else
static inline int lfs_strcmp(const char *a, const char *b) { static inline int lfs3_strcmp(const char *a, const char *b) {
while (*a && *a == *b) { while (*a && *a == *b) {
a++; a++;
b++; b++;
@@ -563,10 +563,10 @@ static inline int lfs_strcmp(const char *a, const char *b) {
#endif #endif
// Copy a null-terminated string from src to dst // Copy a null-terminated string from src to dst
#if !defined(LFS_NO_STRINGH) #if !defined(LFS3_NO_STRINGH)
#define lfs_strcpy strcpy #define lfs3_strcpy strcpy
#else #else
static inline char *lfs_strcpy( static inline char *lfs3_strcpy(
char *restrict dst, const char *restrict src) { char *restrict dst, const char *restrict src) {
char *dst_ = dst; char *dst_ = dst;
while (*src) { while (*src) {
@@ -581,10 +581,10 @@ static inline char *lfs_strcpy(
#endif #endif
// Find first occurrence of c or NULL // Find first occurrence of c or NULL
#ifndef LFS_NO_STRINGH #ifndef LFS3_NO_STRINGH
#define lfs_strchr strchr #define lfs3_strchr strchr
#else #else
static inline char *lfs_strchr(const char *a, int c) { static inline char *lfs3_strchr(const char *a, int c) {
while (*a) { while (*a) {
if (*a == c) { if (*a == c) {
return (char*)a; return (char*)a;
@@ -598,7 +598,7 @@ static inline char *lfs_strchr(const char *a, int c) {
#endif #endif
// Find first occurrence of anything not c or NULL // Find first occurrence of anything not c or NULL
static inline char *lfs_strcchr(const char *a, int c) { static inline char *lfs3_strcchr(const char *a, int c) {
while (*a) { while (*a) {
if (*a != c) { if (*a != c) {
return (char*)a; return (char*)a;
@@ -611,10 +611,10 @@ static inline char *lfs_strcchr(const char *a, int c) {
} }
// Find length of a that does not contain any char in cs // Find length of a that does not contain any char in cs
#ifndef LFS_NO_STRINGH #ifndef LFS3_NO_STRINGH
#define lfs_strspn strspn #define lfs3_strspn strspn
#else #else
static inline size_t lfs_strspn(const char *a, const char *cs) { static inline size_t lfs3_strspn(const char *a, const char *cs) {
const char *a_ = a; const char *a_ = a;
while (*a_) { while (*a_) {
const char *cs_ = cs; const char *cs_ = cs;
@@ -633,10 +633,10 @@ static inline size_t lfs_strspn(const char *a, const char *cs) {
#endif #endif
// Find length of a that only contains chars in cs // Find length of a that only contains chars in cs
#ifndef LFS_NO_STRINGH #ifndef LFS3_NO_STRINGH
#define lfs_strcspn strcspn #define lfs3_strcspn strcspn
#else #else
static inline size_t lfs_strcspn(const char *a, const char *cs) { static inline size_t lfs3_strcspn(const char *a, const char *cs) {
const char *a_ = a; const char *a_ = a;
while (*a_) { while (*a_) {
const char *cs_ = cs; const char *cs_ = cs;
@@ -656,8 +656,8 @@ static inline size_t lfs_strcspn(const char *a, const char *cs) {
// Odd-parity and even-parity zeros in our crc32c ring // Odd-parity and even-parity zeros in our crc32c ring
#define LFS_CRC32C_ODDZERO 0xfca42daf #define LFS3_CRC32C_ODDZERO 0xfca42daf
#define LFS_CRC32C_EVENZERO 0x00000000 #define LFS3_CRC32C_EVENZERO 0x00000000
// Calculate crc32c incrementally // Calculate crc32c incrementally
// //
@@ -665,32 +665,32 @@ static inline size_t lfs_strcspn(const char *a, const char *cs) {
// init = 0xffffffff // init = 0xffffffff
// fini = 0xffffffff // fini = 0xffffffff
// //
uint32_t lfs_crc32c(uint32_t crc, const void *buffer, size_t size); uint32_t lfs3_crc32c(uint32_t crc, const void *buffer, size_t size);
// Multiply two crc32cs in the crc32c ring // Multiply two crc32cs in the crc32c ring
uint32_t lfs_crc32c_mul(uint32_t a, uint32_t b); uint32_t lfs3_crc32c_mul(uint32_t a, uint32_t b);
// Find the cube of a crc32c in the crc32c ring // Find the cube of a crc32c in the crc32c ring
static inline uint32_t lfs_crc32c_cube(uint32_t a) { static inline uint32_t lfs3_crc32c_cube(uint32_t a) {
return lfs_crc32c_mul(lfs_crc32c_mul(a, a), a); return lfs3_crc32c_mul(lfs3_crc32c_mul(a, a), a);
} }
// Allocate memory, only used if buffers are not provided to littlefs // Allocate memory, only used if buffers are not provided to littlefs
#ifndef LFS_NO_MALLOC #ifndef LFS3_NO_MALLOC
#define lfs_malloc malloc #define lfs3_malloc malloc
#else #else
static inline void *lfs_malloc(size_t size) { static inline void *lfs3_malloc(size_t size) {
(void)size; (void)size;
return NULL; return NULL;
} }
#endif #endif
// Deallocate memory, only used if buffers are not provided to littlefs // Deallocate memory, only used if buffers are not provided to littlefs
#ifndef LFS_NO_MALLOC #ifndef LFS3_NO_MALLOC
#define lfs_free free #define lfs3_free free
#else #else
static inline void lfs_free(void *p) { static inline void lfs3_free(void *p) {
(void)p; (void)p;
} }
#endif #endif
+25 -25
View File
@@ -9,7 +9,7 @@
#endif #endif
#include "runners/bench_runner.h" #include "runners/bench_runner.h"
#include "bd/lfs_emubd.h" #include "bd/lfs3_emubd.h"
#include <getopt.h> #include <getopt.h>
#include <sys/types.h> #include <sys/types.h>
@@ -439,9 +439,9 @@ FILE *bench_trace_file = NULL;
uint32_t bench_trace_cycles = 0; uint32_t bench_trace_cycles = 0;
uint64_t bench_trace_time = 0; uint64_t bench_trace_time = 0;
uint64_t bench_trace_open_time = 0; uint64_t bench_trace_open_time = 0;
lfs_emubd_sleep_t bench_read_sleep = 0.0; lfs3_emubd_sleep_t bench_read_sleep = 0.0;
lfs_emubd_sleep_t bench_prog_sleep = 0.0; lfs3_emubd_sleep_t bench_prog_sleep = 0.0;
lfs_emubd_sleep_t bench_erase_sleep = 0.0; lfs3_emubd_sleep_t bench_erase_sleep = 0.0;
// this determines both the backtrace buffer and the trace printf buffer, if // this determines both the backtrace buffer and the trace printf buffer, if
// trace ends up interleaved or truncated this may need to be increased // trace ends up interleaved or truncated this may need to be increased
@@ -607,17 +607,17 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size) {
typedef struct bench_record { typedef struct bench_record {
const char *m; const char *m;
uintmax_t n; uintmax_t n;
lfs_emubd_io_t last_readed; lfs3_emubd_io_t last_readed;
lfs_emubd_io_t last_proged; lfs3_emubd_io_t last_proged;
lfs_emubd_io_t last_erased; lfs3_emubd_io_t last_erased;
} bench_record_t; } bench_record_t;
static struct lfs_config *bench_cfg = NULL; static struct lfs3_config *bench_cfg = NULL;
static bench_record_t *bench_records; static bench_record_t *bench_records;
size_t bench_record_count; size_t bench_record_count;
size_t bench_record_capacity; size_t bench_record_capacity;
void bench_reset(struct lfs_config *cfg) { void bench_reset(struct lfs3_config *cfg) {
bench_cfg = cfg; bench_cfg = cfg;
bench_record_count = 0; bench_record_count = 0;
} }
@@ -625,11 +625,11 @@ void bench_reset(struct lfs_config *cfg) {
void bench_start(const char *m, uintmax_t n) { void bench_start(const char *m, uintmax_t n) {
// measure current read/prog/erase // measure current read/prog/erase
assert(bench_cfg); assert(bench_cfg);
lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg); lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg);
assert(readed >= 0); assert(readed >= 0);
lfs_emubd_sio_t proged = lfs_emubd_proged(bench_cfg); lfs3_emubd_sio_t proged = lfs3_emubd_proged(bench_cfg);
assert(proged >= 0); assert(proged >= 0);
lfs_emubd_sio_t erased = lfs_emubd_erased(bench_cfg); lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg);
assert(erased >= 0); assert(erased >= 0);
// allocate a new record // allocate a new record
@@ -648,11 +648,11 @@ void bench_start(const char *m, uintmax_t n) {
void bench_stop(const char *m) { void bench_stop(const char *m) {
// measure current read/prog/erase // measure current read/prog/erase
assert(bench_cfg); assert(bench_cfg);
lfs_emubd_sio_t readed = lfs_emubd_readed(bench_cfg); lfs3_emubd_sio_t readed = lfs3_emubd_readed(bench_cfg);
assert(readed >= 0); assert(readed >= 0);
lfs_emubd_sio_t proged = lfs_emubd_proged(bench_cfg); lfs3_emubd_sio_t proged = lfs3_emubd_proged(bench_cfg);
assert(proged >= 0); assert(proged >= 0);
lfs_emubd_sio_t erased = lfs_emubd_erased(bench_cfg); lfs3_emubd_sio_t erased = lfs3_emubd_erased(bench_cfg);
assert(erased >= 0); assert(erased >= 0);
// find our record // find our record
@@ -1335,18 +1335,18 @@ void perm_run(
} }
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
BENCH_CFG BENCH_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = bench_disk_path, .disk_path = bench_disk_path,
.read_sleep = bench_read_sleep, .read_sleep = bench_read_sleep,
.prog_sleep = bench_prog_sleep, .prog_sleep = bench_prog_sleep,
@@ -1354,7 +1354,7 @@ void perm_run(
BENCH_BDCFG BENCH_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, bench_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, bench_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -1373,7 +1373,7 @@ void perm_run(
printf("\n"); printf("\n");
// cleanup // cleanup
err = lfs_emubd_destroy(&cfg); err = lfs3_emubd_destroy(&cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1920,7 +1920,7 @@ getopt_done: ;
if (d >= define_count) { if (d >= define_count) {
// align to power of two to avoid any superlinear growth // align to power of two to avoid any superlinear growth
size_t ncount = 1 << lfs_nlog2(d+1); size_t ncount = 1 << lfs3_nlog2(d+1);
defines = realloc(defines, defines = realloc(defines,
ncount*sizeof(bench_define_t)); ncount*sizeof(bench_define_t));
memset(defines+define_count, 0, memset(defines+define_count, 0,
+13 -13
View File
@@ -8,16 +8,16 @@
#define BENCH_RUNNER_H #define BENCH_RUNNER_H
// override LFS_TRACE // override LFS3_TRACE
void bench_trace(const char *fmt, ...); void bench_trace(const char *fmt, ...);
#define LFS_TRACE_(fmt, ...) \ #define LFS3_TRACE_(fmt, ...) \
bench_trace("%s:%d:trace: " fmt "%s\n", \ bench_trace("%s:%d:trace: " fmt "%s\n", \
__FILE__, \ __FILE__, \
__LINE__, \ __LINE__, \
__VA_ARGS__) __VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") #define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") #define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
// BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes // BENCH_START/BENCH_STOP macros measure readed/proged/erased bytes
// through emubd // through emubd
@@ -36,7 +36,7 @@ void bench_fresult(const char *m, uintmax_t n, double result);
// note these are indirectly included in any generated files // note these are indirectly included in any generated files
#include "bd/lfs_emubd.h" #include "bd/lfs3_emubd.h"
#include <stdio.h> #include <stdio.h>
// give source a chance to define feature macros // give source a chance to define feature macros
@@ -45,7 +45,7 @@ void bench_fresult(const char *m, uintmax_t n, double result);
// generated bench configurations // generated bench configurations
struct lfs_config; struct lfs3_config;
enum bench_flags { enum bench_flags {
BENCH_INTERNAL = 0x1, BENCH_INTERNAL = 0x1,
@@ -69,7 +69,7 @@ struct bench_case {
size_t permutations; size_t permutations;
bool (*if_)(void); bool (*if_)(void);
void (*run)(struct lfs_config *cfg); void (*run)(struct lfs3_config *cfg);
}; };
struct bench_suite { struct bench_suite {
@@ -110,21 +110,21 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
BENCH_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \ BENCH_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
BENCH_DEFINE(DISK_SIZE, 1024*1024 ) \ BENCH_DEFINE(DISK_SIZE, 1024*1024 ) \
BENCH_DEFINE(BLOCK_RECYCLES, -1 ) \ BENCH_DEFINE(BLOCK_RECYCLES, -1 ) \
BENCH_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \ BENCH_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
BENCH_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \ BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \ BENCH_DEFINE(FILE_CACHE_SIZE, 16 ) \
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \ BENCH_DEFINE(LOOKAHEAD_SIZE, 16 ) \
BENCH_DEFINE(GC_FLAGS, 0 ) \ BENCH_DEFINE(GC_FLAGS, 0 ) \
BENCH_DEFINE(GC_STEPS, 0 ) \ BENCH_DEFINE(GC_STEPS, 0 ) \
BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \ BENCH_DEFINE(GC_COMPACT_THRESH, 0 ) \
BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \ BENCH_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
BENCH_DEFINE(FRAGMENT_SIZE, LFS_MIN(BLOCK_SIZE/8, 512) ) \ BENCH_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \ BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
BENCH_DEFINE(FRAGMENT_THRESH, -1 ) \ BENCH_DEFINE(FRAGMENT_THRESH, -1 ) \
BENCH_DEFINE(ERASE_VALUE, 0xff ) \ BENCH_DEFINE(ERASE_VALUE, 0xff ) \
BENCH_DEFINE(ERASE_CYCLES, 0 ) \ BENCH_DEFINE(ERASE_CYCLES, 0 ) \
BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \ BENCH_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \ BENCH_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
BENCH_DEFINE(EMUBD_SEED, 0 ) BENCH_DEFINE(EMUBD_SEED, 0 )
// declare defines as global intmax_ts // declare defines as global intmax_ts
@@ -152,7 +152,7 @@ void bench_permutation(size_t i, uint32_t *buffer, size_t size);
.crystal_thresh = CRYSTAL_THRESH, \ .crystal_thresh = CRYSTAL_THRESH, \
.fragment_thresh = FRAGMENT_THRESH, .fragment_thresh = FRAGMENT_THRESH,
#ifdef LFS_GC #ifdef LFS3_GC
#define BENCH_GC_CFG \ #define BENCH_GC_CFG \
.gc_flags = GC_FLAGS, \ .gc_flags = GC_FLAGS, \
.gc_steps = GC_STEPS, .gc_steps = GC_STEPS,
+76 -76
View File
@@ -9,7 +9,7 @@
#endif #endif
#include "runners/test_runner.h" #include "runners/test_runner.h"
#include "bd/lfs_emubd.h" #include "bd/lfs3_emubd.h"
#include <getopt.h> #include <getopt.h>
#include <sys/types.h> #include <sys/types.h>
@@ -117,7 +117,7 @@ typedef struct test_powerloss {
const struct test_powerloss *powerloss, const struct test_powerloss *powerloss,
const struct test_suite *suite, const struct test_suite *suite,
const struct test_case *case_); const struct test_case *case_);
const lfs_emubd_powercycles_t *cycles; const lfs3_emubd_powercycles_t *cycles;
size_t cycle_count; size_t cycle_count;
} test_powerloss_t; } test_powerloss_t;
@@ -450,9 +450,9 @@ FILE *test_trace_file = NULL;
uint32_t test_trace_cycles = 0; uint32_t test_trace_cycles = 0;
uint64_t test_trace_time = 0; uint64_t test_trace_time = 0;
uint64_t test_trace_open_time = 0; uint64_t test_trace_open_time = 0;
lfs_emubd_sleep_t test_read_sleep = 0.0; lfs3_emubd_sleep_t test_read_sleep = 0.0;
lfs_emubd_sleep_t test_prog_sleep = 0.0; lfs3_emubd_sleep_t test_prog_sleep = 0.0;
lfs_emubd_sleep_t test_erase_sleep = 0.0; lfs3_emubd_sleep_t test_erase_sleep = 0.0;
volatile size_t TEST_PLS = 0; volatile size_t TEST_PLS = 0;
@@ -623,7 +623,7 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size) {
static void perm_printid( static void perm_printid(
const struct test_suite *suite, const struct test_suite *suite,
const struct test_case *case_, const struct test_case *case_,
const lfs_emubd_powercycles_t *cycles, const lfs3_emubd_powercycles_t *cycles,
size_t cycle_count) { size_t cycle_count) {
(void)suite; (void)suite;
// case[:permutation[:powercycles]] // case[:permutation[:powercycles]]
@@ -1299,18 +1299,18 @@ static void run_powerloss_none(
(void)powerloss; (void)powerloss;
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
TEST_CFG TEST_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path, .disk_path = test_disk_path,
.read_sleep = test_read_sleep, .read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep, .prog_sleep = test_prog_sleep,
@@ -1318,7 +1318,7 @@ static void run_powerloss_none(
TEST_BDCFG TEST_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -1339,7 +1339,7 @@ static void run_powerloss_none(
printf("\n"); printf("\n");
// cleanup // cleanup
err = lfs_emubd_destroy(&cfg); err = lfs3_emubd_destroy(&cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1359,19 +1359,19 @@ static void run_powerloss_linear(
TEST_PLS = 0; TEST_PLS = 0;
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
jmp_buf powerloss_jmp; jmp_buf powerloss_jmp;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
TEST_CFG TEST_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path, .disk_path = test_disk_path,
.read_sleep = test_read_sleep, .read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep, .prog_sleep = test_prog_sleep,
@@ -1384,7 +1384,7 @@ static void run_powerloss_linear(
TEST_BDCFG TEST_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -1411,7 +1411,7 @@ static void run_powerloss_linear(
// increment pls // increment pls
TEST_PLS += 1; TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count) lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? TEST_PLS+1 ? TEST_PLS+1
: 0); : 0);
} }
@@ -1421,7 +1421,7 @@ static void run_powerloss_linear(
printf("\n"); printf("\n");
// cleanup // cleanup
err = lfs_emubd_destroy(&cfg); err = lfs3_emubd_destroy(&cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1436,19 +1436,19 @@ static void run_powerloss_log(
TEST_PLS = 0; TEST_PLS = 0;
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
jmp_buf powerloss_jmp; jmp_buf powerloss_jmp;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
TEST_CFG TEST_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path, .disk_path = test_disk_path,
.read_sleep = test_read_sleep, .read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep, .prog_sleep = test_prog_sleep,
@@ -1461,7 +1461,7 @@ static void run_powerloss_log(
TEST_BDCFG TEST_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -1488,7 +1488,7 @@ static void run_powerloss_log(
// increment pls // increment pls
TEST_PLS += 1; TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count) lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? 1 << TEST_PLS ? 1 << TEST_PLS
: 0); : 0);
} }
@@ -1498,7 +1498,7 @@ static void run_powerloss_log(
printf("\n"); printf("\n");
// cleanup // cleanup
err = lfs_emubd_destroy(&cfg); err = lfs3_emubd_destroy(&cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1513,19 +1513,19 @@ static void run_powerloss_cycles(
TEST_PLS = 0; TEST_PLS = 0;
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
jmp_buf powerloss_jmp; jmp_buf powerloss_jmp;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
TEST_CFG TEST_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path, .disk_path = test_disk_path,
.read_sleep = test_read_sleep, .read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep, .prog_sleep = test_prog_sleep,
@@ -1538,7 +1538,7 @@ static void run_powerloss_cycles(
TEST_BDCFG TEST_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -1564,7 +1564,7 @@ static void run_powerloss_cycles(
// increment pls // increment pls
TEST_PLS += 1; TEST_PLS += 1;
lfs_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count) lfs3_emubd_setpowercycles(&cfg, (TEST_PLS < powerloss->cycle_count)
? powerloss->cycles[TEST_PLS] ? powerloss->cycles[TEST_PLS]
: 0); : 0);
} }
@@ -1574,7 +1574,7 @@ static void run_powerloss_cycles(
printf("\n"); printf("\n");
// cleanup // cleanup
err = lfs_emubd_destroy(&cfg); err = lfs3_emubd_destroy(&cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1582,15 +1582,15 @@ static void run_powerloss_cycles(
} }
struct powerloss_exhaustive_state { struct powerloss_exhaustive_state {
struct lfs_config *cfg; struct lfs3_config *cfg;
lfs_emubd_t *branches; lfs3_emubd_t *branches;
size_t branch_count; size_t branch_count;
size_t branch_capacity; size_t branch_capacity;
}; };
struct powerloss_exhaustive_cycles { struct powerloss_exhaustive_cycles {
lfs_emubd_powercycles_t *cycles; lfs3_emubd_powercycles_t *cycles;
size_t cycle_count; size_t cycle_count;
size_t cycle_capacity; size_t cycle_capacity;
}; };
@@ -1598,9 +1598,9 @@ struct powerloss_exhaustive_cycles {
static void powerloss_exhaustive_branch(void *c) { static void powerloss_exhaustive_branch(void *c) {
struct powerloss_exhaustive_state *state = c; struct powerloss_exhaustive_state *state = c;
// append to branches // append to branches
lfs_emubd_t *branch = mappend( lfs3_emubd_t *branch = mappend(
(void**)&state->branches, (void**)&state->branches,
sizeof(lfs_emubd_t), sizeof(lfs3_emubd_t),
&state->branch_count, &state->branch_count,
&state->branch_capacity); &state->branch_capacity);
if (!branch) { if (!branch) {
@@ -1609,22 +1609,22 @@ static void powerloss_exhaustive_branch(void *c) {
} }
// create copy-on-write copy // create copy-on-write copy
int err = lfs_emubd_cpy(state->cfg, branch); int err = lfs3_emubd_cpy(state->cfg, branch);
if (err) { if (err) {
fprintf(stderr, "error: exhaustive: could not create bd copy\n"); fprintf(stderr, "error: exhaustive: could not create bd copy\n");
exit(-1); exit(-1);
} }
// also trigger on next power cycle // also trigger on next power cycle
lfs_emubd_setpowercycles(state->cfg, 1); lfs3_emubd_setpowercycles(state->cfg, 1);
} }
static void run_powerloss_exhaustive_layer( static void run_powerloss_exhaustive_layer(
struct powerloss_exhaustive_cycles *cycles, struct powerloss_exhaustive_cycles *cycles,
const struct test_suite *suite, const struct test_suite *suite,
const struct test_case *case_, const struct test_case *case_,
struct lfs_config *cfg, struct lfs3_config *cfg,
struct lfs_emubd_config *bdcfg, struct lfs3_emubd_config *bdcfg,
size_t depth, size_t depth,
size_t pls) { size_t pls) {
struct powerloss_exhaustive_state state = { struct powerloss_exhaustive_state state = {
@@ -1639,14 +1639,14 @@ static void run_powerloss_exhaustive_layer(
// run through the test without additional powerlosses, collecting possible // run through the test without additional powerlosses, collecting possible
// branches as we do so // branches as we do so
lfs_emubd_setpowercycles(state.cfg, (depth > 0) ? 1 : 0); lfs3_emubd_setpowercycles(state.cfg, (depth > 0) ? 1 : 0);
bdcfg->powerloss_data = &state; bdcfg->powerloss_data = &state;
// run the tests // run the tests
case_->run(cfg); case_->run(cfg);
// aggressively clean up memory here to try to keep our memory usage low // aggressively clean up memory here to try to keep our memory usage low
int err = lfs_emubd_destroy(cfg); int err = lfs3_emubd_destroy(cfg);
if (err) { if (err) {
fprintf(stderr, "error: could not destroy block device: %d\n", err); fprintf(stderr, "error: could not destroy block device: %d\n", err);
exit(-1); exit(-1);
@@ -1655,9 +1655,9 @@ static void run_powerloss_exhaustive_layer(
// recurse into each branch // recurse into each branch
for (size_t i = 0; i < state.branch_count; i++) { for (size_t i = 0; i < state.branch_count; i++) {
// first push and print the branch // first push and print the branch
lfs_emubd_powercycles_t *cycle = mappend( lfs3_emubd_powercycles_t *cycle = mappend(
(void**)&cycles->cycles, (void**)&cycles->cycles,
sizeof(lfs_emubd_powercycles_t), sizeof(lfs3_emubd_powercycles_t),
&cycles->cycle_count, &cycles->cycle_count,
&cycles->cycle_capacity); &cycles->cycle_capacity);
if (!cycle) { if (!cycle) {
@@ -1689,18 +1689,18 @@ static void run_powerloss_exhaustive(
const struct test_suite *suite, const struct test_suite *suite,
const struct test_case *case_) { const struct test_case *case_) {
// create block device and configuration // create block device and configuration
lfs_emubd_t bd; lfs3_emubd_t bd;
struct lfs_config cfg = { struct lfs3_config cfg = {
.context = &bd, .context = &bd,
.read = lfs_emubd_read, .read = lfs3_emubd_read,
.prog = lfs_emubd_prog, .prog = lfs3_emubd_prog,
.erase = lfs_emubd_erase, .erase = lfs3_emubd_erase,
.sync = lfs_emubd_sync, .sync = lfs3_emubd_sync,
TEST_CFG TEST_CFG
}; };
struct lfs_emubd_config bdcfg = { struct lfs3_emubd_config bdcfg = {
.disk_path = test_disk_path, .disk_path = test_disk_path,
.read_sleep = test_read_sleep, .read_sleep = test_read_sleep,
.prog_sleep = test_prog_sleep, .prog_sleep = test_prog_sleep,
@@ -1710,7 +1710,7 @@ static void run_powerloss_exhaustive(
TEST_BDCFG TEST_BDCFG
}; };
int err = lfs_emubd_createcfg(&cfg, test_disk_path, &bdcfg); int err = lfs3_emubd_createcfg(&cfg, test_disk_path, &bdcfg);
if (err) { if (err) {
fprintf(stderr, "error: could not create block device: %d\n", err); fprintf(stderr, "error: could not create block device: %d\n", err);
exit(-1); exit(-1);
@@ -2234,16 +2234,16 @@ int main(int argc, char **argv) {
// comma-separated permutation // comma-separated permutation
if (*optarg == '{') { if (*optarg == '{') {
lfs_emubd_powercycles_t *cycles = NULL; lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0; size_t cycle_count = 0;
size_t cycle_capacity = 0; size_t cycle_capacity = 0;
char *s = optarg + 1; char *s = optarg + 1;
while (true) { while (true) {
parsed = NULL; parsed = NULL;
*(lfs_emubd_powercycles_t*)mappend( *(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles, (void**)&cycles,
sizeof(lfs_emubd_powercycles_t), sizeof(lfs3_emubd_powercycles_t),
&cycle_count, &cycle_count,
&cycle_capacity) &cycle_capacity)
= strtoumax(s, &parsed, 0); = strtoumax(s, &parsed, 0);
@@ -2295,7 +2295,7 @@ int main(int argc, char **argv) {
// otherwise explicit power cycles // otherwise explicit power cycles
} else { } else {
lfs_emubd_powercycles_t *cycles = NULL; lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0; size_t cycle_count = 0;
size_t cycle_capacity = 0; size_t cycle_capacity = 0;
@@ -2307,9 +2307,9 @@ int main(int argc, char **argv) {
break; break;
} }
*(lfs_emubd_powercycles_t*)mappend( *(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles, (void**)&cycles,
sizeof(lfs_emubd_powercycles_t), sizeof(lfs3_emubd_powercycles_t),
&cycle_count, &cycle_count,
&cycle_capacity) = x; &cycle_capacity) = x;
s = parsed; s = parsed;
@@ -2538,7 +2538,7 @@ getopt_done:;
if (d >= define_count) { if (d >= define_count) {
// align to power of two to avoid any superlinear growth // align to power of two to avoid any superlinear growth
size_t ncount = 1 << lfs_nlog2(d+1); size_t ncount = 1 << lfs3_nlog2(d+1);
defines = realloc(defines, defines = realloc(defines,
ncount*sizeof(test_define_t)); ncount*sizeof(test_define_t));
memset(defines+define_count, 0, memset(defines+define_count, 0,
@@ -2588,14 +2588,14 @@ getopt_done:;
// otherwise explicit power cycles // otherwise explicit power cycles
} else if (cycles_) { } else if (cycles_) {
// parse power cycles // parse power cycles
lfs_emubd_powercycles_t *cycles = NULL; lfs3_emubd_powercycles_t *cycles = NULL;
size_t cycle_count = 0; size_t cycle_count = 0;
size_t cycle_capacity = 0; size_t cycle_capacity = 0;
while (*cycles_ != '\0') { while (*cycles_ != '\0') {
char *parsed = NULL; char *parsed = NULL;
*(lfs_emubd_powercycles_t*)mappend( *(lfs3_emubd_powercycles_t*)mappend(
(void**)&cycles, (void**)&cycles,
sizeof(lfs_emubd_powercycles_t), sizeof(lfs3_emubd_powercycles_t),
&cycle_count, &cycle_count,
&cycle_capacity) &cycle_capacity)
= leb16_parse(cycles_, &parsed); = leb16_parse(cycles_, &parsed);
+13 -13
View File
@@ -8,20 +8,20 @@
#define TEST_RUNNER_H #define TEST_RUNNER_H
// override LFS_TRACE // override LFS3_TRACE
void test_trace(const char *fmt, ...); void test_trace(const char *fmt, ...);
#define LFS_TRACE_(fmt, ...) \ #define LFS3_TRACE_(fmt, ...) \
test_trace("%s:%d:trace: " fmt "%s\n", \ test_trace("%s:%d:trace: " fmt "%s\n", \
__FILE__, \ __FILE__, \
__LINE__, \ __LINE__, \
__VA_ARGS__) __VA_ARGS__)
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") #define LFS3_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
#define LFS_EMUBD_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") #define LFS3_EMUBD_TRACE(...) LFS3_TRACE_(__VA_ARGS__, "")
// note these are indirectly included in any generated files // note these are indirectly included in any generated files
#include "bd/lfs_emubd.h" #include "bd/lfs3_emubd.h"
#include <stdio.h> #include <stdio.h>
// give source a chance to define feature macros // give source a chance to define feature macros
@@ -30,7 +30,7 @@ void test_trace(const char *fmt, ...);
// generated test configurations // generated test configurations
struct lfs_config; struct lfs3_config;
enum test_flags { enum test_flags {
TEST_INTERNAL = 0x1, TEST_INTERNAL = 0x1,
@@ -56,7 +56,7 @@ struct test_case {
size_t permutations; size_t permutations;
bool (*if_)(void); bool (*if_)(void);
void (*run)(struct lfs_config *cfg); void (*run)(struct lfs3_config *cfg);
}; };
struct test_suite { struct test_suite {
@@ -101,21 +101,21 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
TEST_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \ TEST_DEFINE(BLOCK_COUNT, DISK_SIZE/BLOCK_SIZE ) \
TEST_DEFINE(DISK_SIZE, 1024*1024 ) \ TEST_DEFINE(DISK_SIZE, 1024*1024 ) \
TEST_DEFINE(BLOCK_RECYCLES, -1 ) \ TEST_DEFINE(BLOCK_RECYCLES, -1 ) \
TEST_DEFINE(RCACHE_SIZE, LFS_MAX(16, READ_SIZE) ) \ TEST_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) ) \
TEST_DEFINE(PCACHE_SIZE, LFS_MAX(16, PROG_SIZE) ) \ TEST_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) ) \
TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \ TEST_DEFINE(FILE_CACHE_SIZE, 16 ) \
TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \ TEST_DEFINE(LOOKAHEAD_SIZE, 16 ) \
TEST_DEFINE(GC_FLAGS, 0 ) \ TEST_DEFINE(GC_FLAGS, 0 ) \
TEST_DEFINE(GC_STEPS, 0 ) \ TEST_DEFINE(GC_STEPS, 0 ) \
TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \ TEST_DEFINE(GC_COMPACT_THRESH, 0 ) \
TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \ TEST_DEFINE(INLINE_SIZE, BLOCK_SIZE/4 ) \
TEST_DEFINE(FRAGMENT_SIZE, LFS_MIN(BLOCK_SIZE/8, 512) ) \ TEST_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/8, 512) ) \
TEST_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \ TEST_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/8 ) \
TEST_DEFINE(FRAGMENT_THRESH, -1 ) \ TEST_DEFINE(FRAGMENT_THRESH, -1 ) \
TEST_DEFINE(ERASE_VALUE, 0xff ) \ TEST_DEFINE(ERASE_VALUE, 0xff ) \
TEST_DEFINE(ERASE_CYCLES, 0 ) \ TEST_DEFINE(ERASE_CYCLES, 0 ) \
TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS_EMUBD_BADBLOCK_PROGERROR ) \ TEST_DEFINE(BADBLOCK_BEHAVIOR, LFS3_EMUBD_BADBLOCK_PROGERROR ) \
TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS_EMUBD_POWERLOSS_ATOMIC ) \ TEST_DEFINE(POWERLOSS_BEHAVIOR, LFS3_EMUBD_POWERLOSS_ATOMIC ) \
TEST_DEFINE(EMUBD_SEED, 0 ) TEST_DEFINE(EMUBD_SEED, 0 )
// declare defines as global intmax_ts // declare defines as global intmax_ts
@@ -143,7 +143,7 @@ void test_permutation(size_t i, uint32_t *buffer, size_t size);
.crystal_thresh = CRYSTAL_THRESH, \ .crystal_thresh = CRYSTAL_THRESH, \
.fragment_thresh = FRAGMENT_THRESH, .fragment_thresh = FRAGMENT_THRESH,
#ifdef LFS_GC #ifdef LFS3_GC
#define TEST_GC_CFG \ #define TEST_GC_CFG \
.gc_flags = GC_FLAGS, \ .gc_flags = GC_FLAGS, \
.gc_steps = GC_STEPS, .gc_steps = GC_STEPS,
+2 -2
View File
@@ -432,7 +432,7 @@ def compile(bench_paths, **args):
# create case run function # create case run function
f.writeln('void __bench__%s__run(' f.writeln('void __bench__%s__run('
'__attribute__((unused)) ' '__attribute__((unused)) '
'struct lfs_config *CFG) {' % ( 'struct lfs3_config *CFG) {' % (
case.name)) case.name))
f.writeln(4*' '+'// bench case %s' % case.name) f.writeln(4*' '+'// bench case %s' % case.name)
if case.code_lineno is not None: if case.code_lineno is not None:
@@ -491,7 +491,7 @@ def compile(bench_paths, **args):
'void);' % ( 'void);' % (
case.name)) case.name))
f.writeln('extern void __bench__%s__run(' f.writeln('extern void __bench__%s__run('
'struct lfs_config *CFG);' % ( 'struct lfs3_config *CFG);' % (
case.name)) case.name))
f.writeln() f.writeln()
+5 -5
View File
@@ -2769,7 +2769,7 @@ class Gstate:
# high-level littlefs representation # high-level littlefs representation
class Lfs: class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *, def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False): corrupt=False):
self.bd = bd self.bd = bd
@@ -3018,7 +3018,7 @@ class Lfs:
# empty path? # empty path?
if path_ == b'': if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__ = [] path__ = []
for p in path_.split(b'/'): for p in path_.split(b'/'):
@@ -3039,7 +3039,7 @@ class Lfs:
else: else:
path__.append(p) path__.append(p)
if dotdots: if dotdots:
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse() path__.reverse()
path_ = path__ path_ = path__
@@ -3570,7 +3570,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name) super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did # we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir) if (isinstance(self, Lfs3.Dir)
and not self.grmed and not self.grmed
and self.did is not None): and self.did is not None):
self.recursable = True self.recursable = True
@@ -4507,7 +4507,7 @@ def main_(ring, disk, mroots=None, *,
# fetch the filesystem # fetch the filesystem
bd = Bd(f, block_size, block_count) bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk, lfs = Lfs3.fetch(bd, mroots, trunk,
# don't bother to check things if we're not reporting errors # don't bother to check things if we're not reporting errors
no_ck=not args.get('error_on_corrupt')) no_ck=not args.get('error_on_corrupt'))
corrupted = not bool(lfs) corrupted = not bool(lfs)
+5 -5
View File
@@ -2799,7 +2799,7 @@ class Gstate:
# high-level littlefs representation # high-level littlefs representation
class Lfs: class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *, def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False): corrupt=False):
self.bd = bd self.bd = bd
@@ -3048,7 +3048,7 @@ class Lfs:
# empty path? # empty path?
if path_ == b'': if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__ = [] path__ = []
for p in path_.split(b'/'): for p in path_.split(b'/'):
@@ -3069,7 +3069,7 @@ class Lfs:
else: else:
path__.append(p) path__.append(p)
if dotdots: if dotdots:
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse() path__.reverse()
path_ = path__ path_ = path__
@@ -3600,7 +3600,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name) super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did # we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir) if (isinstance(self, Lfs3.Dir)
and not self.grmed and not self.grmed
and self.did is not None): and self.did is not None):
self.recursable = True self.recursable = True
@@ -4227,7 +4227,7 @@ def main(disk, output, mroots=None, *,
# fetch the filesystem # fetch the filesystem
bd = Bd(f, block_size, block_count) bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk) lfs = Lfs3.fetch(bd, mroots, trunk)
corrupted = not bool(lfs) corrupted = not bool(lfs)
# if we can't figure out the block_count, guess # if we can't figure out the block_count, guess
+4 -4
View File
@@ -35,14 +35,14 @@ def main(errs, *,
# list all known error codes # list all known error codes
if list_: if list_:
for n, e, h in ERRS: for n, e, h in ERRS:
lines.append(('LFS_ERR_'+n, str(e), h)) lines.append(('LFS3_ERR_'+n, str(e), h))
# find these errors # find these errors
else: else:
def find_err(err): def find_err(err):
# find by LFS_ERR_+name # find by LFS3_ERR_+name
for n, e, h in ERRS: for n, e, h in ERRS:
if 'LFS_ERR_'+n == err.upper(): if 'LFS3_ERR_'+n == err.upper():
return n, e, h return n, e, h
# find by ERR_+name # find by ERR_+name
for n, e, h in ERRS: for n, e, h in ERRS:
@@ -73,7 +73,7 @@ def main(errs, *,
for err in errs: for err in errs:
try: try:
n, e, h = find_err(err) n, e, h = find_err(err)
lines.append(('LFS_ERR_'+n, str(e), h)) lines.append(('LFS3_ERR_'+n, str(e), h))
except KeyError: except KeyError:
lines.append(('?', err, 'Unknown err code')) lines.append(('?', err, 'Unknown err code'))
+22 -22
View File
@@ -77,8 +77,8 @@ FLAGS = [
('M', 'MODE', 1, "Mount's access mode" ), ('M', 'MODE', 1, "Mount's access mode" ),
('^', 'RDWR', 0, "Mount the filesystem as read and write" ), ('^', 'RDWR', 0, "Mount the filesystem as read and write" ),
('^', 'RDONLY', 1, "Mount the filesystem as read only" ), ('^', 'RDONLY', 1, "Mount the filesystem as read only" ),
('M', 'FLUSH', 0x00000040, "Open all files with LFS_O_FLUSH" ), ('M', 'FLUSH', 0x00000040, "Open all files with LFS3_O_FLUSH" ),
('M', 'SYNC', 0x00000080, "Open all files with LFS_O_SYNC" ), ('M', 'SYNC', 0x00000080, "Open all files with LFS3_O_SYNC" ),
('M', 'REVDBG', 0x00000010, "Add debug info to revision counts" ), ('M', 'REVDBG', 0x00000010, "Add debug info to revision counts" ),
('M', 'REVNOISE', 0x00000020, "Add noise to revision counts" ), ('M', 'REVNOISE', 0x00000020, "Add noise to revision counts" ),
('M', 'CKPROGS', 0x00080000, "Check progs by reading back progged data" ), ('M', 'CKPROGS', 0x00080000, "Check progs by reading back progged data" ),
@@ -105,16 +105,16 @@ FLAGS = [
# Filesystem info flags # Filesystem info flags
('I', 'RDONLY', 0x00000001, "Mounted read only" ), ('I', 'RDONLY', 0x00000001, "Mounted read only" ),
('I', 'FLUSH', 0x00000040, "Mounted with LFS_M_FLUSH" ), ('I', 'FLUSH', 0x00000040, "Mounted with LFS3_M_FLUSH" ),
('I', 'SYNC', 0x00000080, "Mounted with LFS_M_SYNC" ), ('I', 'SYNC', 0x00000080, "Mounted with LFS3_M_SYNC" ),
('I', 'REVDBG', 0x00000010, "Mounted with LFS_M_REVDBG" ), ('I', 'REVDBG', 0x00000010, "Mounted with LFS3_M_REVDBG" ),
('I', 'REVNOISE', 0x00000020, "Mounted with LFS_M_REVNOISE" ), ('I', 'REVNOISE', 0x00000020, "Mounted with LFS3_M_REVNOISE" ),
('I', 'CKPROGS', 0x00080000, "Mounted with LFS_M_CKPROGS" ), ('I', 'CKPROGS', 0x00080000, "Mounted with LFS3_M_CKPROGS" ),
('I', 'CKFETCHES', 0x00100000, "Mounted with LFS_M_CKFETCHES" ), ('I', 'CKFETCHES', 0x00100000, "Mounted with LFS3_M_CKFETCHES" ),
('I', 'CKMETAPARITY', ('I', 'CKMETAPARITY',
0x00200000, "Mounted with LFS_M_CKMETAPARITY" ), 0x00200000, "Mounted with LFS3_M_CKMETAPARITY" ),
('I', 'CKDATACKSUMREADS', ('I', 'CKDATACKSUMREADS',
0x00800000, "Mounted with LFS_M_CKDATACKSUMREADS" ), 0x00800000, "Mounted with LFS3_M_CKDATACKSUMREADS" ),
('I', 'MKCONSISTENT', ('I', 'MKCONSISTENT',
0x00000100, "Filesystem needs mkconsistent to write" ), 0x00000100, "Filesystem needs mkconsistent to write" ),
@@ -233,10 +233,10 @@ def main(flags, *,
# accept prefix prefix # accept prefix prefix
if f.upper() in prefixes: if f.upper() in prefixes:
prefix.update(prefixes[f.upper()]) prefix.update(prefixes[f.upper()])
# accept LFS_+prefix prefix # accept LFS3_+prefix prefix
elif (f.upper().startswith('LFS_') elif (f.upper().startswith('LFS3_')
and f.upper()[len('LFS_'):] in prefixes): and f.upper()[len('LFS3_'):] in prefixes):
prefix.update(prefixes[f.upper()[len('LFS_'):]]) prefix.update(prefixes[f.upper()[len('LFS3_'):]])
else: else:
flags_.append(f) flags_.append(f)
@@ -261,30 +261,30 @@ def main(flags, *,
for p, t, n, f, h in flags__: for p, t, n, f, h in flags__:
if not all_ and (t is not None or p[0].islower()): if not all_ and (t is not None or p[0].islower()):
continue continue
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
# find flags by name or value # find flags by name or value
else: else:
for f_ in flags_: for f_ in flags_:
found = False found = False
# find by LFS_+prefix+_+name # find by LFS3_+prefix+_+name
for p, t, n, f, h in flags__: for p, t, n, f, h in flags__:
if 'LFS_%s_%s' % (p, n) == f_.upper(): if 'LFS3_%s_%s' % (p, n) == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True found = True
if found: if found:
continue continue
# find by prefix+_+name # find by prefix+_+name
for p, t, n, f, h in flags__: for p, t, n, f, h in flags__:
if '%s_%s' % (p, n) == f_.upper(): if '%s_%s' % (p, n) == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True found = True
if found: if found:
continue continue
# find by name # find by name
for p, t, n, f, h in flags__: for p, t, n, f, h in flags__:
if n == f_.upper(): if n == f_.upper():
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
found = True found = True
if found: if found:
continue continue
@@ -298,11 +298,11 @@ def main(flags, *,
continue continue
# matches flag? # matches flag?
if t is None and (f__ & f) == f: if t is None and (f__ & f) == f:
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
f___ &= ~f f___ &= ~f
# matches type? # matches type?
elif t is not None and (f__ & t) == f: elif t is not None and (f__ & t) == f:
lines.append(('LFS_%s_%s' % (p, n), '0x%08x' % f, h)) lines.append(('LFS3_%s_%s' % (p, n), '0x%08x' % f, h))
f___ &= ~t f___ &= ~t
if f___: if f___:
lines.append(('?', '0x%08x' % f___, 'Unknown flags')) lines.append(('?', '0x%08x' % f___, 'Unknown flags'))
+8 -8
View File
@@ -2726,7 +2726,7 @@ class Gstate:
# high-level littlefs representation # high-level littlefs representation
class Lfs: class Lfs3:
def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *, def __init__(self, bd, mtree, config=None, gstate=None, cksum=None, *,
corrupt=False): corrupt=False):
self.bd = bd self.bd = bd
@@ -2975,7 +2975,7 @@ class Lfs:
# empty path? # empty path?
if path_ == b'': if path_ == b'':
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__ = [] path__ = []
for p in path_.split(b'/'): for p in path_.split(b'/'):
@@ -2996,7 +2996,7 @@ class Lfs:
else: else:
path__.append(p) path__.append(p)
if dotdots: if dotdots:
raise Lfs.PathError("invalid path: %r" % path) raise Lfs3.PathError("invalid path: %r" % path)
path__.reverse() path__.reverse()
path_ = path__ path_ = path__
@@ -3527,7 +3527,7 @@ class Lfs:
super().__init__(lfs, mid, mdir, tag, name) super().__init__(lfs, mid, mdir, tag, name)
# we're recursable if we're a non-grmed directory with a did # we're recursable if we're a non-grmed directory with a did
if (isinstance(self, Lfs.Dir) if (isinstance(self, Lfs3.Dir)
and not self.grmed and not self.grmed
and self.did is not None): and self.did is not None):
self.recursable = True self.recursable = True
@@ -4157,7 +4157,7 @@ def dbg_files(lfs, paths, *,
try: try:
dir = lfs.pathlookup(path, dir = lfs.pathlookup(path,
all=args.get('all')) all=args.get('all'))
except Lfs.PathError as e: except Lfs3.PathError as e:
print("error: %s" % e, print("error: %s" % e,
file=sys.stderr) file=sys.stderr)
sys.exit(-1) sys.exit(-1)
@@ -4178,7 +4178,7 @@ def dbg_files(lfs, paths, *,
# include any orphaned entries in the root directory to help # include any orphaned entries in the root directory to help
# debugging (these don't actually live in the root directory) # debugging (these don't actually live in the root directory)
if not no_orphans and isinstance(dir, Lfs.Root): if not no_orphans and isinstance(dir, Lfs3.Root):
# finding orphans is expensive, so cache this # finding orphans is expensive, so cache this
if not hasattr(iter_dir, 'orphans'): if not hasattr(iter_dir, 'orphans'):
iter_dir.orphans = dir.lfs.orphans() iter_dir.orphans = dir.lfs.orphans()
@@ -4224,7 +4224,7 @@ def dbg_files(lfs, paths, *,
if file.orphaned: if file.orphaned:
notes.append('orphaned') notes.append('orphaned')
# missing bookmark/did? # missing bookmark/did?
if isinstance(file, Lfs.Dir): if isinstance(file, Lfs3.Dir):
if file.did is None: if file.did is None:
notes.append('missing did') notes.append('missing did')
elif lfs.namelookup(file.did, b'') is None: elif lfs.namelookup(file.did, b'') is None:
@@ -4582,7 +4582,7 @@ def main(disk, mroots=None, paths=None, *,
# fetch the filesystem # fetch the filesystem
bd = Bd(f, block_size, block_count) bd = Bd(f, block_size, block_count)
lfs = Lfs.fetch(bd, mroots, trunk) lfs = Lfs3.fetch(bd, mroots, trunk)
# print some information about the filesystem # print some information about the filesystem
if not quiet: if not quiet:
+2 -2
View File
@@ -444,7 +444,7 @@ def compile(test_paths, **args):
# create case run function # create case run function
f.writeln('void __test__%s__run(' f.writeln('void __test__%s__run('
'__attribute__((unused)) ' '__attribute__((unused)) '
'struct lfs_config *CFG) {' % ( 'struct lfs3_config *CFG) {' % (
case.name)) case.name))
f.writeln(4*' '+'// test case %s' % case.name) f.writeln(4*' '+'// test case %s' % case.name)
if case.code_lineno is not None: if case.code_lineno is not None:
@@ -503,7 +503,7 @@ def compile(test_paths, **args):
'void);' % ( 'void);' % (
case.name)) case.name))
f.writeln('extern void __test__%s__run(' f.writeln('extern void __test__%s__run('
'struct lfs_config *CFG);' % ( 'struct lfs3_config *CFG);' % (
case.name)) case.name))
f.writeln() f.writeln()
+240 -240
View File
@@ -20,23 +20,23 @@ defines.COUNT = [
'2', '2',
] ]
defines.ERASE = [false, true] defines.ERASE = [false, true]
in = 'lfs.c' in = 'lfs3.c'
code = ''' code = '''
// test various block counts // test various block counts
struct lfs_config cfg = *CFG; struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT; cfg.block_count = COUNT;
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating // start allocating
lfs_alloc_ckpoint(&lfs); lfs3_alloc_ckpoint(&lfs3);
lfs_size_t alloced = 0; lfs3_size_t alloced = 0;
while (true) { while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE); lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC); assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) { if (block == LFS3_ERR_NOSPC) {
break; break;
} }
alloced += 1; alloced += 1;
@@ -47,10 +47,10 @@ code = '''
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
# test that we can realloc after an ack # test that we can realloc after an ack
@@ -64,23 +64,23 @@ defines.COUNT = [
'2', '2',
] ]
defines.ERASE = [false, true] defines.ERASE = [false, true]
in = 'lfs.c' in = 'lfs3.c'
code = ''' code = '''
// test various block counts // test various block counts
struct lfs_config cfg = *CFG; struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT; cfg.block_count = COUNT;
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// start allocating // start allocating
lfs_alloc_ckpoint(&lfs); lfs3_alloc_ckpoint(&lfs3);
lfs_size_t alloced = 0; lfs3_size_t alloced = 0;
while (true) { while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE); lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC); assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) { if (block == LFS3_ERR_NOSPC) {
break; break;
} }
alloced += 1; alloced += 1;
@@ -91,17 +91,17 @@ code = '''
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
// ack again, effectively releasing all the previously alloced blocks // ack again, effectively releasing all the previously alloced blocks
lfs_alloc_ckpoint(&lfs); lfs3_alloc_ckpoint(&lfs3);
alloced = 0; alloced = 0;
while (true) { while (true) {
lfs_sblock_t block = lfs_alloc(&lfs, ERASE); lfs3_sblock_t block = lfs3_alloc(&lfs3, ERASE);
assert(block >= 0 || block == LFS_ERR_NOSPC); assert(block >= 0 || block == LFS3_ERR_NOSPC);
if (block == LFS_ERR_NOSPC) { if (block == LFS3_ERR_NOSPC) {
break; break;
} }
alloced += 1; alloced += 1;
@@ -112,10 +112,10 @@ code = '''
// excluding our mroot, we should have allocated exactly // excluding our mroot, we should have allocated exactly
// block_count-2 blocks // block_count-2 blocks
printf("alloced %d/%d blocks\n", alloced, (lfs_block_t)COUNT); printf("alloced %d/%d blocks\n", alloced, (lfs3_block_t)COUNT);
assert(alloced == COUNT-2); assert(alloced == COUNT-2);
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -124,81 +124,81 @@ code = '''
defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512] defines.N = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
defines.CKMETA = [false, true] defines.CKMETA = [false, true]
defines.REMOUNT = [false, true] defines.REMOUNT = [false, true]
in = 'lfs.c' in = 'lfs3.c'
code = ''' code = '''
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many directories // create this many directories
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "dir%03x", i); sprintf(name, "dir%03x", i);
lfsr_mkdir(&lfs, name) => 0; lfs3_mkdir(&lfs3, name) => 0;
} }
// check that our mkdir worked // check that our mkdir worked
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "dir%03x", i); sprintf(name, "dir%03x", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_t dir; lfs3_dir_t dir;
lfsr_dir_open(&lfs, &dir, "/") => 0; lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs_info info; struct lfs3_info info;
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0); assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0); assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "dir%03x", i); sprintf(name, "dir%03x", i);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0; lfs3_dir_close(&lfs3, &dir) => 0;
// remount? // remount?
if (REMOUNT) { if (REMOUNT) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
} }
// first traverse the tree to find all blocks in use // first traverse the tree to find all blocks in use
uint8_t *seen = malloc((BLOCK_COUNT+7)/8); uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8); memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t; lfs3_traversal_t t;
lfsr_traversal_init(&t, lfs3_traversal_init(&t,
LFS_T_RDONLY LFS3_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0)); | ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) { for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops // a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT); assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag; lfs3_tag_t tag;
lfsr_bptr_t bptr; lfs3_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t, int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr); &tag, &bptr);
assert(!err || err == LFS_ERR_NOENT); assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS_ERR_NOENT) { if (err == LFS3_ERR_NOENT) {
break; break;
} }
if (tag == LFSR_TAG_MDIR) { if (tag == LFS3_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer; lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n", printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag, tag,
mdir->rbyd.blocks[0], mdir->rbyd.blocks[0],
@@ -208,8 +208,8 @@ code = '''
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8); seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8); seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) { } else if (tag == LFS3_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer; lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n", printf("traversal: 0x%x btree 0x%x.%x\n",
tag, tag,
rbyd->blocks[0], rbyd->trunk); rbyd->blocks[0], rbyd->trunk);
@@ -227,7 +227,7 @@ code = '''
// then clobber every other block // then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE]; uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE); memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) { for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) { if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0; CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -239,42 +239,42 @@ code = '''
for (int remount = 0; remount < 2; remount++) { for (int remount = 0; remount < 2; remount++) {
// remount? // remount?
if (remount) { if (remount) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
} }
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "dir%03x", i); sprintf(name, "dir%03x", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_open(&lfs, &dir, "/") => 0; lfs3_dir_open(&lfs3, &dir, "/") => 0;
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0); assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0); assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "dir%03x", i); sprintf(name, "dir%03x", i);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0; lfs3_dir_close(&lfs3, &dir) => 0;
} }
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
[cases.test_alloc_clobber_files] [cases.test_alloc_clobber_files]
@@ -290,86 +290,86 @@ defines.SIZE = [
] ]
defines.CKMETA = [false, true] defines.CKMETA = [false, true]
defines.REMOUNT = [false, true] defines.REMOUNT = [false, true]
in = 'lfs.c' in = 'lfs3.c'
if = '(SIZE*N)/BLOCK_SIZE <= 32' if = '(SIZE*N)/BLOCK_SIZE <= 32'
code = ''' code = '''
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many files // create this many files
uint32_t prng = 42; uint32_t prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "file%03x", i); sprintf(name, "file%03x", i);
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
lfsr_file_open(&lfs, &file, name, lfs3_file_open(&lfs3, &file, name,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL) => 0; LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
lfsr_file_write(&lfs, &file, wbuf, SIZE) => SIZE; lfs3_file_write(&lfs3, &file, wbuf, SIZE) => SIZE;
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
} }
// check that our writes worked // check that our writes worked
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
// check with stat // check with stat
char name[256]; char name[256];
sprintf(name, "file%03x", i); sprintf(name, "file%03x", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG); assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE); assert(info.size == SIZE);
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
} }
// remount? // remount?
if (REMOUNT) { if (REMOUNT) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
} }
// first traverse the tree to find all blocks in use // first traverse the tree to find all blocks in use
uint8_t *seen = malloc((BLOCK_COUNT+7)/8); uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8); memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t; lfs3_traversal_t t;
lfsr_traversal_init(&t, lfs3_traversal_init(&t,
LFS_T_RDONLY LFS3_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0)); | ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) { for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops // a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT); assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag; lfs3_tag_t tag;
lfsr_bptr_t bptr; lfs3_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t, int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr); &tag, &bptr);
assert(!err || err == LFS_ERR_NOENT); assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS_ERR_NOENT) { if (err == LFS3_ERR_NOENT) {
break; break;
} }
if (tag == LFSR_TAG_MDIR) { if (tag == LFS3_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer; lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n", printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag, tag,
mdir->rbyd.blocks[0], mdir->rbyd.blocks[0],
@@ -379,8 +379,8 @@ code = '''
seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8); seen[mdir->rbyd.blocks[1] / 8] |= 1 << (mdir->rbyd.blocks[1] % 8);
seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8); seen[mdir->rbyd.blocks[0] / 8] |= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) { } else if (tag == LFS3_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer; lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n", printf("traversal: 0x%x btree 0x%x.%x\n",
tag, tag,
rbyd->blocks[0], rbyd->trunk); rbyd->blocks[0], rbyd->trunk);
@@ -388,7 +388,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8); seen[rbyd->blocks[0] / 8] |= 1 << (rbyd->blocks[0] % 8);
} else if (tag == LFSR_TAG_BLOCK) { } else if (tag == LFS3_TAG_BLOCK) {
printf("traversal: 0x%x block 0x%x\n", printf("traversal: 0x%x block 0x%x\n",
tag, tag,
bptr.data.u.disk.block); bptr.data.u.disk.block);
@@ -407,7 +407,7 @@ code = '''
// then clobber every other block // then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE]; uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE); memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) { for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) { if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0; CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -419,37 +419,37 @@ code = '''
for (int remount = 0; remount < 2; remount++) { for (int remount = 0; remount < 2; remount++) {
// remount? // remount?
if (remount) { if (remount) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
} }
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
// check with stat // check with stat
char name[256]; char name[256];
sprintf(name, "file%03x", i); sprintf(name, "file%03x", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG); assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE); assert(info.size == SIZE);
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
} }
} }
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
# open files need to be tracked internally to make sure this doesn't break # open files need to be tracked internally to make sure this doesn't break
@@ -465,42 +465,42 @@ defines.SIZE = [
'8*BLOCK_SIZE', '8*BLOCK_SIZE',
] ]
defines.CKMETA = [false, true] defines.CKMETA = [false, true]
in = 'lfs.c' in = 'lfs3.c'
if = '(SIZE*N)/BLOCK_SIZE <= 32' if = '(SIZE*N)/BLOCK_SIZE <= 32'
code = ''' code = '''
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, CFG) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, CFG) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
// create this many files // create this many files
lfsr_file_t files[N]; lfs3_file_t files[N];
uint32_t prng = 42; uint32_t prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
char name[256]; char name[256];
sprintf(name, "file%03x", i); sprintf(name, "file%03x", i);
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_open(&lfs, &files[i], name, lfs3_file_open(&lfs3, &files[i], name,
LFS_O_RDWR | LFS_O_CREAT | LFS_O_EXCL) => 0; LFS3_O_RDWR | LFS3_O_CREAT | LFS3_O_EXCL) => 0;
lfsr_file_write(&lfs, &files[i], wbuf, SIZE) => SIZE; lfs3_file_write(&lfs3, &files[i], wbuf, SIZE) => SIZE;
} }
// check that our writes worked // check that our writes worked
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_rewind(&lfs, &files[i]) => 0; lfs3_file_rewind(&lfs3, &files[i]) => 0;
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
} }
@@ -508,25 +508,25 @@ code = '''
uint8_t *seen = malloc((BLOCK_COUNT+7)/8); uint8_t *seen = malloc((BLOCK_COUNT+7)/8);
memset(seen, 0, (BLOCK_COUNT+7)/8); memset(seen, 0, (BLOCK_COUNT+7)/8);
lfsr_traversal_t t; lfs3_traversal_t t;
lfsr_traversal_init(&t, lfs3_traversal_init(&t,
LFS_T_RDONLY LFS3_T_RDONLY
| ((CKMETA) ? LFS_T_CKMETA : 0)); | ((CKMETA) ? LFS3_T_CKMETA : 0));
for (lfs_block_t i = 0;; i++) { for (lfs3_block_t i = 0;; i++) {
// a bit hacky, but this catches infinite loops // a bit hacky, but this catches infinite loops
assert(i < 2*BLOCK_COUNT); assert(i < 2*BLOCK_COUNT);
lfsr_tag_t tag; lfs3_tag_t tag;
lfsr_bptr_t bptr; lfs3_bptr_t bptr;
int err = lfsr_mtree_traverse(&lfs, &t, int err = lfs3_mtree_traverse(&lfs3, &t,
&tag, &bptr); &tag, &bptr);
assert(!err || err == LFS_ERR_NOENT); assert(!err || err == LFS3_ERR_NOENT);
if (err == LFS_ERR_NOENT) { if (err == LFS3_ERR_NOENT) {
break; break;
} }
if (tag == LFSR_TAG_MDIR) { if (tag == LFS3_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)bptr.data.u.buffer; lfs3_mdir_t *mdir = (lfs3_mdir_t*)bptr.data.u.buffer;
printf("traversal: 0x%x mdir 0x{%x,%x}\n", printf("traversal: 0x%x mdir 0x{%x,%x}\n",
tag, tag,
mdir->rbyd.blocks[0], mdir->rbyd.blocks[0],
@@ -538,8 +538,8 @@ code = '''
seen[mdir->rbyd.blocks[0] / 8] seen[mdir->rbyd.blocks[0] / 8]
|= 1 << (mdir->rbyd.blocks[0] % 8); |= 1 << (mdir->rbyd.blocks[0] % 8);
} else if (tag == LFSR_TAG_BRANCH) { } else if (tag == LFS3_TAG_BRANCH) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)bptr.data.u.buffer; lfs3_rbyd_t *rbyd = (lfs3_rbyd_t*)bptr.data.u.buffer;
printf("traversal: 0x%x btree 0x%x.%x\n", printf("traversal: 0x%x btree 0x%x.%x\n",
tag, tag,
rbyd->blocks[0], rbyd->trunk); rbyd->blocks[0], rbyd->trunk);
@@ -548,7 +548,7 @@ code = '''
seen[rbyd->blocks[0] / 8] seen[rbyd->blocks[0] / 8]
|= 1 << (rbyd->blocks[0] % 8); |= 1 << (rbyd->blocks[0] % 8);
} else if (tag == LFSR_TAG_BLOCK) { } else if (tag == LFS3_TAG_BLOCK) {
printf("traversal: 0x%x block 0x%x\n", printf("traversal: 0x%x block 0x%x\n",
tag, tag,
bptr.data.u.disk.block); bptr.data.u.disk.block);
@@ -567,7 +567,7 @@ code = '''
// then clobber every other block // then clobber every other block
uint8_t clobber_buf[BLOCK_SIZE]; uint8_t clobber_buf[BLOCK_SIZE];
memset(clobber_buf, 0xcc, BLOCK_SIZE); memset(clobber_buf, 0xcc, BLOCK_SIZE);
for (lfs_block_t block = 0; block < BLOCK_COUNT; block++) { for (lfs3_block_t block = 0; block < BLOCK_COUNT; block++) {
if (!(seen[block / 8] & (1 << (block % 8)))) { if (!(seen[block / 8] & (1 << (block % 8)))) {
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0; CFG->prog(CFG, block, 0, clobber_buf, BLOCK_SIZE) => 0;
@@ -577,58 +577,58 @@ code = '''
// then check that reading our files still works after clobbering // then check that reading our files still works after clobbering
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_rewind(&lfs, &files[i]) => 0; lfs3_file_rewind(&lfs3, &files[i]) => 0;
lfsr_file_read(&lfs, &files[i], rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &files[i], rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
} }
// and everything is fine after saving the files // and everything is fine after saving the files
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
lfsr_file_close(&lfs, &files[i]) => 0; lfs3_file_close(&lfs3, &files[i]) => 0;
} }
for (int remount = 0; remount < 2; remount++) { for (int remount = 0; remount < 2; remount++) {
// remount? // remount?
if (remount) { if (remount) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, CFG) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, CFG) => 0;
} }
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < N; i++) { for (lfs3_size_t i = 0; i < N; i++) {
// check with stat // check with stat
char name[256]; char name[256];
sprintf(name, "file%03x", i); sprintf(name, "file%03x", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG); assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE); assert(info.size == SIZE);
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
} }
} }
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
@@ -647,20 +647,20 @@ defines.COUNT = [
] ]
code = ''' code = '''
// test various block counts // test various block counts
struct lfs_config cfg = *CFG; struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT; cfg.block_count = COUNT;
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// create directories until we run out of space // create directories until we run out of space
lfs_size_t n = 0; lfs3_size_t n = 0;
for (;; n++) { for (;; n++) {
char name[256]; char name[256];
sprintf(name, "dir%08d", n); sprintf(name, "dir%08d", n);
int err = lfsr_mkdir(&lfs, name); int err = lfs3_mkdir(&lfs3, name);
assert(!err || err == LFS_ERR_NOSPC); assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) { if (err == LFS3_ERR_NOSPC) {
break; break;
} }
} }
@@ -668,45 +668,45 @@ code = '''
for (int remount = 0; remount < 2; remount++) { for (int remount = 0; remount < 2; remount++) {
// remount? // remount?
if (remount) { if (remount) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
} }
// check that our mkdir worked until we ran out of space // check that our mkdir worked until we ran out of space
for (lfs_size_t i = 0; i < n; i++) { for (lfs3_size_t i = 0; i < n; i++) {
char name[256]; char name[256];
sprintf(name, "dir%08d", i); sprintf(name, "dir%08d", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_t dir; lfs3_dir_t dir;
lfsr_dir_open(&lfs, &dir, "/") => 0; lfs3_dir_open(&lfs3, &dir, "/") => 0;
struct lfs_info info; struct lfs3_info info;
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, ".") == 0); assert(strcmp(info.name, ".") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, "..") == 0); assert(strcmp(info.name, "..") == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
for (lfs_size_t i = 0; i < n; i++) { for (lfs3_size_t i = 0; i < n; i++) {
char name[256]; char name[256];
sprintf(name, "dir%08d", i); sprintf(name, "dir%08d", i);
lfsr_dir_read(&lfs, &dir, &info) => 0; lfs3_dir_read(&lfs3, &dir, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_DIR); assert(info.type == LFS3_TYPE_DIR);
assert(info.size == 0); assert(info.size == 0);
} }
lfsr_dir_read(&lfs, &dir, &info) => LFS_ERR_NOENT; lfs3_dir_read(&lfs3, &dir, &info) => LFS3_ERR_NOENT;
lfsr_dir_close(&lfs, &dir) => 0; lfs3_dir_close(&lfs3, &dir) => 0;
} }
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
[cases.test_alloc_nospc_files] [cases.test_alloc_nospc_files]
@@ -729,42 +729,42 @@ defines.SIZE = [
] ]
code = ''' code = '''
// test various block counts // test various block counts
struct lfs_config cfg = *CFG; struct lfs3_config cfg = *CFG;
cfg.block_count = COUNT; cfg.block_count = COUNT;
lfs_t lfs; lfs3_t lfs3;
lfsr_format(&lfs, LFS_F_RDWR, &cfg) => 0; lfs3_format(&lfs3, LFS3_F_RDWR, &cfg) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
// create files until we run out of space // create files until we run out of space
uint32_t prng = 42; uint32_t prng = 42;
lfs_size_t n = 0; lfs3_size_t n = 0;
for (;; n++) { for (;; n++) {
char name[256]; char name[256];
sprintf(name, "file%08d", n); sprintf(name, "file%08d", n);
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
int err = lfsr_file_open(&lfs, &file, name, int err = lfs3_file_open(&lfs3, &file, name,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL); LFS3_O_WRONLY | LFS3_O_CREAT | LFS3_O_EXCL);
assert(!err || err == LFS_ERR_NOSPC); assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) { if (err == LFS3_ERR_NOSPC) {
break; break;
} }
lfs_ssize_t size = lfsr_file_write(&lfs, &file, wbuf, SIZE); lfs3_ssize_t size = lfs3_file_write(&lfs3, &file, wbuf, SIZE);
assert(size == SIZE || size == LFS_ERR_NOSPC); assert(size == SIZE || size == LFS3_ERR_NOSPC);
if (size == LFS_ERR_NOSPC) { if (size == LFS3_ERR_NOSPC) {
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
break; break;
} }
err = lfsr_file_close(&lfs, &file); err = lfs3_file_close(&lfs3, &file);
assert(!err || err == LFS_ERR_NOSPC); assert(!err || err == LFS3_ERR_NOSPC);
if (err == LFS_ERR_NOSPC) { if (err == LFS3_ERR_NOSPC) {
break; break;
} }
} }
@@ -772,37 +772,37 @@ code = '''
for (int remount = 0; remount < 2; remount++) { for (int remount = 0; remount < 2; remount++) {
// remount? // remount?
if (remount) { if (remount) {
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
lfsr_mount(&lfs, LFS_M_RDWR, &cfg) => 0; lfs3_mount(&lfs3, LFS3_M_RDWR, &cfg) => 0;
} }
// check that our file writes worked until we ran out of space // check that our file writes worked until we ran out of space
prng = 42; prng = 42;
for (lfs_size_t i = 0; i < n; i++) { for (lfs3_size_t i = 0; i < n; i++) {
// check with stat // check with stat
char name[256]; char name[256];
sprintf(name, "file%08d", i); sprintf(name, "file%08d", i);
struct lfs_info info; struct lfs3_info info;
lfsr_stat(&lfs, name, &info) => 0; lfs3_stat(&lfs3, name, &info) => 0;
assert(strcmp(info.name, name) == 0); assert(strcmp(info.name, name) == 0);
assert(info.type == LFS_TYPE_REG); assert(info.type == LFS3_TYPE_REG);
assert(info.size == SIZE); assert(info.size == SIZE);
// try reading the file, note we reset prng above // try reading the file, note we reset prng above
uint8_t wbuf[SIZE]; uint8_t wbuf[SIZE];
for (lfs_size_t j = 0; j < SIZE; j++) { for (lfs3_size_t j = 0; j < SIZE; j++) {
wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26); wbuf[j] = 'a' + (TEST_PRNG(&prng) % 26);
} }
lfsr_file_t file; lfs3_file_t file;
uint8_t rbuf[SIZE]; uint8_t rbuf[SIZE];
lfsr_file_open(&lfs, &file, name, LFS_O_RDONLY) => 0; lfs3_file_open(&lfs3, &file, name, LFS3_O_RDONLY) => 0;
lfsr_file_read(&lfs, &file, rbuf, SIZE) => SIZE; lfs3_file_read(&lfs3, &file, rbuf, SIZE) => SIZE;
assert(memcmp(rbuf, wbuf, SIZE) == 0); assert(memcmp(rbuf, wbuf, SIZE) == 0);
lfsr_file_close(&lfs, &file) => 0; lfs3_file_close(&lfs3, &file) => 0;
} }
} }
lfsr_unmount(&lfs) => 0; lfs3_unmount(&lfs3) => 0;
''' '''
+1318 -1308
View File
File diff suppressed because it is too large Load Diff
+1592 -1592
View File
File diff suppressed because it is too large Load Diff
+59 -59
View File
@@ -10,23 +10,23 @@
defines.READ = ['READ_SIZE', 'BLOCK_SIZE'] defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE'] defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = ''' code = '''
uint8_t buffer[LFS_MAX(READ, PROG)]; uint8_t buffer[LFS3_MAX(READ, PROG)];
// write data // write data
CFG->erase(CFG, 0) => 0; CFG->erase(CFG, 0) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (i+j) % 251; buffer[j] = (i+j) % 251;
} }
CFG->prog(CFG, 0, i, buffer, PROG) => 0; CFG->prog(CFG, 0, i, buffer, PROG) => 0;
} }
// read data // read data
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, 0, i, buffer, READ) => 0; CFG->read(CFG, 0, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (i+j) % 251); LFS3_ASSERT(buffer[j] == (i+j) % 251);
} }
} }
''' '''
@@ -35,14 +35,14 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE'] defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE'] defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = ''' code = '''
uint8_t buffer[LFS_MAX(READ, PROG)]; uint8_t buffer[LFS3_MAX(READ, PROG)];
lfs_block_t block; lfs3_block_t block;
// write block 0 // write block 0
block = 0; block = 0;
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -50,19 +50,19 @@ code = '''
// read block 0 // read block 0
block = 0; block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
// write block 1 // write block 1
block = 1; block = 1;
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -70,21 +70,21 @@ code = '''
// read block 1 // read block 1
block = 1; block = 1;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
// read block 0 again // read block 0 again
block = 0; block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
''' '''
@@ -93,14 +93,14 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE'] defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE'] defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = ''' code = '''
uint8_t buffer[LFS_MAX(READ, PROG)]; uint8_t buffer[LFS3_MAX(READ, PROG)];
lfs_block_t block; lfs3_block_t block;
// write block 0 // write block 0
block = 0; block = 0;
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -108,19 +108,19 @@ code = '''
// read block 0 // read block 0
block = 0; block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
// write block n-1 // write block n-1
block = CFG->block_count-1; block = CFG->block_count-1;
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
@@ -128,21 +128,21 @@ code = '''
// read block n-1 // read block n-1
block = CFG->block_count-1; block = CFG->block_count-1;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
// read block 0 again // read block 0 again
block = 0; block = 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
''' '''
@@ -151,26 +151,26 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE'] defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE'] defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = ''' code = '''
uint8_t buffer[LFS_MAX(READ, PROG)]; uint8_t buffer[LFS3_MAX(READ, PROG)];
// write/read every power of 2 // write/read every power of 2
lfs_block_t block = 1; lfs3_block_t block = 1;
while (block < CFG->block_count) { while (block < CFG->block_count) {
// write // write
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
} }
// read // read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
@@ -181,11 +181,11 @@ code = '''
block = 1; block = 1;
while (block < CFG->block_count) { while (block < CFG->block_count) {
// read // read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
@@ -197,31 +197,31 @@ code = '''
defines.READ = ['READ_SIZE', 'BLOCK_SIZE'] defines.READ = ['READ_SIZE', 'BLOCK_SIZE']
defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE'] defines.PROG = ['PROG_SIZE', 'BLOCK_SIZE']
code = ''' code = '''
uint8_t buffer[LFS_MAX(READ, PROG)]; uint8_t buffer[LFS3_MAX(READ, PROG)];
// write/read every fibonacci number on our device // write/read every fibonacci number on our device
lfs_block_t block = 1; lfs3_block_t block = 1;
lfs_block_t block_ = 1; lfs3_block_t block_ = 1;
while (block < CFG->block_count) { while (block < CFG->block_count) {
// write // write
CFG->erase(CFG, block) => 0; CFG->erase(CFG, block) => 0;
for (lfs_off_t i = 0; i < CFG->block_size; i += PROG) { for (lfs3_off_t i = 0; i < CFG->block_size; i += PROG) {
for (lfs_off_t j = 0; j < PROG; j++) { for (lfs3_off_t j = 0; j < PROG; j++) {
buffer[j] = (block+i+j) % 251; buffer[j] = (block+i+j) % 251;
} }
CFG->prog(CFG, block, i, buffer, PROG) => 0; CFG->prog(CFG, block, i, buffer, PROG) => 0;
} }
// read // read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
lfs_block_t nblock = block + block_; lfs3_block_t nblock = block + block_;
block_ = block; block_ = block;
block = nblock; block = nblock;
} }
@@ -231,15 +231,15 @@ code = '''
block_ = 1; block_ = 1;
while (block < CFG->block_count) { while (block < CFG->block_count) {
// read // read
for (lfs_off_t i = 0; i < CFG->block_size; i += READ) { for (lfs3_off_t i = 0; i < CFG->block_size; i += READ) {
CFG->read(CFG, block, i, buffer, READ) => 0; CFG->read(CFG, block, i, buffer, READ) => 0;
for (lfs_off_t j = 0; j < READ; j++) { for (lfs3_off_t j = 0; j < READ; j++) {
LFS_ASSERT(buffer[j] == (block+i+j) % 251); LFS3_ASSERT(buffer[j] == (block+i+j) % 251);
} }
} }
lfs_block_t nblock = block + block_; lfs3_block_t nblock = block + block_;
block_ = block; block_ = block;
block = nblock; block = nblock;
} }
+1837 -1837
View File
File diff suppressed because it is too large Load Diff
+1559 -1555
View File
File diff suppressed because it is too large Load Diff
+364 -364
View File
File diff suppressed because it is too large Load Diff
+2987 -2987
View File
File diff suppressed because it is too large Load Diff
+639 -639
View File
File diff suppressed because it is too large Load Diff
+427 -427
View File
File diff suppressed because it is too large Load Diff
+1187 -1186
View File
File diff suppressed because it is too large Load Diff
+2637 -2637
View File
File diff suppressed because it is too large Load Diff
+1750 -1740
View File
File diff suppressed because it is too large Load Diff
+1250 -1238
View File
File diff suppressed because it is too large Load Diff
+937 -937
View File
File diff suppressed because it is too large Load Diff
+994 -991
View File
File diff suppressed because it is too large Load Diff
+2150 -2145
View File
File diff suppressed because it is too large Load Diff
+6080 -6080
View File
File diff suppressed because it is too large Load Diff
+287 -285
View File
File diff suppressed because it is too large Load Diff
+7622 -7599
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+4487 -4433
View File
File diff suppressed because it is too large Load Diff
+4291 -4267
View File
File diff suppressed because it is too large Load Diff