Compare commits

..

1 Commits

Author SHA1 Message Date
Christopher Haster
76333aeab1 Moved SPDX and license info into README
This makes is a bit easier to find the description about the SPDX tags,
and fixes the issue where GitHub doesn't detect the license text.
2018-07-27 13:20:18 -05:00
25 changed files with 4008 additions and 4145 deletions

2
.gitignore vendored
View File

@@ -5,5 +5,5 @@
# Testing things
blocks/
lfs1
lfs
test.c

View File

@@ -18,16 +18,16 @@ script:
- make test QUIET=1
# run tests with a few different configurations
- make test QUIET=1 CFLAGS+="-DLFS1_READ_SIZE=1 -DLFS1_PROG_SIZE=1"
- make test QUIET=1 CFLAGS+="-DLFS1_READ_SIZE=512 -DLFS1_PROG_SIZE=512"
- make test QUIET=1 CFLAGS+="-DLFS1_BLOCK_COUNT=1023 -DLFS1_LOOKAHEAD=2048"
- make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=1 -DLFS_PROG_SIZE=1"
- make test QUIET=1 CFLAGS+="-DLFS_READ_SIZE=512 -DLFS_PROG_SIZE=512"
- make test QUIET=1 CFLAGS+="-DLFS_BLOCK_COUNT=1023 -DLFS_LOOKAHEAD=2048"
- make clean test QUIET=1 CFLAGS+="-DLFS1_NO_INTRINSICS"
- make clean test QUIET=1 CFLAGS+="-DLFS_NO_INTRINSICS"
# compile and find the code size with the smallest configuration
- make clean size
OBJ="$(ls lfs1*.o | tr '\n' ' ')"
CFLAGS+="-DLFS1_NO_ASSERT -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR"
OBJ="$(ls lfs*.o | tr '\n' ' ')"
CFLAGS+="-DLFS_NO_ASSERT -DLFS_NO_DEBUG -DLFS_NO_WARN -DLFS_NO_ERROR"
| tee sizes
# update status if we succeeded, compare with master if possible
@@ -95,64 +95,92 @@ jobs:
- mips-linux-gnu-gcc --version
- qemu-mips -version
# self-host with littlefs-fuse for fuzz test
- stage: test
env:
- STAGE=test
- NAME=littlefs-fuse
install:
- sudo apt-get install libfuse-dev
- git clone --depth 1 https://github.com/geky/littlefs-fuse
- fusermount -V
- gcc --version
before_script:
# setup disk for littlefs-fuse
- rm -rf littlefs-fuse/littlefs/*
- cp -r $(git ls-tree --name-only HEAD) littlefs-fuse/littlefs
- mkdir mount
- sudo chmod a+rw /dev/loop0
- dd if=/dev/zero bs=512 count=2048 of=disk
- losetup /dev/loop0 disk
script:
# self-host test
- make -C littlefs-fuse
- littlefs-fuse/lfs --format /dev/loop0
- littlefs-fuse/lfs /dev/loop0 mount
- ls mount
- mkdir mount/littlefs
- cp -r $(git ls-tree --name-only HEAD) mount/littlefs
- cd mount/littlefs
- ls
- make -B test_dirs test_files QUIET=1
# Automatically update releases
- stage: deploy
env:
- STAGE=deploy
- NAME=deploy
script:
# Find version defined in lfs1.h
- LFS1_VERSION=$(grep -ox '#define LFS1_VERSION .*' lfs1.h | cut -d ' ' -f3)
- LFS1_VERSION_MAJOR=$((0xffff & ($LFS1_VERSION >> 16)))
- LFS1_VERSION_MINOR=$((0xffff & ($LFS1_VERSION >> 0)))
# Grab latests patch from repo tags, default to 0, needs finagling to get past github's pagination api
- PREV_URL=https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs/tags/v$LFS1_VERSION_MAJOR.$LFS1_VERSION_MINOR.
- PREV_URL=$(curl -u "$GEKY_BOT_RELEASES" "$PREV_URL" -I
| sed -n '/^Link/{s/.*<\(.*\)>; rel="last"/\1/;p;q0};$q1'
|| echo $PREV_URL)
- LFS1_VERSION_PATCH=$(curl -u "$GEKY_BOT_RELEASES" "$PREV_URL"
| jq 'map(.ref | match("\\bv.*\\..*\\.(.*)$";"g")
.captures[].string | tonumber) | max + 1'
|| echo 0)
# We have our new version
- LFS1_VERSION="v$LFS1_VERSION_MAJOR.$LFS1_VERSION_MINOR.$LFS1_VERSION_PATCH"
- echo "VERSION $LFS1_VERSION"
# Update tag for version defined in lfs.h
- LFS_VERSION=$(grep -ox '#define LFS_VERSION .*' lfs.h | cut -d ' ' -f3)
- LFS_VERSION_MAJOR=$((0xffff & ($LFS_VERSION >> 16)))
- LFS_VERSION_MINOR=$((0xffff & ($LFS_VERSION >> 0)))
- LFS_VERSION="v$LFS_VERSION_MAJOR.$LFS_VERSION_MINOR"
- echo "littlefs version $LFS_VERSION"
- |
# Check that we're the most recent commit
CURRENT_COMMIT=$(curl -f -u "$GEKY_BOT_RELEASES" \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/commits/master \
| jq -re '.sha')
if [ "$TRAVIS_COMMIT" == "$CURRENT_COMMIT" ]
curl -u $GEKY_BOT_RELEASES -X POST \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs \
-d "{
\"ref\": \"refs/tags/$LFS_VERSION\",
\"sha\": \"$TRAVIS_COMMIT\"
}"
- |
curl -f -u $GEKY_BOT_RELEASES -X PATCH \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs/tags/$LFS_VERSION \
-d "{
\"sha\": \"$TRAVIS_COMMIT\"
}"
# Create release notes from commits
- LFS_PREV_VERSION="v$LFS_VERSION_MAJOR.$(($LFS_VERSION_MINOR-1))"
- |
if [ $(git tag -l "$LFS_PREV_VERSION") ]
then
# Create a simple tag
curl -f -u "$GEKY_BOT_RELEASES" -X POST \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/git/refs \
curl -u $GEKY_BOT_RELEASES -X POST \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases \
-d "{
\"ref\": \"refs/tags/$LFS1_VERSION\",
\"sha\": \"$TRAVIS_COMMIT\"
\"tag_name\": \"$LFS_VERSION\",
\"name\": \"$LFS_VERSION\"
}"
# Minor release?
if [[ "$LFS1_VERSION" == *.0 ]]
then
# Build release notes
PREV=$(git tag --sort=-v:refname -l "v*.0" | head -1)
if [ ! -z "$PREV" ]
then
echo "PREV $PREV"
CHANGES=$'### Changes\n\n'$( \
git log --oneline $PREV.. --grep='^Merge' --invert-grep)
printf "CHANGES\n%s\n\n" "$CHANGES"
fi
# Create the release
curl -f -u "$GEKY_BOT_RELEASES" -X POST \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases \
-d "{
\"tag_name\": \"$LFS1_VERSION\",
\"name\": \"${LFS1_VERSION%.0}\",
\"draft\": true,
\"body\": $(jq -sR '.' <<< "$CHANGES")
}"
fi
RELEASE=$(
curl -f -u $GEKY_BOT_RELEASES \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/tags/$LFS_VERSION
)
CHANGES=$(
git log --oneline $LFS_PREV_VERSION.. --grep='^Merge' --invert-grep
)
curl -f -u $GEKY_BOT_RELEASES -X PATCH \
https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases/$(
jq -r '.id' <<< "$RELEASE"
) \
-d "$(
jq -s '{
"body": ((.[0] // "" | sub("(?<=\n)#+ Changes.*"; ""; "mi"))
+ "### Changes\n\n" + .[1])
}' <(jq '.body' <<< "$RELEASE") <(jq -sR '.' <<< "$CHANGES")
)"
fi
# Manage statuses

View File

@@ -1,6 +1,6 @@
TARGET = lfs1.a
TARGET = lfs.a
ifneq ($(wildcard test.c main.c),)
override TARGET = lfs1
override TARGET = lfs
endif
CC ?= gcc
@@ -25,8 +25,7 @@ ifdef WORD
override CFLAGS += -m$(WORD)
endif
override CFLAGS += -I.
override CFLAGS += -std=c99 -Wall -pedantic
override CFLAGS += -Wshadow -Wunused-parameter -Wjump-misses-init -Wsign-compare
override CFLAGS += -std=c99 -Wall -pedantic -Wshadow -Wunused-parameter
all: $(TARGET)
@@ -50,7 +49,7 @@ endif
-include $(DEP)
lfs1: $(OBJ)
lfs: $(OBJ)
$(CC) $(CFLAGS) $^ $(LFLAGS) -o $@
%.a: $(OBJ)

View File

@@ -30,14 +30,14 @@ main runs. The program can be interrupted at any time without losing track
of how many times it has been booted and without corrupting the filesystem:
``` c
#include "lfs1.h"
#include "lfs.h"
// variables used by the filesystem
lfs1_t lfs1;
lfs1_file_t file;
lfs_t lfs;
lfs_file_t file;
// configuration of the filesystem is provided by this struct
const struct lfs1_config cfg = {
const struct lfs_config cfg = {
// block device operations
.read = user_provided_block_device_read,
.prog = user_provided_block_device_prog,
@@ -55,30 +55,30 @@ const struct lfs1_config cfg = {
// entry point
int main(void) {
// mount the filesystem
int err = lfs1_mount(&lfs1, &cfg);
int err = lfs_mount(&lfs, &cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if (err) {
lfs1_format(&lfs1, &cfg);
lfs1_mount(&lfs1, &cfg);
lfs_format(&lfs, &cfg);
lfs_mount(&lfs, &cfg);
}
// read current count
uint32_t boot_count = 0;
lfs1_file_open(&lfs1, &file, "boot_count", LFS1_O_RDWR | LFS1_O_CREAT);
lfs1_file_read(&lfs1, &file, &boot_count, sizeof(boot_count));
lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count));
// update boot count
boot_count += 1;
lfs1_file_rewind(&lfs1, &file);
lfs1_file_write(&lfs1, &file, &boot_count, sizeof(boot_count));
lfs_file_rewind(&lfs, &file);
lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count));
// remember the storage is not updated until the file is closed successfully
lfs1_file_close(&lfs1, &file);
lfs_file_close(&lfs, &file);
// release any resources we were using
lfs1_unmount(&lfs1);
lfs_unmount(&lfs);
// print the boot count
printf("boot_count: %d\n", boot_count);
@@ -88,7 +88,7 @@ int main(void) {
## Usage
Detailed documentation (or at least as much detail as is currently available)
can be found in the comments in [lfs1.h](lfs1.h).
can be found in the comments in [lfs.h](lfs.h).
As you may have noticed, littlefs takes in a configuration structure that
defines how the filesystem operates. The configuration struct provides the
@@ -96,9 +96,9 @@ filesystem with the block device operations and dimensions, tweakable
parameters that tradeoff memory usage for performance, and optional
static buffers if the user wants to avoid dynamic memory.
The state of the littlefs is stored in the `lfs1_t` type which is left up
The state of the littlefs is stored in the `lfs_t` type which is left up
to the user to allocate, allowing multiple filesystems to be in use
simultaneously. With the `lfs1_t` and configuration struct, a user can
simultaneously. With the `lfs_t` and configuration struct, a user can
format a block device or mount the filesystem.
Once mounted, the littlefs provides a full set of POSIX-like file and
@@ -111,12 +111,12 @@ filesystem until sync or close is called on the file.
## Other notes
All littlefs calls have the potential to return a negative error code. The
errors can be either one of those found in the `enum lfs1_error` in
[lfs1.h](lfs1.h), or an error returned by the user's block device operations.
All littlefs have the potential to return a negative error code. The errors
can be either one of those found in the `enum lfs_error` in [lfs.h](lfs.h),
or an error returned by the user's block device operations.
In the configuration struct, the `prog` and `erase` function provided by the
user may return a `LFS1_ERR_CORRUPT` error if the implementation already can
user may return a `LFS_ERR_CORRUPT` error if the implementation already can
detect corrupt blocks. However, the wear leveling does not depend on the return
code of these functions, instead all data is read back and checked for
integrity.
@@ -139,7 +139,7 @@ with all the nitty-gritty details. Can be useful for developing tooling.
## Testing
The littlefs comes with a test suite designed to run on a PC using the
[emulated block device](emubd/lfs1_emubd.h) found in the emubd directory.
[emulated block device](emubd/lfs_emubd.h) found in the emubd directory.
The tests assume a Linux environment and can be started with make:
``` bash
@@ -175,18 +175,3 @@ handy.
[littlefs-js](https://github.com/geky/littlefs-js) - A javascript wrapper for
littlefs. I'm not sure why you would want this, but it is handy for demos.
You can see it in action [here](http://littlefs.geky.net/demo.html).
[mklfs](https://github.com/whitecatboard/Lua-RTOS-ESP32/tree/master/components/mklfs/src) -
A command line tool built by the [Lua RTOS](https://github.com/whitecatboard/Lua-RTOS-ESP32)
guys for making littlefs images from a host PC. Supports Windows, Mac OS,
and Linux.
[SPIFFS](https://github.com/pellepl/spiffs) - Another excellent embedded
filesystem for NOR flash. As a more traditional logging filesystem with full
static wear-leveling, SPIFFS will likely outperform littlefs on small
memories such as the internal flash on microcontrollers.
[Dhara](https://github.com/dlbeer/dhara) - An interesting NAND flash
translation layer designed for small MCUs. It offers static wear-leveling and
power-resilience with only a fixed O(|address|) pointer structure stored on
each block and in RAM.

View File

@@ -4,7 +4,7 @@
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "emubd/lfs1_emubd.h"
#include "emubd/lfs_emubd.h"
#include <errno.h>
#include <string.h>
@@ -20,8 +20,8 @@
// Block device emulated on existing filesystem
int lfs1_emubd_create(const struct lfs1_config *cfg, const char *path) {
lfs1_emubd_t *emu = cfg->context;
int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
lfs_emubd_t *emu = cfg->context;
emu->cfg.read_size = cfg->read_size;
emu->cfg.prog_size = cfg->prog_size;
emu->cfg.block_size = cfg->block_size;
@@ -29,7 +29,7 @@ int lfs1_emubd_create(const struct lfs1_config *cfg, const char *path) {
// Allocate buffer for creating children files
size_t pathlen = strlen(path);
emu->path = malloc(pathlen + 1 + LFS1_NAME_MAX + 1);
emu->path = malloc(pathlen + 1 + LFS_NAME_MAX + 1);
if (!emu->path) {
return -ENOMEM;
}
@@ -37,7 +37,7 @@ int lfs1_emubd_create(const struct lfs1_config *cfg, const char *path) {
strcpy(emu->path, path);
emu->path[pathlen] = '/';
emu->child = &emu->path[pathlen+1];
memset(emu->child, '\0', LFS1_NAME_MAX+1);
memset(emu->child, '\0', LFS_NAME_MAX+1);
// Create directory if it doesn't exist
int err = mkdir(path, 0777);
@@ -46,40 +46,35 @@ int lfs1_emubd_create(const struct lfs1_config *cfg, const char *path) {
}
// Load stats to continue incrementing
snprintf(emu->child, LFS1_NAME_MAX, "stats");
snprintf(emu->child, LFS_NAME_MAX, "stats");
FILE *f = fopen(emu->path, "r");
if (!f && errno != ENOENT) {
if (!f) {
return -errno;
}
if (errno == ENOENT) {
memset(&emu->stats, 0x0, sizeof(emu->stats));
} else {
size_t res = fread(&emu->stats, sizeof(emu->stats), 1, f);
if (res < 1) {
return -errno;
}
size_t res = fread(&emu->stats, sizeof(emu->stats), 1, f);
if (res < 1) {
return -errno;
}
err = fclose(f);
if (err) {
return -errno;
}
err = fclose(f);
if (err) {
return -errno;
}
return 0;
}
void lfs1_emubd_destroy(const struct lfs1_config *cfg) {
lfs1_emubd_sync(cfg);
void lfs_emubd_destroy(const struct lfs_config *cfg) {
lfs_emubd_sync(cfg);
lfs1_emubd_t *emu = cfg->context;
lfs_emubd_t *emu = cfg->context;
free(emu->path);
}
int lfs1_emubd_read(const struct lfs1_config *cfg, lfs1_block_t block,
lfs1_off_t off, void *buffer, lfs1_size_t size) {
lfs1_emubd_t *emu = cfg->context;
int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size) {
lfs_emubd_t *emu = cfg->context;
uint8_t *data = buffer;
// Check if read is valid
@@ -91,7 +86,7 @@ int lfs1_emubd_read(const struct lfs1_config *cfg, lfs1_block_t block,
memset(data, 0, size);
// Read data
snprintf(emu->child, LFS1_NAME_MAX, "%" PRIx32, block);
snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block);
FILE *f = fopen(emu->path, "rb");
if (!f && errno != ENOENT) {
@@ -119,9 +114,9 @@ int lfs1_emubd_read(const struct lfs1_config *cfg, lfs1_block_t block,
return 0;
}
int lfs1_emubd_prog(const struct lfs1_config *cfg, lfs1_block_t block,
lfs1_off_t off, const void *buffer, lfs1_size_t size) {
lfs1_emubd_t *emu = cfg->context;
int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size) {
lfs_emubd_t *emu = cfg->context;
const uint8_t *data = buffer;
// Check if write is valid
@@ -130,7 +125,7 @@ int lfs1_emubd_prog(const struct lfs1_config *cfg, lfs1_block_t block,
assert(block < cfg->block_count);
// Program data
snprintf(emu->child, LFS1_NAME_MAX, "%" PRIx32, block);
snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block);
FILE *f = fopen(emu->path, "r+b");
if (!f) {
@@ -170,14 +165,14 @@ int lfs1_emubd_prog(const struct lfs1_config *cfg, lfs1_block_t block,
return 0;
}
int lfs1_emubd_erase(const struct lfs1_config *cfg, lfs1_block_t block) {
lfs1_emubd_t *emu = cfg->context;
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) {
lfs_emubd_t *emu = cfg->context;
// Check if erase is valid
assert(block < cfg->block_count);
// Erase the block
snprintf(emu->child, LFS1_NAME_MAX, "%" PRIx32, block);
snprintf(emu->child, LFS_NAME_MAX, "%" PRIx32, block);
struct stat st;
int err = stat(emu->path, &st);
if (err && errno != ENOENT) {
@@ -207,11 +202,11 @@ int lfs1_emubd_erase(const struct lfs1_config *cfg, lfs1_block_t block) {
return 0;
}
int lfs1_emubd_sync(const struct lfs1_config *cfg) {
lfs1_emubd_t *emu = cfg->context;
int lfs_emubd_sync(const struct lfs_config *cfg) {
lfs_emubd_t *emu = cfg->context;
// Just write out info/stats for later lookup
snprintf(emu->child, LFS1_NAME_MAX, "config");
snprintf(emu->child, LFS_NAME_MAX, "config");
FILE *f = fopen(emu->path, "w");
if (!f) {
return -errno;
@@ -227,7 +222,7 @@ int lfs1_emubd_sync(const struct lfs1_config *cfg) {
return -errno;
}
snprintf(emu->child, LFS1_NAME_MAX, "stats");
snprintf(emu->child, LFS_NAME_MAX, "stats");
f = fopen(emu->path, "w");
if (!f) {
return -errno;

View File

@@ -4,11 +4,11 @@
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS1_EMUBD_H
#define LFS1_EMUBD_H
#ifndef LFS_EMUBD_H
#define LFS_EMUBD_H
#include "lfs1.h"
#include "lfs1_util.h"
#include "lfs.h"
#include "lfs_util.h"
#ifdef __cplusplus
extern "C"
@@ -17,25 +17,25 @@ extern "C"
// Config options
#ifndef LFS1_EMUBD_READ_SIZE
#define LFS1_EMUBD_READ_SIZE 1
#ifndef LFS_EMUBD_READ_SIZE
#define LFS_EMUBD_READ_SIZE 1
#endif
#ifndef LFS1_EMUBD_PROG_SIZE
#define LFS1_EMUBD_PROG_SIZE 1
#ifndef LFS_EMUBD_PROG_SIZE
#define LFS_EMUBD_PROG_SIZE 1
#endif
#ifndef LFS1_EMUBD_ERASE_SIZE
#define LFS1_EMUBD_ERASE_SIZE 512
#ifndef LFS_EMUBD_ERASE_SIZE
#define LFS_EMUBD_ERASE_SIZE 512
#endif
#ifndef LFS1_EMUBD_TOTAL_SIZE
#define LFS1_EMUBD_TOTAL_SIZE 524288
#ifndef LFS_EMUBD_TOTAL_SIZE
#define LFS_EMUBD_TOTAL_SIZE 524288
#endif
// The emu bd state
typedef struct lfs1_emubd {
typedef struct lfs_emubd {
char *path;
char *child;
@@ -51,33 +51,33 @@ typedef struct lfs1_emubd {
uint32_t block_size;
uint32_t block_count;
} cfg;
} lfs1_emubd_t;
} lfs_emubd_t;
// Create a block device using path for the directory to store blocks
int lfs1_emubd_create(const struct lfs1_config *cfg, const char *path);
int lfs_emubd_create(const struct lfs_config *cfg, const char *path);
// Clean up memory associated with emu block device
void lfs1_emubd_destroy(const struct lfs1_config *cfg);
void lfs_emubd_destroy(const struct lfs_config *cfg);
// Read a block
int lfs1_emubd_read(const struct lfs1_config *cfg, lfs1_block_t block,
lfs1_off_t off, void *buffer, lfs1_size_t size);
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 lfs1_emubd_prog(const struct lfs1_config *cfg, lfs1_block_t block,
lfs1_off_t off, const void *buffer, lfs1_size_t size);
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 lfs1_emubd_erase(const struct lfs1_config *cfg, lfs1_block_t block);
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
int lfs1_emubd_sync(const struct lfs1_config *cfg);
int lfs_emubd_sync(const struct lfs_config *cfg);
#ifdef __cplusplus

2566
lfs.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS1_H
#define LFS1_H
#ifndef LFS_H
#define LFS_H
#include <stdint.h>
#include <stdbool.h>
@@ -21,142 +21,136 @@ extern "C"
// Software library version
// Major (top-nibble), incremented on backwards incompatible changes
// Minor (bottom-nibble), incremented on feature additions
#define LFS1_VERSION 0x00010007
#define LFS1_VERSION_MAJOR (0xffff & (LFS1_VERSION >> 16))
#define LFS1_VERSION_MINOR (0xffff & (LFS1_VERSION >> 0))
#define LFS_VERSION 0x00010005
#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0))
// Version of On-disk data structures
// Major (top-nibble), incremented on backwards incompatible changes
// Minor (bottom-nibble), incremented on feature additions
#define LFS1_DISK_VERSION 0x00010001
#define LFS1_DISK_VERSION_MAJOR (0xffff & (LFS1_DISK_VERSION >> 16))
#define LFS1_DISK_VERSION_MINOR (0xffff & (LFS1_DISK_VERSION >> 0))
#define LFS_DISK_VERSION 0x00010001
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
/// Definitions ///
// Type definitions
typedef uint32_t lfs1_size_t;
typedef uint32_t lfs1_off_t;
typedef uint32_t lfs_size_t;
typedef uint32_t lfs_off_t;
typedef int32_t lfs1_ssize_t;
typedef int32_t lfs1_soff_t;
typedef int32_t lfs_ssize_t;
typedef int32_t lfs_soff_t;
typedef uint32_t lfs1_block_t;
typedef uint32_t lfs_block_t;
// Max name size in bytes
#ifndef LFS1_NAME_MAX
#define LFS1_NAME_MAX 255
#endif
// Max file size in bytes
#ifndef LFS1_FILE_MAX
#define LFS1_FILE_MAX 2147483647
#ifndef LFS_NAME_MAX
#define LFS_NAME_MAX 255
#endif
// Possible error codes, these are negative to allow
// valid positive return values
enum lfs1_error {
LFS1_ERR_OK = 0, // No error
LFS1_ERR_IO = -5, // Error during device operation
LFS1_ERR_CORRUPT = -52, // Corrupted
LFS1_ERR_NOENT = -2, // No directory entry
LFS1_ERR_EXIST = -17, // Entry already exists
LFS1_ERR_NOTDIR = -20, // Entry is not a dir
LFS1_ERR_ISDIR = -21, // Entry is a dir
LFS1_ERR_NOTEMPTY = -39, // Dir is not empty
LFS1_ERR_BADF = -9, // Bad file number
LFS1_ERR_FBIG = -27, // File too large
LFS1_ERR_INVAL = -22, // Invalid parameter
LFS1_ERR_NOSPC = -28, // No space left on device
LFS1_ERR_NOMEM = -12, // No more memory available
enum lfs_error {
LFS_ERR_OK = 0, // No error
LFS_ERR_IO = -5, // Error during device operation
LFS_ERR_CORRUPT = -52, // Corrupted
LFS_ERR_NOENT = -2, // No directory entry
LFS_ERR_EXIST = -17, // Entry already exists
LFS_ERR_NOTDIR = -20, // Entry is not a dir
LFS_ERR_ISDIR = -21, // Entry is a dir
LFS_ERR_NOTEMPTY = -39, // Dir is not empty
LFS_ERR_BADF = -9, // Bad file number
LFS_ERR_INVAL = -22, // Invalid parameter
LFS_ERR_NOSPC = -28, // No space left on device
LFS_ERR_NOMEM = -12, // No more memory available
};
// File types
enum lfs1_type {
LFS1_TYPE_REG = 0x11,
LFS1_TYPE_DIR = 0x22,
LFS1_TYPE_SUPERBLOCK = 0x2e,
enum lfs_type {
LFS_TYPE_REG = 0x11,
LFS_TYPE_DIR = 0x22,
LFS_TYPE_SUPERBLOCK = 0x2e,
};
// File open flags
enum lfs1_open_flags {
enum lfs_open_flags {
// open flags
LFS1_O_RDONLY = 1, // Open a file as read only
LFS1_O_WRONLY = 2, // Open a file as write only
LFS1_O_RDWR = 3, // Open a file as read and write
LFS1_O_CREAT = 0x0100, // Create a file if it does not exist
LFS1_O_EXCL = 0x0200, // Fail if a file already exists
LFS1_O_TRUNC = 0x0400, // Truncate the existing file to zero size
LFS1_O_APPEND = 0x0800, // Move to end of file on every write
LFS_O_RDONLY = 1, // Open a file as read only
LFS_O_WRONLY = 2, // Open a file as write only
LFS_O_RDWR = 3, // Open a file as read and write
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
LFS_O_EXCL = 0x0200, // Fail if a file already exists
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
LFS_O_APPEND = 0x0800, // Move to end of file on every write
// internally used flags
LFS1_F_DIRTY = 0x10000, // File does not match storage
LFS1_F_WRITING = 0x20000, // File has been written since last flush
LFS1_F_READING = 0x40000, // File has been read since last flush
LFS1_F_ERRED = 0x80000, // An error occured during write
LFS_F_DIRTY = 0x10000, // File does not match storage
LFS_F_WRITING = 0x20000, // File has been written since last flush
LFS_F_READING = 0x40000, // File has been read since last flush
LFS_F_ERRED = 0x80000, // An error occured during write
};
// File seek flags
enum lfs1_whence_flags {
LFS1_SEEK_SET = 0, // Seek relative to an absolute position
LFS1_SEEK_CUR = 1, // Seek relative to the current file position
LFS1_SEEK_END = 2, // Seek relative to the end of the file
enum lfs_whence_flags {
LFS_SEEK_SET = 0, // Seek relative to an absolute position
LFS_SEEK_CUR = 1, // Seek relative to the current file position
LFS_SEEK_END = 2, // Seek relative to the end of the file
};
// Configuration provided during initialization of the littlefs
struct lfs1_config {
struct lfs_config {
// Opaque user provided context that can be used to pass
// information to the block device operations
void *context;
// Read a region in a block. Negative error codes are propogated
// to the user.
int (*read)(const struct lfs1_config *c, lfs1_block_t block,
lfs1_off_t off, void *buffer, lfs1_size_t size);
int (*read)(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
// Program a region in a block. The block must have previously
// been erased. Negative error codes are propogated to the user.
// May return LFS1_ERR_CORRUPT if the block should be considered bad.
int (*prog)(const struct lfs1_config *c, lfs1_block_t block,
lfs1_off_t off, const void *buffer, lfs1_size_t size);
// May return LFS_ERR_CORRUPT if the block should be considered bad.
int (*prog)(const struct lfs_config *c, 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. Negative error codes
// are propogated to the user.
// May return LFS1_ERR_CORRUPT if the block should be considered bad.
int (*erase)(const struct lfs1_config *c, lfs1_block_t block);
// May return LFS_ERR_CORRUPT if the block should be considered bad.
int (*erase)(const struct lfs_config *c, lfs_block_t block);
// Sync the state of the underlying block device. Negative error codes
// are propogated to the user.
int (*sync)(const struct lfs1_config *c);
int (*sync)(const struct lfs_config *c);
// Minimum size of a block read. This determines the size of read buffers.
// This may be larger than the physical read size to improve performance
// by caching more of the block device.
lfs1_size_t read_size;
lfs_size_t read_size;
// Minimum size of a block program. This determines the size of program
// buffers. This may be larger than the physical program size to improve
// performance by caching more of the block device.
// Must be a multiple of the read size.
lfs1_size_t prog_size;
lfs_size_t prog_size;
// Size of an erasable block. This does not impact ram consumption and
// may be larger than the physical erase size. However, this should be
// kept small as each file currently takes up an entire block.
// Must be a multiple of the program size.
lfs1_size_t block_size;
lfs_size_t block_size;
// Number of erasable blocks on the device.
lfs1_size_t block_count;
lfs_size_t block_count;
// Number of blocks to lookahead during block allocation. A larger
// lookahead reduces the number of passes required to allocate a block.
// The lookahead buffer requires only 1 bit per block so it can be quite
// large with little ram impact. Should be a multiple of 32.
lfs1_size_t lookahead;
lfs_size_t lookahead;
// Optional, statically allocated read buffer. Must be read sized.
void *read_buffer;
@@ -173,121 +167,120 @@ struct lfs1_config {
void *file_buffer;
};
// Optional configuration provided during lfs1_file_opencfg
struct lfs1_file_config {
// Optional configuration provided during lfs_file_opencfg
struct lfs_file_config {
// Optional, statically allocated buffer for files. Must be program sized.
// If NULL, malloc will be used by default.
void *buffer;
};
// File info structure
struct lfs1_info {
// Type of the file, either LFS1_TYPE_REG or LFS1_TYPE_DIR
struct lfs_info {
// Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
uint8_t type;
// Size of the file, only valid for REG files
lfs1_size_t size;
lfs_size_t size;
// Name of the file stored as a null-terminated string
char name[LFS1_NAME_MAX+1];
char name[LFS_NAME_MAX+1];
};
/// littlefs data structures ///
typedef struct lfs1_entry {
lfs1_off_t off;
typedef struct lfs_entry {
lfs_off_t off;
struct lfs1_disk_entry {
struct lfs_disk_entry {
uint8_t type;
uint8_t elen;
uint8_t alen;
uint8_t nlen;
union {
struct {
lfs1_block_t head;
lfs1_size_t size;
lfs_block_t head;
lfs_size_t size;
} file;
lfs1_block_t dir[2];
lfs_block_t dir[2];
} u;
} d;
} lfs1_entry_t;
} lfs_entry_t;
typedef struct lfs1_cache {
lfs1_block_t block;
lfs1_off_t off;
typedef struct lfs_cache {
lfs_block_t block;
lfs_off_t off;
uint8_t *buffer;
} lfs1_cache_t;
} lfs_cache_t;
typedef struct lfs1_file {
struct lfs1_file *next;
lfs1_block_t pair[2];
lfs1_off_t poff;
typedef struct lfs_file {
struct lfs_file *next;
lfs_block_t pair[2];
lfs_off_t poff;
lfs1_block_t head;
lfs1_size_t size;
lfs_block_t head;
lfs_size_t size;
const struct lfs1_file_config *cfg;
const struct lfs_file_config *cfg;
uint32_t flags;
lfs1_off_t pos;
lfs1_block_t block;
lfs1_off_t off;
lfs1_cache_t cache;
} lfs1_file_t;
lfs_off_t pos;
lfs_block_t block;
lfs_off_t off;
lfs_cache_t cache;
} lfs_file_t;
typedef struct lfs1_dir {
struct lfs1_dir *next;
lfs1_block_t pair[2];
lfs1_off_t off;
typedef struct lfs_dir {
struct lfs_dir *next;
lfs_block_t pair[2];
lfs_off_t off;
lfs1_block_t head[2];
lfs1_off_t pos;
lfs_block_t head[2];
lfs_off_t pos;
struct lfs1_disk_dir {
struct lfs_disk_dir {
uint32_t rev;
lfs1_size_t size;
lfs1_block_t tail[2];
lfs_size_t size;
lfs_block_t tail[2];
} d;
} lfs1_dir_t;
} lfs_dir_t;
typedef struct lfs1_superblock {
lfs1_off_t off;
typedef struct lfs_superblock {
lfs_off_t off;
struct lfs1_disk_superblock {
struct lfs_disk_superblock {
uint8_t type;
uint8_t elen;
uint8_t alen;
uint8_t nlen;
lfs1_block_t root[2];
lfs_block_t root[2];
uint32_t block_size;
uint32_t block_count;
uint32_t version;
char magic[8];
} d;
} lfs1_superblock_t;
} lfs_superblock_t;
typedef struct lfs1_free {
lfs1_block_t off;
lfs1_block_t size;
lfs1_block_t i;
lfs1_block_t ack;
typedef struct lfs_free {
lfs_block_t off;
lfs_block_t size;
lfs_block_t i;
lfs_block_t ack;
uint32_t *buffer;
} lfs1_free_t;
} lfs_free_t;
// The littlefs type
typedef struct lfs1 {
const struct lfs1_config *cfg;
typedef struct lfs {
const struct lfs_config *cfg;
lfs1_block_t root[2];
lfs1_file_t *files;
lfs1_dir_t *dirs;
lfs_block_t root[2];
lfs_file_t *files;
lfs_dir_t *dirs;
lfs1_cache_t rcache;
lfs1_cache_t pcache;
lfs_cache_t rcache;
lfs_cache_t pcache;
lfs1_free_t free;
lfs_free_t free;
bool deorphaned;
bool moving;
} lfs1_t;
} lfs_t;
/// Filesystem functions ///
@@ -299,23 +292,23 @@ typedef struct lfs1 {
// be zeroed for defaults and backwards compatibility.
//
// Returns a negative error code on failure.
int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *config);
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
// Mounts a littlefs
//
// Requires a littlefs object and config struct. Multiple filesystems
// may be mounted simultaneously with multiple littlefs objects. Both
// lfs1 and config must be allocated while mounted. The config struct must
// lfs and config must be allocated while mounted. The config struct must
// be zeroed for defaults and backwards compatibility.
//
// Returns a negative error code on failure.
int lfs1_mount(lfs1_t *lfs1, const struct lfs1_config *config);
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
// Unmounts a littlefs
//
// Does nothing besides releasing any allocated resources.
// Returns a negative error code on failure.
int lfs1_unmount(lfs1_t *lfs1);
int lfs_unmount(lfs_t *lfs);
/// General operations ///
@@ -323,7 +316,7 @@ int lfs1_unmount(lfs1_t *lfs1);
//
// If removing a directory, the directory must be empty.
// Returns a negative error code on failure.
int lfs1_remove(lfs1_t *lfs1, const char *path);
int lfs_remove(lfs_t *lfs, const char *path);
// Rename or move a file or directory
//
@@ -331,13 +324,13 @@ int lfs1_remove(lfs1_t *lfs1, const char *path);
// If the destination is a directory, the directory must be empty.
//
// Returns a negative error code on failure.
int lfs1_rename(lfs1_t *lfs1, const char *oldpath, const char *newpath);
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
// Find info about a file or directory
//
// Fills out the info structure, based on the specified file or directory.
// Returns a negative error code on failure.
int lfs1_stat(lfs1_t *lfs1, const char *path, struct lfs1_info *info);
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
/// File operations ///
@@ -345,25 +338,25 @@ int lfs1_stat(lfs1_t *lfs1, const char *path, struct lfs1_info *info);
// Open a file
//
// The mode that the file is opened in is determined by the flags, which
// are values from the enum lfs1_open_flags that are bitwise-ored together.
// are values from the enum lfs_open_flags that are bitwise-ored together.
//
// Returns a negative error code on failure.
int lfs1_file_open(lfs1_t *lfs1, lfs1_file_t *file,
int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
const char *path, int flags);
// Open a file with extra configuration
//
// The mode that the file is opened in is determined by the flags, which
// are values from the enum lfs1_open_flags that are bitwise-ored together.
// are values from the enum lfs_open_flags that are bitwise-ored together.
//
// The config struct provides additional config options per file as described
// above. The config struct must be allocated while the file is open, and the
// config struct must be zeroed for defaults and backwards compatibility.
//
// Returns a negative error code on failure.
int lfs1_file_opencfg(lfs1_t *lfs1, lfs1_file_t *file,
int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
const char *path, int flags,
const struct lfs1_file_config *config);
const struct lfs_file_config *config);
// Close a file
//
@@ -371,20 +364,20 @@ int lfs1_file_opencfg(lfs1_t *lfs1, lfs1_file_t *file,
// sync had been called and releases any allocated resources.
//
// Returns a negative error code on failure.
int lfs1_file_close(lfs1_t *lfs1, lfs1_file_t *file);
int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
// Synchronize a file on storage
//
// Any pending writes are written out to storage.
// Returns a negative error code on failure.
int lfs1_file_sync(lfs1_t *lfs1, lfs1_file_t *file);
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
// Read data from file
//
// Takes a buffer and size indicating where to store the read data.
// Returns the number of bytes read, or a negative error code on failure.
lfs1_ssize_t lfs1_file_read(lfs1_t *lfs1, lfs1_file_t *file,
void *buffer, lfs1_size_t size);
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
void *buffer, lfs_size_t size);
// Write data to file
//
@@ -392,38 +385,38 @@ lfs1_ssize_t lfs1_file_read(lfs1_t *lfs1, lfs1_file_t *file,
// actually be updated on the storage until either sync or close is called.
//
// Returns the number of bytes written, or a negative error code on failure.
lfs1_ssize_t lfs1_file_write(lfs1_t *lfs1, lfs1_file_t *file,
const void *buffer, lfs1_size_t size);
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
const void *buffer, lfs_size_t size);
// Change the position of the file
//
// The change in position is determined by the offset and whence flag.
// Returns the old position of the file, or a negative error code on failure.
lfs1_soff_t lfs1_file_seek(lfs1_t *lfs1, lfs1_file_t *file,
lfs1_soff_t off, int whence);
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
lfs_soff_t off, int whence);
// Truncates the size of the file to the specified size
//
// Returns a negative error code on failure.
int lfs1_file_truncate(lfs1_t *lfs1, lfs1_file_t *file, lfs1_off_t size);
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
// Return the position of the file
//
// Equivalent to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_CUR)
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
// Returns the position of the file, or a negative error code on failure.
lfs1_soff_t lfs1_file_tell(lfs1_t *lfs1, lfs1_file_t *file);
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
// Change the position of the file to the beginning of the file
//
// Equivalent to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_CUR)
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
// Returns a negative error code on failure.
int lfs1_file_rewind(lfs1_t *lfs1, lfs1_file_t *file);
int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
// Return the size of the file
//
// Similar to lfs1_file_seek(lfs1, file, 0, LFS1_SEEK_END)
// Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
// Returns the size of the file, or a negative error code on failure.
lfs1_soff_t lfs1_file_size(lfs1_t *lfs1, lfs1_file_t *file);
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
/// Directory operations ///
@@ -431,25 +424,25 @@ lfs1_soff_t lfs1_file_size(lfs1_t *lfs1, lfs1_file_t *file);
// Create a directory
//
// Returns a negative error code on failure.
int lfs1_mkdir(lfs1_t *lfs1, const char *path);
int lfs_mkdir(lfs_t *lfs, const char *path);
// Open a directory
//
// Once open a directory can be used with read to iterate over files.
// Returns a negative error code on failure.
int lfs1_dir_open(lfs1_t *lfs1, lfs1_dir_t *dir, const char *path);
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
// Close a directory
//
// Releases any allocated resources.
// Returns a negative error code on failure.
int lfs1_dir_close(lfs1_t *lfs1, lfs1_dir_t *dir);
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
// Read an entry in the directory
//
// Fills out the info structure, based on the specified file or directory.
// Returns a negative error code on failure.
int lfs1_dir_read(lfs1_t *lfs1, lfs1_dir_t *dir, struct lfs1_info *info);
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
// Change the position of the directory
//
@@ -457,7 +450,7 @@ int lfs1_dir_read(lfs1_t *lfs1, lfs1_dir_t *dir, struct lfs1_info *info);
// an absolute offset in the directory seek.
//
// Returns a negative error code on failure.
int lfs1_dir_seek(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_off_t off);
int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
// Return the position of the directory
//
@@ -465,12 +458,12 @@ int lfs1_dir_seek(lfs1_t *lfs1, lfs1_dir_t *dir, lfs1_off_t off);
// sense, but does indicate the current position in the directory iteration.
//
// Returns the position of the directory, or a negative error code on failure.
lfs1_soff_t lfs1_dir_tell(lfs1_t *lfs1, lfs1_dir_t *dir);
lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
// Change the position of the directory to the beginning of the directory
//
// Returns a negative error code on failure.
int lfs1_dir_rewind(lfs1_t *lfs1, lfs1_dir_t *dir);
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
/// Miscellaneous littlefs specific operations ///
@@ -482,7 +475,7 @@ int lfs1_dir_rewind(lfs1_t *lfs1, lfs1_dir_t *dir);
// blocks are in use or how much of the storage is available.
//
// Returns a negative error code on failure.
int lfs1_traverse(lfs1_t *lfs1, int (*cb)(void*, lfs1_block_t), void *data);
int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
// Prunes any recoverable errors that may have occured in the filesystem
//
@@ -491,7 +484,7 @@ int lfs1_traverse(lfs1_t *lfs1, int (*cb)(void*, lfs1_block_t), void *data);
// allocation.
//
// Returns a negative error code on failure.
int lfs1_deorphan(lfs1_t *lfs1);
int lfs_deorphan(lfs_t *lfs);
#ifdef __cplusplus

2583
lfs1.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,17 @@
/*
* lfs1 util functions
* lfs util functions
*
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "lfs1_util.h"
#include "lfs_util.h"
// Only compile if user does not provide custom config
#ifndef LFS1_CONFIG
#ifndef LFS_CONFIG
// Software CRC implementation with small lookup table
void lfs1_crc(uint32_t *restrict crc, const void *buffer, size_t size) {
void lfs_crc(uint32_t *restrict crc, const void *buffer, size_t size) {
static const uint32_t rtable[16] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,

View File

@@ -1,22 +1,22 @@
/*
* lfs1 utility functions
* lfs utility functions
*
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LFS1_UTIL_H
#define LFS1_UTIL_H
#ifndef LFS_UTIL_H
#define LFS_UTIL_H
// Users can override lfs1_util.h with their own configuration by defining
// LFS1_CONFIG as a header file to include (-DLFS1_CONFIG=lfs1_config.h).
// Users can override lfs_util.h with their own configuration by defining
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
//
// If LFS1_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 lfs1_util.h and
// If LFS_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 and
// modifying as needed.
#ifdef LFS1_CONFIG
#define LFS1_STRINGIZE(x) LFS1_STRINGIZE2(x)
#define LFS1_STRINGIZE2(x) #x
#include LFS1_STRINGIZE(LFS1_CONFIG)
#ifdef LFS_CONFIG
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
#define LFS_STRINGIZE2(x) #x
#include LFS_STRINGIZE(LFS_CONFIG)
#else
// System includes
@@ -24,13 +24,13 @@
#include <stdbool.h>
#include <string.h>
#ifndef LFS1_NO_MALLOC
#ifndef LFS_NO_MALLOC
#include <stdlib.h>
#endif
#ifndef LFS1_NO_ASSERT
#ifndef LFS_NO_ASSERT
#include <assert.h>
#endif
#if !defined(LFS1_NO_DEBUG) || !defined(LFS1_NO_WARN) || !defined(LFS1_NO_ERROR)
#if !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR)
#include <stdio.h>
#endif
@@ -45,51 +45,51 @@ extern "C"
// code footprint
// Logging functions
#ifndef LFS1_NO_DEBUG
#define LFS1_DEBUG(fmt, ...) \
printf("lfs1 debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#ifndef LFS_NO_DEBUG
#define LFS_DEBUG(fmt, ...) \
printf("lfs debug:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#else
#define LFS1_DEBUG(fmt, ...)
#define LFS_DEBUG(fmt, ...)
#endif
#ifndef LFS1_NO_WARN
#define LFS1_WARN(fmt, ...) \
printf("lfs1 warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#ifndef LFS_NO_WARN
#define LFS_WARN(fmt, ...) \
printf("lfs warn:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#else
#define LFS1_WARN(fmt, ...)
#define LFS_WARN(fmt, ...)
#endif
#ifndef LFS1_NO_ERROR
#define LFS1_ERROR(fmt, ...) \
printf("lfs1 error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#ifndef LFS_NO_ERROR
#define LFS_ERROR(fmt, ...) \
printf("lfs error:%d: " fmt "\n", __LINE__, __VA_ARGS__)
#else
#define LFS1_ERROR(fmt, ...)
#define LFS_ERROR(fmt, ...)
#endif
// Runtime assertions
#ifndef LFS1_NO_ASSERT
#define LFS1_ASSERT(test) assert(test)
#ifndef LFS_NO_ASSERT
#define LFS_ASSERT(test) assert(test)
#else
#define LFS1_ASSERT(test)
#define LFS_ASSERT(test)
#endif
// Builtin functions, these may be replaced by more efficient
// toolchain-specific implementations. LFS1_NO_INTRINSICS falls back to a more
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
// expensive basic C implementation for debugging purposes
// Min/max functions for unsigned 32-bit numbers
static inline uint32_t lfs1_max(uint32_t a, uint32_t b) {
static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
return (a > b) ? a : b;
}
static inline uint32_t lfs1_min(uint32_t a, uint32_t b) {
static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
return (a < b) ? a : b;
}
// Find the next smallest power of 2 less than or equal to a
static inline uint32_t lfs1_npw2(uint32_t a) {
#if !defined(LFS1_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
static inline uint32_t lfs_npw2(uint32_t a) {
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
return 32 - __builtin_clz(a-1);
#else
uint32_t r = 0;
@@ -104,18 +104,18 @@ static inline uint32_t lfs1_npw2(uint32_t a) {
}
// Count the number of trailing binary zeros in a
// lfs1_ctz(0) may be undefined
static inline uint32_t lfs1_ctz(uint32_t a) {
#if !defined(LFS1_NO_INTRINSICS) && defined(__GNUC__)
// lfs_ctz(0) may be undefined
static inline uint32_t lfs_ctz(uint32_t a) {
#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
return __builtin_ctz(a);
#else
return lfs1_npw2((a & -a) + 1) - 1;
return lfs_npw2((a & -a) + 1) - 1;
#endif
}
// Count the number of binary ones in a
static inline uint32_t lfs1_popc(uint32_t a) {
#if !defined(LFS1_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
static inline uint32_t lfs_popc(uint32_t a) {
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
return __builtin_popcount(a);
#else
a = a - ((a >> 1) & 0x55555555);
@@ -126,18 +126,18 @@ static inline uint32_t lfs1_popc(uint32_t a) {
// Find the sequence comparison of a and b, this is the distance
// between a and b ignoring overflow
static inline int lfs1_scmp(uint32_t a, uint32_t b) {
static inline int lfs_scmp(uint32_t a, uint32_t b) {
return (int)(unsigned)(a - b);
}
// Convert from 32-bit little-endian to native order
static inline uint32_t lfs1_fromle32(uint32_t a) {
#if !defined(LFS1_NO_INTRINSICS) && ( \
static inline uint32_t lfs_fromle32(uint32_t a) {
#if !defined(LFS_NO_INTRINSICS) && ( \
(defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
(defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
return a;
#elif !defined(LFS1_NO_INTRINSICS) && ( \
#elif !defined(LFS_NO_INTRINSICS) && ( \
(defined( BYTE_ORDER ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
(defined(__BYTE_ORDER ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
@@ -151,16 +151,16 @@ static inline uint32_t lfs1_fromle32(uint32_t a) {
}
// Convert to 32-bit little-endian from native order
static inline uint32_t lfs1_tole32(uint32_t a) {
return lfs1_fromle32(a);
static inline uint32_t lfs_tole32(uint32_t a) {
return lfs_fromle32(a);
}
// Calculate CRC-32 with polynomial = 0x04c11db7
void lfs1_crc(uint32_t *crc, const void *buffer, size_t size);
void lfs_crc(uint32_t *crc, const void *buffer, size_t size);
// Allocate memory, only used if buffers are not provided to littlefs
static inline void *lfs1_malloc(size_t size) {
#ifndef LFS1_NO_MALLOC
static inline void *lfs_malloc(size_t size) {
#ifndef LFS_NO_MALLOC
return malloc(size);
#else
(void)size;
@@ -169,8 +169,8 @@ static inline void *lfs1_malloc(size_t size) {
}
// Deallocate memory, only used if buffers are not provided to littlefs
static inline void lfs1_free(void *p) {
#ifndef LFS1_NO_MALLOC
static inline void lfs_free(void *p) {
#ifndef LFS_NO_MALLOC
free(p);
#else
(void)p;

View File

@@ -1,61 +0,0 @@
#!/usr/bin/env python
# This script replaces prefixes of files, and symbols in that file.
# Useful for creating different versions of the codebase that don't
# conflict at compile time.
#
# example:
# $ ./scripts/prefix.py lfs12
import os
import os.path
import re
import glob
import itertools
import tempfile
import shutil
import subprocess
DEFAULT_PREFIX = "lfs1"
def subn(from_prefix, to_prefix, name):
name, count1 = re.subn('\\b'+from_prefix, to_prefix, name)
name, count2 = re.subn('\\b'+from_prefix.upper(), to_prefix.upper(), name)
name, count3 = re.subn('\\B-D'+from_prefix.upper(),
'-D'+to_prefix.upper(), name)
return name, count1+count2+count3
def main(from_prefix, to_prefix=None, files=None):
if not to_prefix:
from_prefix, to_prefix = DEFAULT_PREFIX, from_prefix
if not files:
files = subprocess.check_output([
'git', 'ls-tree', '-r', '--name-only', 'HEAD']).split()
for oldname in files:
# Rename any matching file names
newname, namecount = subn(from_prefix, to_prefix, oldname)
if namecount:
subprocess.check_call(['git', 'mv', oldname, newname])
# Rename any prefixes in file
count = 0
with open(newname+'~', 'w') as tempf:
with open(newname) as newf:
for line in newf:
line, n = subn(from_prefix, to_prefix, line)
count += n
tempf.write(line)
shutil.copystat(newname, newname+'~')
os.rename(newname+'~', newname)
subprocess.check_call(['git', 'add', newname])
# Summary
print '%s: %d replacements' % (
'%s -> %s' % (oldname, newname) if namecount else oldname,
count)
if __name__ == "__main__":
import sys
sys.exit(main(*sys.argv[1:]))

View File

@@ -1,6 +1,6 @@
/// AUTOGENERATED TEST ///
#include "lfs1.h"
#include "emubd/lfs1_emubd.h"
#include "lfs.h"
#include "emubd/lfs_emubd.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -37,7 +37,7 @@ static void test_assert(const char *file, unsigned line,
// utility functions for traversals
static int __attribute__((used)) test_count(void *p, lfs1_block_t b) {{
static int __attribute__((used)) test_count(void *p, lfs_block_t b) {{
(void)b;
unsigned *u = (unsigned*)p;
*u += 1;
@@ -45,62 +45,62 @@ static int __attribute__((used)) test_count(void *p, lfs1_block_t b) {{
}}
// lfs1 declarations
lfs1_t lfs1;
lfs1_emubd_t bd;
lfs1_file_t file[4];
lfs1_dir_t dir[4];
struct lfs1_info info;
// lfs declarations
lfs_t lfs;
lfs_emubd_t bd;
lfs_file_t file[4];
lfs_dir_t dir[4];
struct lfs_info info;
uint8_t buffer[1024];
uint8_t wbuffer[1024];
uint8_t rbuffer[1024];
lfs1_size_t size;
lfs1_size_t wsize;
lfs1_size_t rsize;
lfs_size_t size;
lfs_size_t wsize;
lfs_size_t rsize;
uintmax_t test;
#ifndef LFS1_READ_SIZE
#define LFS1_READ_SIZE 16
#ifndef LFS_READ_SIZE
#define LFS_READ_SIZE 16
#endif
#ifndef LFS1_PROG_SIZE
#define LFS1_PROG_SIZE 16
#ifndef LFS_PROG_SIZE
#define LFS_PROG_SIZE 16
#endif
#ifndef LFS1_BLOCK_SIZE
#define LFS1_BLOCK_SIZE 512
#ifndef LFS_BLOCK_SIZE
#define LFS_BLOCK_SIZE 512
#endif
#ifndef LFS1_BLOCK_COUNT
#define LFS1_BLOCK_COUNT 1024
#ifndef LFS_BLOCK_COUNT
#define LFS_BLOCK_COUNT 1024
#endif
#ifndef LFS1_LOOKAHEAD
#define LFS1_LOOKAHEAD 128
#ifndef LFS_LOOKAHEAD
#define LFS_LOOKAHEAD 128
#endif
const struct lfs1_config cfg = {{
const struct lfs_config cfg = {{
.context = &bd,
.read = &lfs1_emubd_read,
.prog = &lfs1_emubd_prog,
.erase = &lfs1_emubd_erase,
.sync = &lfs1_emubd_sync,
.read = &lfs_emubd_read,
.prog = &lfs_emubd_prog,
.erase = &lfs_emubd_erase,
.sync = &lfs_emubd_sync,
.read_size = LFS1_READ_SIZE,
.prog_size = LFS1_PROG_SIZE,
.block_size = LFS1_BLOCK_SIZE,
.block_count = LFS1_BLOCK_COUNT,
.lookahead = LFS1_LOOKAHEAD,
.read_size = LFS_READ_SIZE,
.prog_size = LFS_PROG_SIZE,
.block_size = LFS_BLOCK_SIZE,
.block_count = LFS_BLOCK_COUNT,
.lookahead = LFS_LOOKAHEAD,
}};
// Entry point
int main(void) {{
lfs1_emubd_create(&cfg, "blocks");
lfs_emubd_create(&cfg, "blocks");
{tests}
lfs1_emubd_destroy(&cfg);
lfs_emubd_destroy(&cfg);
}}

View File

@@ -28,7 +28,7 @@ def generate(test):
# Remove build artifacts to force rebuild
try:
os.remove('test.o')
os.remove('lfs1')
os.remove('lfs')
except OSError:
pass
@@ -39,9 +39,9 @@ def compile():
def execute():
if 'EXEC' in os.environ:
subprocess.check_call([os.environ['EXEC'], "./lfs1"])
subprocess.check_call([os.environ['EXEC'], "./lfs"])
else:
subprocess.check_call(["./lfs1"])
subprocess.check_call(["./lfs"])
def main(test=None):
if test and not test.startswith('-'):

View File

@@ -4,424 +4,424 @@ set -eu
echo "=== Allocator tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
SIZE=15000
lfs1_mkdir() {
lfs_mkdir() {
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "$1") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "$1") => 0;
lfs_unmount(&lfs) => 0;
TEST
}
lfs1_remove() {
lfs_remove() {
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "$1/eggs") => 0;
lfs1_remove(&lfs1, "$1/bacon") => 0;
lfs1_remove(&lfs1, "$1/pancakes") => 0;
lfs1_remove(&lfs1, "$1") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "$1/eggs") => 0;
lfs_remove(&lfs, "$1/bacon") => 0;
lfs_remove(&lfs, "$1/pancakes") => 0;
lfs_remove(&lfs, "$1") => 0;
lfs_unmount(&lfs) => 0;
TEST
}
lfs1_alloc_singleproc() {
lfs_alloc_singleproc() {
tests/test.py << TEST
const char *names[] = {"bacon", "eggs", "pancakes"};
lfs1_mount(&lfs1, &cfg) => 0;
for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
lfs_mount(&lfs, &cfg) => 0;
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
sprintf((char*)buffer, "$1/%s", names[n]);
lfs1_file_open(&lfs1, &file[n], (char*)buffer,
LFS1_O_WRONLY | LFS1_O_CREAT | LFS1_O_APPEND) => 0;
lfs_file_open(&lfs, &file[n], (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
}
for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
size = strlen(names[n]);
for (int i = 0; i < $SIZE; i++) {
lfs1_file_write(&lfs1, &file[n], names[n], size) => size;
lfs_file_write(&lfs, &file[n], names[n], size) => size;
}
}
for (unsigned n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
lfs1_file_close(&lfs1, &file[n]) => 0;
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) {
lfs_file_close(&lfs, &file[n]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
}
lfs1_alloc_multiproc() {
lfs_alloc_multiproc() {
for name in bacon eggs pancakes
do
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "$1/$name",
LFS1_O_WRONLY | LFS1_O_CREAT | LFS1_O_APPEND) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "$1/$name",
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
size = strlen("$name");
memcpy(buffer, "$name", size);
for (int i = 0; i < $SIZE; i++) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
done
}
lfs1_verify() {
lfs_verify() {
for name in bacon eggs pancakes
do
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "$1/$name", LFS1_O_RDONLY) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "$1/$name", LFS_O_RDONLY) => 0;
size = strlen("$name");
for (int i = 0; i < $SIZE; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "$name", size) => 0;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
done
}
echo "--- Single-process allocation test ---"
lfs1_mkdir singleproc
lfs1_alloc_singleproc singleproc
lfs1_verify singleproc
lfs_mkdir singleproc
lfs_alloc_singleproc singleproc
lfs_verify singleproc
echo "--- Multi-process allocation test ---"
lfs1_mkdir multiproc
lfs1_alloc_multiproc multiproc
lfs1_verify multiproc
lfs1_verify singleproc
lfs_mkdir multiproc
lfs_alloc_multiproc multiproc
lfs_verify multiproc
lfs_verify singleproc
echo "--- Single-process reuse test ---"
lfs1_remove singleproc
lfs1_mkdir singleprocreuse
lfs1_alloc_singleproc singleprocreuse
lfs1_verify singleprocreuse
lfs1_verify multiproc
lfs_remove singleproc
lfs_mkdir singleprocreuse
lfs_alloc_singleproc singleprocreuse
lfs_verify singleprocreuse
lfs_verify multiproc
echo "--- Multi-process reuse test ---"
lfs1_remove multiproc
lfs1_mkdir multiprocreuse
lfs1_alloc_singleproc multiprocreuse
lfs1_verify multiprocreuse
lfs1_verify singleprocreuse
lfs_remove multiproc
lfs_mkdir multiprocreuse
lfs_alloc_singleproc multiprocreuse
lfs_verify multiprocreuse
lfs_verify singleprocreuse
echo "--- Cleanup ---"
lfs1_remove multiprocreuse
lfs1_remove singleprocreuse
lfs_remove multiprocreuse
lfs_remove singleprocreuse
echo "--- Exhaustion test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
lfs1_ssize_t res;
lfs_ssize_t res;
while (true) {
res = lfs1_file_write(&lfs1, &file[0], buffer, size);
res = lfs_file_write(&lfs, &file[0], buffer, size);
if (res < 0) {
break;
}
res => size;
}
res => LFS1_ERR_NOSPC;
res => LFS_ERR_NOSPC;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_RDONLY);
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs1_file_size(&lfs1, &file[0]) => size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_size(&lfs, &file[0]) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Exhaustion wraparound test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "exhaustion") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "exhaustion") => 0;
lfs1_file_open(&lfs1, &file[0], "padding", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_file_open(&lfs, &file[0], "padding", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("buffering");
memcpy(buffer, "buffering", size);
for (int i = 0; i < $SIZE; i++) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_remove(&lfs1, "padding") => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_remove(&lfs, "padding") => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("exhaustion");
memcpy(buffer, "exhaustion", size);
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
lfs1_ssize_t res;
lfs_ssize_t res;
while (true) {
res = lfs1_file_write(&lfs1, &file[0], buffer, size);
res = lfs_file_write(&lfs, &file[0], buffer, size);
if (res < 0) {
break;
}
res => size;
}
res => LFS1_ERR_NOSPC;
res => LFS_ERR_NOSPC;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_RDONLY);
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_RDONLY);
size = strlen("exhaustion");
lfs1_file_size(&lfs1, &file[0]) => size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_size(&lfs, &file[0]) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "exhaustion", size) => 0;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Dir exhaustion test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "exhaustion") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "exhaustion") => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < (cfg.block_count-6)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_mkdir(&lfs1, "exhaustiondir") => 0;
lfs1_remove(&lfs1, "exhaustiondir") => 0;
lfs_mkdir(&lfs, "exhaustiondir") => 0;
lfs_remove(&lfs, "exhaustiondir") => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_APPEND);
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_APPEND);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < (cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_mkdir(&lfs1, "exhaustiondir") => LFS1_ERR_NOSPC;
lfs1_unmount(&lfs1) => 0;
lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Chained dir exhaustion test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "exhaustion") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "exhaustion") => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < (cfg.block_count-24)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
for (int i = 0; i < 9; i++) {
sprintf((char*)buffer, "dirwithanexhaustivelylongnameforpadding%d", i);
lfs1_mkdir(&lfs1, (char*)buffer) => 0;
lfs_mkdir(&lfs, (char*)buffer) => 0;
}
lfs1_mkdir(&lfs1, "exhaustiondir") => LFS1_ERR_NOSPC;
lfs_mkdir(&lfs, "exhaustiondir") => LFS_ERR_NOSPC;
lfs1_remove(&lfs1, "exhaustion") => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_remove(&lfs, "exhaustion") => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < (cfg.block_count-26)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_mkdir(&lfs1, "exhaustiondir") => 0;
lfs1_mkdir(&lfs1, "exhaustiondir2") => LFS1_ERR_NOSPC;
lfs_mkdir(&lfs, "exhaustiondir") => 0;
lfs_mkdir(&lfs, "exhaustiondir2") => LFS_ERR_NOSPC;
TEST
echo "--- Split dir test ---"
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
// create one block whole for half a directory
lfs1_file_open(&lfs1, &file[0], "bump", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_write(&lfs1, &file[0], (void*)"hi", 2) => 2;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file[0], (void*)"hi", 2) => 2;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion", LFS1_O_WRONLY | LFS1_O_CREAT);
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < (cfg.block_count-6)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
// open hole
lfs1_remove(&lfs1, "bump") => 0;
lfs_remove(&lfs, "bump") => 0;
lfs1_mkdir(&lfs1, "splitdir") => 0;
lfs1_file_open(&lfs1, &file[0], "splitdir/bump",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_write(&lfs1, &file[0], buffer, size) => LFS1_ERR_NOSPC;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_mkdir(&lfs, "splitdir") => 0;
lfs_file_open(&lfs, &file[0], "splitdir/bump",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file[0], buffer, size) => LFS_ERR_NOSPC;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Outdated lookahead test ---"
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
// fill completely with two files
lfs1_file_open(&lfs1, &file[0], "exhaustion1",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion1",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion2",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion2",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4+1)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
// remount to force reset of lookahead
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
// rewrite one file
lfs1_file_open(&lfs1, &file[0], "exhaustion1",
LFS1_O_WRONLY | LFS1_O_TRUNC) => 0;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion1",
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
// rewrite second file, this requires lookahead does not
// use old population
lfs1_file_open(&lfs1, &file[0], "exhaustion2",
LFS1_O_WRONLY | LFS1_O_TRUNC) => 0;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion2",
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4+1)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
TEST
echo "--- Outdated lookahead and split dir test ---"
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
// fill completely with two files
lfs1_file_open(&lfs1, &file[0], "exhaustion1",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion1",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "exhaustion2",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion2",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4+1)/2)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
// remount to force reset of lookahead
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
// rewrite one file with a hole of one block
lfs1_file_open(&lfs1, &file[0], "exhaustion1",
LFS1_O_WRONLY | LFS1_O_TRUNC) => 0;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion1",
LFS_O_WRONLY | LFS_O_TRUNC) => 0;
lfs_file_sync(&lfs, &file[0]) => 0;
size = strlen("blahblahblahblah");
memcpy(buffer, "blahblahblahblah", size);
for (lfs1_size_t i = 0;
for (lfs_size_t i = 0;
i < ((cfg.block_count-4)/2 - 1)*(cfg.block_size-8);
i += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
// try to allocate a directory, should fail!
lfs1_mkdir(&lfs1, "split") => LFS1_ERR_NOSPC;
lfs_mkdir(&lfs, "split") => LFS_ERR_NOSPC;
// file should not fail
lfs1_file_open(&lfs1, &file[0], "notasplit",
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_write(&lfs1, &file[0], "hi", 2) => 2;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "notasplit",
LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file[0], "hi", 2) => 2;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -6,71 +6,71 @@ echo "=== Corrupt tests ==="
NAMEMULT=64
FILEMULT=1
lfs1_mktree() {
lfs_mktree() {
tests/test.py ${1:-} << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
for (int i = 1; i < 10; i++) {
for (int j = 0; j < $NAMEMULT; j++) {
buffer[j] = '0'+i;
}
buffer[$NAMEMULT] = '\0';
lfs1_mkdir(&lfs1, (char*)buffer) => 0;
lfs_mkdir(&lfs, (char*)buffer) => 0;
buffer[$NAMEMULT] = '/';
for (int j = 0; j < $NAMEMULT; j++) {
buffer[j+$NAMEMULT+1] = '0'+i;
}
buffer[2*$NAMEMULT+1] = '\0';
lfs1_file_open(&lfs1, &file[0], (char*)buffer,
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = $NAMEMULT;
for (int j = 0; j < i*$FILEMULT; j++) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
}
lfs1_chktree() {
lfs_chktree() {
tests/test.py ${1:-} << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
for (int i = 1; i < 10; i++) {
for (int j = 0; j < $NAMEMULT; j++) {
buffer[j] = '0'+i;
}
buffer[$NAMEMULT] = '\0';
lfs1_stat(&lfs1, (char*)buffer, &info) => 0;
info.type => LFS1_TYPE_DIR;
lfs_stat(&lfs, (char*)buffer, &info) => 0;
info.type => LFS_TYPE_DIR;
buffer[$NAMEMULT] = '/';
for (int j = 0; j < $NAMEMULT; j++) {
buffer[j+$NAMEMULT+1] = '0'+i;
}
buffer[2*$NAMEMULT+1] = '\0';
lfs1_file_open(&lfs1, &file[0], (char*)buffer, LFS1_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[0], (char*)buffer, LFS_O_RDONLY) => 0;
size = $NAMEMULT;
for (int j = 0; j < i*$FILEMULT; j++) {
lfs1_file_read(&lfs1, &file[0], rbuffer, size) => size;
lfs_file_read(&lfs, &file[0], rbuffer, size) => size;
memcmp(buffer, rbuffer, size) => 0;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
}
echo "--- Sanity check ---"
rm -rf blocks
lfs1_mktree
lfs1_chktree
lfs_mktree
lfs_chktree
echo "--- Block corruption ---"
for i in {0..33}
@@ -78,8 +78,8 @@ do
rm -rf blocks
mkdir blocks
ln -s /dev/zero blocks/$(printf '%x' $i)
lfs1_mktree
lfs1_chktree
lfs_mktree
lfs_chktree
done
echo "--- Block persistance ---"
@@ -87,10 +87,10 @@ for i in {0..33}
do
rm -rf blocks
mkdir blocks
lfs1_mktree
lfs_mktree
chmod a-w blocks/$(printf '%x' $i)
lfs1_mktree
lfs1_chktree
lfs_mktree
lfs_chktree
done
echo "--- Big region corruption ---"
@@ -100,8 +100,8 @@ for i in {2..255}
do
ln -s /dev/zero blocks/$(printf '%x' $i)
done
lfs1_mktree
lfs1_chktree
lfs_mktree
lfs_chktree
echo "--- Alternating corruption ---"
rm -rf blocks
@@ -110,8 +110,8 @@ for i in {2..511..2}
do
ln -s /dev/zero blocks/$(printf '%x' $i)
done
lfs1_mktree
lfs1_chktree
lfs_mktree
lfs_chktree
echo "--- Results ---"
tests/stats.py

View File

@@ -6,294 +6,294 @@ LARGESIZE=128
echo "=== Directory tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
echo "--- Root directory ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Directory creation ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "potato") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "potato") => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- File creation ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "burito", LFS1_O_CREAT | LFS1_O_WRONLY) => 0;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "burito", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Directory iteration ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "potato") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Directory failures ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "potato") => LFS1_ERR_EXIST;
lfs1_dir_open(&lfs1, &dir[0], "tomato") => LFS1_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "burito") => LFS1_ERR_NOTDIR;
lfs1_file_open(&lfs1, &file[0], "tomato", LFS1_O_RDONLY) => LFS1_ERR_NOENT;
lfs1_file_open(&lfs1, &file[0], "potato", LFS1_O_RDONLY) => LFS1_ERR_ISDIR;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "potato") => LFS_ERR_EXIST;
lfs_dir_open(&lfs, &dir[0], "tomato") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "burito") => LFS_ERR_NOTDIR;
lfs_file_open(&lfs, &file[0], "tomato", LFS_O_RDONLY) => LFS_ERR_NOENT;
lfs_file_open(&lfs, &file[0], "potato", LFS_O_RDONLY) => LFS_ERR_ISDIR;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Nested directories ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "potato/baked") => 0;
lfs1_mkdir(&lfs1, "potato/sweet") => 0;
lfs1_mkdir(&lfs1, "potato/fried") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "potato/baked") => 0;
lfs_mkdir(&lfs, "potato/sweet") => 0;
lfs_mkdir(&lfs, "potato/fried") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "potato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "potato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "baked") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "sweet") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "fried") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Multi-block directory ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "cactus") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "cactus") => 0;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "cactus/test%d", i);
lfs1_mkdir(&lfs1, (char*)buffer) => 0;
lfs_mkdir(&lfs, (char*)buffer) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "cactus") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "cactus") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
info.type => LFS_TYPE_DIR;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "test%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
info.type => LFS1_TYPE_DIR;
info.type => LFS_TYPE_DIR;
}
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Directory remove ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "potato") => LFS1_ERR_NOTEMPTY;
lfs1_remove(&lfs1, "potato/sweet") => 0;
lfs1_remove(&lfs1, "potato/baked") => 0;
lfs1_remove(&lfs1, "potato/fried") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "potato") => LFS_ERR_NOTEMPTY;
lfs_remove(&lfs, "potato/sweet") => 0;
lfs_remove(&lfs, "potato/baked") => 0;
lfs_remove(&lfs, "potato/fried") => 0;
lfs1_dir_open(&lfs1, &dir[0], "potato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "potato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs1_remove(&lfs1, "potato") => 0;
lfs_remove(&lfs, "potato") => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "cactus") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "cactus") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Directory rename ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "coldpotato") => 0;
lfs1_mkdir(&lfs1, "coldpotato/baked") => 0;
lfs1_mkdir(&lfs1, "coldpotato/sweet") => 0;
lfs1_mkdir(&lfs1, "coldpotato/fried") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "coldpotato") => 0;
lfs_mkdir(&lfs, "coldpotato/baked") => 0;
lfs_mkdir(&lfs, "coldpotato/sweet") => 0;
lfs_mkdir(&lfs, "coldpotato/fried") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "coldpotato", "hotpotato") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "coldpotato", "hotpotato") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "hotpotato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "hotpotato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "baked") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "sweet") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "fried") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "warmpotato") => 0;
lfs1_mkdir(&lfs1, "warmpotato/mushy") => 0;
lfs1_rename(&lfs1, "hotpotato", "warmpotato") => LFS1_ERR_NOTEMPTY;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "warmpotato") => 0;
lfs_mkdir(&lfs, "warmpotato/mushy") => 0;
lfs_rename(&lfs, "hotpotato", "warmpotato") => LFS_ERR_NOTEMPTY;
lfs1_remove(&lfs1, "warmpotato/mushy") => 0;
lfs1_rename(&lfs1, "hotpotato", "warmpotato") => 0;
lfs_remove(&lfs, "warmpotato/mushy") => 0;
lfs_rename(&lfs, "hotpotato", "warmpotato") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "warmpotato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "warmpotato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "baked") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "sweet") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "fried") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "coldpotato") => 0;
lfs1_rename(&lfs1, "warmpotato/baked", "coldpotato/baked") => 0;
lfs1_rename(&lfs1, "warmpotato/sweet", "coldpotato/sweet") => 0;
lfs1_rename(&lfs1, "warmpotato/fried", "coldpotato/fried") => 0;
lfs1_remove(&lfs1, "coldpotato") => LFS1_ERR_NOTEMPTY;
lfs1_remove(&lfs1, "warmpotato") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "coldpotato") => 0;
lfs_rename(&lfs, "warmpotato/baked", "coldpotato/baked") => 0;
lfs_rename(&lfs, "warmpotato/sweet", "coldpotato/sweet") => 0;
lfs_rename(&lfs, "warmpotato/fried", "coldpotato/fried") => 0;
lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
lfs_remove(&lfs, "warmpotato") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "coldpotato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "coldpotato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "baked") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "sweet") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "fried") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Recursive remove ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "coldpotato") => LFS1_ERR_NOTEMPTY;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "coldpotato") => LFS_ERR_NOTEMPTY;
lfs1_dir_open(&lfs1, &dir[0], "coldpotato") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "coldpotato") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
while (true) {
int err = lfs1_dir_read(&lfs1, &dir[0], &info);
int err = lfs_dir_read(&lfs, &dir[0], &info);
err >= 0 => 1;
if (err == 0) {
break;
@@ -301,183 +301,124 @@ tests/test.py << TEST
strcpy((char*)buffer, "coldpotato/");
strcat((char*)buffer, info.name);
lfs1_remove(&lfs1, (char*)buffer) => 0;
lfs_remove(&lfs, (char*)buffer) => 0;
}
lfs1_remove(&lfs1, "coldpotato") => 0;
lfs_remove(&lfs, "coldpotato") => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "cactus") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
TEST
echo "--- Multi-block rename ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "cactus/test%d", i);
sprintf((char*)wbuffer, "cactus/tedd%d", i);
lfs1_rename(&lfs1, (char*)buffer, (char*)wbuffer) => 0;
}
lfs1_unmount(&lfs1) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "cactus") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "tedd%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
info.type => LFS1_TYPE_DIR;
}
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Multi-block remove ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "cactus") => LFS1_ERR_NOTEMPTY;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "cactus") => LFS_ERR_NOTEMPTY;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "cactus/tedd%d", i);
lfs1_remove(&lfs1, (char*)buffer) => 0;
sprintf((char*)buffer, "cactus/test%d", i);
lfs_remove(&lfs, (char*)buffer) => 0;
}
lfs1_remove(&lfs1, "cactus") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_remove(&lfs, "cactus") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Multi-block directory with files ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "prickly-pear") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "prickly-pear") => 0;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "prickly-pear/test%d", i);
lfs1_file_open(&lfs1, &file[0], (char*)buffer,
LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = 6;
memcpy(wbuffer, "Hello", size);
lfs1_file_write(&lfs1, &file[0], wbuffer, size) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_write(&lfs, &file[0], wbuffer, size) => size;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "prickly-pear") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "prickly-pear") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
info.type => LFS_TYPE_DIR;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "test%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 6;
}
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
TEST
echo "--- Multi-block rename with files ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "prickly-pear/test%d", i);
sprintf((char*)wbuffer, "prickly-pear/tedd%d", i);
lfs1_rename(&lfs1, (char*)buffer, (char*)wbuffer) => 0;
}
lfs1_unmount(&lfs1) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "prickly-pear") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "tedd%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
info.type => LFS1_TYPE_REG;
info.size => 6;
}
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Multi-block remove with files ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_remove(&lfs1, "prickly-pear") => LFS1_ERR_NOTEMPTY;
lfs_mount(&lfs, &cfg) => 0;
lfs_remove(&lfs, "prickly-pear") => LFS_ERR_NOTEMPTY;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "prickly-pear/tedd%d", i);
lfs1_remove(&lfs1, (char*)buffer) => 0;
sprintf((char*)buffer, "prickly-pear/test%d", i);
lfs_remove(&lfs, (char*)buffer) => 0;
}
lfs1_remove(&lfs1, "prickly-pear") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_remove(&lfs, "prickly-pear") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "burito") => 0;
info.type => LFS1_TYPE_REG;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
info.type => LFS_TYPE_REG;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -8,65 +8,65 @@ LARGESIZE=262144
echo "=== File tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
echo "--- Simple file test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello", LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = strlen("Hello World!\n");
memcpy(wbuffer, "Hello World!\n", size);
lfs1_file_write(&lfs1, &file[0], wbuffer, size) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_write(&lfs, &file[0], wbuffer, size) => size;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "hello", LFS1_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[0], "hello", LFS_O_RDONLY) => 0;
size = strlen("Hello World!\n");
lfs1_file_read(&lfs1, &file[0], rbuffer, size) => size;
lfs_file_read(&lfs, &file[0], rbuffer, size) => size;
memcmp(rbuffer, wbuffer, size) => 0;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
w_test() {
tests/test.py << TEST
size = $1;
lfs1_size_t chunk = 31;
lfs_size_t chunk = 31;
srand(0);
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "$2",
${3:-LFS1_O_WRONLY | LFS1_O_CREAT | LFS1_O_TRUNC}) => 0;
for (lfs1_size_t i = 0; i < size; i += chunk) {
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "$2",
${3:-LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC}) => 0;
for (lfs_size_t i = 0; i < size; i += chunk) {
chunk = (chunk < size - i) ? chunk : size - i;
for (lfs1_size_t b = 0; b < chunk; b++) {
for (lfs_size_t b = 0; b < chunk; b++) {
buffer[b] = rand() & 0xff;
}
lfs1_file_write(&lfs1, &file[0], buffer, chunk) => chunk;
lfs_file_write(&lfs, &file[0], buffer, chunk) => chunk;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
}
r_test() {
tests/test.py << TEST
size = $1;
lfs1_size_t chunk = 29;
lfs_size_t chunk = 29;
srand(0);
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "$2", &info) => 0;
info.type => LFS1_TYPE_REG;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "$2", &info) => 0;
info.type => LFS_TYPE_REG;
info.size => size;
lfs1_file_open(&lfs1, &file[0], "$2", ${3:-LFS1_O_RDONLY}) => 0;
for (lfs1_size_t i = 0; i < size; i += chunk) {
lfs_file_open(&lfs, &file[0], "$2", ${3:-LFS_O_RDONLY}) => 0;
for (lfs_size_t i = 0; i < size; i += chunk) {
chunk = (chunk < size - i) ? chunk : size - i;
lfs1_file_read(&lfs1, &file[0], buffer, chunk) => chunk;
for (lfs1_size_t b = 0; b < chunk && i+b < size; b++) {
lfs_file_read(&lfs, &file[0], buffer, chunk) => chunk;
for (lfs_size_t b = 0; b < chunk && i+b < size; b++) {
buffer[b] => rand() & 0xff;
}
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
}
@@ -106,52 +106,52 @@ r_test 0 noavacado
echo "--- Dir check ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => strlen("Hello World!\n");
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "smallavacado") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => $SMALLSIZE;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "mediumavacado") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => $MEDIUMSIZE;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "largeavacado") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => $LARGESIZE;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "noavacado") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Many file test ---"
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
tests/test.py << TEST
// Create 300 files of 6 bytes
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "directory") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "directory") => 0;
for (unsigned i = 0; i < 300; i++) {
snprintf((char*)buffer, sizeof(buffer), "file_%03d", i);
lfs1_file_open(&lfs1, &file[0], (char*)buffer, LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_file_open(&lfs, &file[0], (char*)buffer, LFS_O_WRONLY | LFS_O_CREAT) => 0;
size = 6;
memcpy(wbuffer, "Hello", size);
lfs1_file_write(&lfs1, &file[0], wbuffer, size) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_write(&lfs, &file[0], wbuffer, size) => size;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -6,43 +6,43 @@ rm -rf blocks
echo "--- Basic formatting ---"
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
echo "--- Invalid superblocks ---"
ln -f -s /dev/zero blocks/0
ln -f -s /dev/zero blocks/1
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => LFS1_ERR_CORRUPT;
lfs_format(&lfs, &cfg) => LFS_ERR_CORRUPT;
TEST
rm blocks/0 blocks/1
echo "--- Basic mounting ---"
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Invalid mount ---"
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
rm blocks/0 blocks/1
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => LFS1_ERR_CORRUPT;
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
TEST
echo "--- Valid corrupt mount ---"
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
rm blocks/0
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -4,182 +4,182 @@ set -eu
echo "=== Interspersed tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
echo "--- Interspersed file test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "a", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_open(&lfs1, &file[1], "b", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_open(&lfs1, &file[2], "c", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_open(&lfs1, &file[3], "d", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "a", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_open(&lfs, &file[1], "b", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_open(&lfs, &file[2], "c", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_open(&lfs, &file[3], "d", LFS_O_WRONLY | LFS_O_CREAT) => 0;
for (int i = 0; i < 10; i++) {
lfs1_file_write(&lfs1, &file[0], (const void*)"a", 1) => 1;
lfs1_file_write(&lfs1, &file[1], (const void*)"b", 1) => 1;
lfs1_file_write(&lfs1, &file[2], (const void*)"c", 1) => 1;
lfs1_file_write(&lfs1, &file[3], (const void*)"d", 1) => 1;
lfs_file_write(&lfs, &file[0], (const void*)"a", 1) => 1;
lfs_file_write(&lfs, &file[1], (const void*)"b", 1) => 1;
lfs_file_write(&lfs, &file[2], (const void*)"c", 1) => 1;
lfs_file_write(&lfs, &file[3], (const void*)"d", 1) => 1;
}
lfs1_file_close(&lfs1, &file[0]);
lfs1_file_close(&lfs1, &file[1]);
lfs1_file_close(&lfs1, &file[2]);
lfs1_file_close(&lfs1, &file[3]);
lfs_file_close(&lfs, &file[0]);
lfs_file_close(&lfs, &file[1]);
lfs_file_close(&lfs, &file[2]);
lfs_file_close(&lfs, &file[3]);
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "a") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "b") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "c") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "d") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "a", LFS1_O_RDONLY) => 0;
lfs1_file_open(&lfs1, &file[1], "b", LFS1_O_RDONLY) => 0;
lfs1_file_open(&lfs1, &file[2], "c", LFS1_O_RDONLY) => 0;
lfs1_file_open(&lfs1, &file[3], "d", LFS1_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[0], "a", LFS_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[1], "b", LFS_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[2], "c", LFS_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[3], "d", LFS_O_RDONLY) => 0;
for (int i = 0; i < 10; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, 1) => 1;
lfs_file_read(&lfs, &file[0], buffer, 1) => 1;
buffer[0] => 'a';
lfs1_file_read(&lfs1, &file[1], buffer, 1) => 1;
lfs_file_read(&lfs, &file[1], buffer, 1) => 1;
buffer[0] => 'b';
lfs1_file_read(&lfs1, &file[2], buffer, 1) => 1;
lfs_file_read(&lfs, &file[2], buffer, 1) => 1;
buffer[0] => 'c';
lfs1_file_read(&lfs1, &file[3], buffer, 1) => 1;
lfs_file_read(&lfs, &file[3], buffer, 1) => 1;
buffer[0] => 'd';
}
lfs1_file_close(&lfs1, &file[0]);
lfs1_file_close(&lfs1, &file[1]);
lfs1_file_close(&lfs1, &file[2]);
lfs1_file_close(&lfs1, &file[3]);
lfs_file_close(&lfs, &file[0]);
lfs_file_close(&lfs, &file[1]);
lfs_file_close(&lfs, &file[2]);
lfs_file_close(&lfs, &file[3]);
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Interspersed remove file test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "e", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "e", LFS_O_WRONLY | LFS_O_CREAT) => 0;
for (int i = 0; i < 5; i++) {
lfs1_file_write(&lfs1, &file[0], (const void*)"e", 1) => 1;
lfs_file_write(&lfs, &file[0], (const void*)"e", 1) => 1;
}
lfs1_remove(&lfs1, "a") => 0;
lfs1_remove(&lfs1, "b") => 0;
lfs1_remove(&lfs1, "c") => 0;
lfs1_remove(&lfs1, "d") => 0;
lfs_remove(&lfs, "a") => 0;
lfs_remove(&lfs, "b") => 0;
lfs_remove(&lfs, "c") => 0;
lfs_remove(&lfs, "d") => 0;
for (int i = 0; i < 5; i++) {
lfs1_file_write(&lfs1, &file[0], (const void*)"e", 1) => 1;
lfs_file_write(&lfs, &file[0], (const void*)"e", 1) => 1;
}
lfs1_file_close(&lfs1, &file[0]);
lfs_file_close(&lfs, &file[0]);
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "e") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "e", LFS1_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[0], "e", LFS_O_RDONLY) => 0;
for (int i = 0; i < 10; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, 1) => 1;
lfs_file_read(&lfs, &file[0], buffer, 1) => 1;
buffer[0] => 'e';
}
lfs1_file_close(&lfs1, &file[0]);
lfs_file_close(&lfs, &file[0]);
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Remove inconveniently test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "e", LFS1_O_WRONLY | LFS1_O_TRUNC) => 0;
lfs1_file_open(&lfs1, &file[1], "f", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs1_file_open(&lfs1, &file[2], "g", LFS1_O_WRONLY | LFS1_O_CREAT) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "e", LFS_O_WRONLY | LFS_O_TRUNC) => 0;
lfs_file_open(&lfs, &file[1], "f", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_open(&lfs, &file[2], "g", LFS_O_WRONLY | LFS_O_CREAT) => 0;
for (int i = 0; i < 5; i++) {
lfs1_file_write(&lfs1, &file[0], (const void*)"e", 1) => 1;
lfs1_file_write(&lfs1, &file[1], (const void*)"f", 1) => 1;
lfs1_file_write(&lfs1, &file[2], (const void*)"g", 1) => 1;
lfs_file_write(&lfs, &file[0], (const void*)"e", 1) => 1;
lfs_file_write(&lfs, &file[1], (const void*)"f", 1) => 1;
lfs_file_write(&lfs, &file[2], (const void*)"g", 1) => 1;
}
lfs1_remove(&lfs1, "f") => 0;
lfs_remove(&lfs, "f") => 0;
for (int i = 0; i < 5; i++) {
lfs1_file_write(&lfs1, &file[0], (const void*)"e", 1) => 1;
lfs1_file_write(&lfs1, &file[1], (const void*)"f", 1) => 1;
lfs1_file_write(&lfs1, &file[2], (const void*)"g", 1) => 1;
lfs_file_write(&lfs, &file[0], (const void*)"e", 1) => 1;
lfs_file_write(&lfs, &file[1], (const void*)"f", 1) => 1;
lfs_file_write(&lfs, &file[2], (const void*)"g", 1) => 1;
}
lfs1_file_close(&lfs1, &file[0]);
lfs1_file_close(&lfs1, &file[1]);
lfs1_file_close(&lfs1, &file[2]);
lfs_file_close(&lfs, &file[0]);
lfs_file_close(&lfs, &file[1]);
lfs_file_close(&lfs, &file[2]);
lfs1_dir_open(&lfs1, &dir[0], "/") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "/") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
info.type => LFS1_TYPE_DIR;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
info.type => LFS_TYPE_DIR;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "e") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "g") => 0;
info.type => LFS1_TYPE_REG;
info.type => LFS_TYPE_REG;
info.size => 10;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs1_file_open(&lfs1, &file[0], "e", LFS1_O_RDONLY) => 0;
lfs1_file_open(&lfs1, &file[1], "g", LFS1_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[0], "e", LFS_O_RDONLY) => 0;
lfs_file_open(&lfs, &file[1], "g", LFS_O_RDONLY) => 0;
for (int i = 0; i < 10; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, 1) => 1;
lfs_file_read(&lfs, &file[0], buffer, 1) => 1;
buffer[0] => 'e';
lfs1_file_read(&lfs1, &file[1], buffer, 1) => 1;
lfs_file_read(&lfs, &file[1], buffer, 1) => 1;
buffer[0] => 'g';
}
lfs1_file_close(&lfs1, &file[0]);
lfs1_file_close(&lfs1, &file[1]);
lfs_file_close(&lfs, &file[0]);
lfs_file_close(&lfs, &file[1]);
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -4,231 +4,231 @@ set -eu
echo "=== Move tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "a") => 0;
lfs1_mkdir(&lfs1, "b") => 0;
lfs1_mkdir(&lfs1, "c") => 0;
lfs1_mkdir(&lfs1, "d") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "a") => 0;
lfs_mkdir(&lfs, "b") => 0;
lfs_mkdir(&lfs, "c") => 0;
lfs_mkdir(&lfs, "d") => 0;
lfs1_mkdir(&lfs1, "a/hi") => 0;
lfs1_mkdir(&lfs1, "a/hi/hola") => 0;
lfs1_mkdir(&lfs1, "a/hi/bonjour") => 0;
lfs1_mkdir(&lfs1, "a/hi/ohayo") => 0;
lfs_mkdir(&lfs, "a/hi") => 0;
lfs_mkdir(&lfs, "a/hi/hola") => 0;
lfs_mkdir(&lfs, "a/hi/bonjour") => 0;
lfs_mkdir(&lfs, "a/hi/ohayo") => 0;
lfs1_file_open(&lfs1, &file[0], "a/hello", LFS1_O_CREAT | LFS1_O_WRONLY) => 0;
lfs1_file_write(&lfs1, &file[0], "hola\n", 5) => 5;
lfs1_file_write(&lfs1, &file[0], "bonjour\n", 8) => 8;
lfs1_file_write(&lfs1, &file[0], "ohayo\n", 6) => 6;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_open(&lfs, &file[0], "a/hello", LFS_O_CREAT | LFS_O_WRONLY) => 0;
lfs_file_write(&lfs, &file[0], "hola\n", 5) => 5;
lfs_file_write(&lfs, &file[0], "bonjour\n", 8) => 8;
lfs_file_write(&lfs, &file[0], "ohayo\n", 6) => 6;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move file ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "a/hello", "b/hello") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "a/hello", "b/hello") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "a") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "a") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hi") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "b") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "b") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move file corrupt source ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "b/hello", "c/hello") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "b/hello", "c/hello") => 0;
lfs_unmount(&lfs) => 0;
TEST
rm -v blocks/7
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "b") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "b") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "c") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "c") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move file corrupt source and dest ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "c/hello", "d/hello") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "c/hello", "d/hello") => 0;
lfs_unmount(&lfs) => 0;
TEST
rm -v blocks/8
rm -v blocks/a
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "c") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "c") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "d") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "d") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move dir ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "a/hi", "b/hi") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "a/hi", "b/hi") => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "a") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "a") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "b") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "b") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hi") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move dir corrupt source ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "b/hi", "c/hi") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "b/hi", "c/hi") => 0;
lfs_unmount(&lfs) => 0;
TEST
rm -v blocks/7
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "b") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "b") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "c") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "c") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hi") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move dir corrupt source and dest ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_rename(&lfs1, "c/hi", "d/hi") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_rename(&lfs, "c/hi", "d/hi") => 0;
lfs_unmount(&lfs) => 0;
TEST
rm -v blocks/9
rm -v blocks/a
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "c") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "c") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hi") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "d") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_dir_open(&lfs, &dir[0], "d") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Move check ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "a/hi") => LFS1_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "b/hi") => LFS1_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "d/hi") => LFS1_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "a/hi") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "b/hi") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "d/hi") => LFS_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "c/hi") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_open(&lfs, &dir[0], "c/hi") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "hola") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "bonjour") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "ohayo") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs1_dir_open(&lfs1, &dir[0], "a/hello") => LFS1_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "b/hello") => LFS1_ERR_NOENT;
lfs1_dir_open(&lfs1, &dir[0], "d/hello") => LFS1_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "a/hello") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "b/hello") => LFS_ERR_NOENT;
lfs_dir_open(&lfs, &dir[0], "d/hello") => LFS_ERR_NOENT;
lfs1_file_open(&lfs1, &file[0], "c/hello", LFS1_O_RDONLY) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, 5) => 5;
lfs_file_open(&lfs, &file[0], "c/hello", LFS_O_RDONLY) => 0;
lfs_file_read(&lfs, &file[0], buffer, 5) => 5;
memcmp(buffer, "hola\n", 5) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, 8) => 8;
lfs_file_read(&lfs, &file[0], buffer, 8) => 8;
memcmp(buffer, "bonjour\n", 8) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, 6) => 6;
lfs_file_read(&lfs, &file[0], buffer, 6) => 6;
memcmp(buffer, "ohayo\n", 6) => 0;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST

View File

@@ -4,37 +4,37 @@ set -eu
echo "=== Orphan tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
echo "--- Orphan test ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "parent") => 0;
lfs1_mkdir(&lfs1, "parent/orphan") => 0;
lfs1_mkdir(&lfs1, "parent/child") => 0;
lfs1_remove(&lfs1, "parent/orphan") => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "parent") => 0;
lfs_mkdir(&lfs, "parent/orphan") => 0;
lfs_mkdir(&lfs, "parent/child") => 0;
lfs_remove(&lfs, "parent/orphan") => 0;
TEST
# remove most recent file, this should be the update to the previous
# linked-list entry and should orphan the child
rm -v blocks/8
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "parent/orphan", &info) => LFS1_ERR_NOENT;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;
unsigned before = 0;
lfs1_traverse(&lfs1, test_count, &before) => 0;
lfs_traverse(&lfs, test_count, &before) => 0;
test_log("before", before);
lfs1_deorphan(&lfs1) => 0;
lfs_deorphan(&lfs) => 0;
lfs1_stat(&lfs1, "parent/orphan", &info) => LFS1_ERR_NOENT;
lfs_stat(&lfs, "parent/orphan", &info) => LFS_ERR_NOENT;
unsigned after = 0;
lfs1_traverse(&lfs1, test_count, &after) => 0;
lfs_traverse(&lfs, test_count, &after) => 0;
test_log("after", after);
int diff = before - after;
diff => 2;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -4,139 +4,139 @@ set -eu
echo "=== Path tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "tea") => 0;
lfs1_mkdir(&lfs1, "coffee") => 0;
lfs1_mkdir(&lfs1, "soda") => 0;
lfs1_mkdir(&lfs1, "tea/hottea") => 0;
lfs1_mkdir(&lfs1, "tea/warmtea") => 0;
lfs1_mkdir(&lfs1, "tea/coldtea") => 0;
lfs1_mkdir(&lfs1, "coffee/hotcoffee") => 0;
lfs1_mkdir(&lfs1, "coffee/warmcoffee") => 0;
lfs1_mkdir(&lfs1, "coffee/coldcoffee") => 0;
lfs1_mkdir(&lfs1, "soda/hotsoda") => 0;
lfs1_mkdir(&lfs1, "soda/warmsoda") => 0;
lfs1_mkdir(&lfs1, "soda/coldsoda") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "tea") => 0;
lfs_mkdir(&lfs, "coffee") => 0;
lfs_mkdir(&lfs, "soda") => 0;
lfs_mkdir(&lfs, "tea/hottea") => 0;
lfs_mkdir(&lfs, "tea/warmtea") => 0;
lfs_mkdir(&lfs, "tea/coldtea") => 0;
lfs_mkdir(&lfs, "coffee/hotcoffee") => 0;
lfs_mkdir(&lfs, "coffee/warmcoffee") => 0;
lfs_mkdir(&lfs, "coffee/coldcoffee") => 0;
lfs_mkdir(&lfs, "soda/hotsoda") => 0;
lfs_mkdir(&lfs, "soda/warmsoda") => 0;
lfs_mkdir(&lfs, "soda/coldsoda") => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Root path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "tea/hottea", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "/tea/hottea", &info) => 0;
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_mkdir(&lfs1, "/milk1") => 0;
lfs1_stat(&lfs1, "/milk1", &info) => 0;
lfs_mkdir(&lfs, "/milk1") => 0;
lfs_stat(&lfs, "/milk1", &info) => 0;
strcmp(info.name, "milk1") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Redundant slash path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "/tea/hottea", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "/tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "//tea//hottea", &info) => 0;
lfs_stat(&lfs, "//tea//hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "///tea///hottea", &info) => 0;
lfs_stat(&lfs, "///tea///hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_mkdir(&lfs1, "///milk2") => 0;
lfs1_stat(&lfs1, "///milk2", &info) => 0;
lfs_mkdir(&lfs, "///milk2") => 0;
lfs_stat(&lfs, "///milk2", &info) => 0;
strcmp(info.name, "milk2") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Dot path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "./tea/hottea", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "./tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "/./tea/hottea", &info) => 0;
lfs_stat(&lfs, "/./tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "/././tea/hottea", &info) => 0;
lfs_stat(&lfs, "/././tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "/./tea/./hottea", &info) => 0;
lfs_stat(&lfs, "/./tea/./hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_mkdir(&lfs1, "/./milk3") => 0;
lfs1_stat(&lfs1, "/./milk3", &info) => 0;
lfs_mkdir(&lfs, "/./milk3") => 0;
lfs_stat(&lfs, "/./milk3", &info) => 0;
strcmp(info.name, "milk3") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Dot dot path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "coffee/../tea/hottea", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "coffee/../tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "tea/coldtea/../hottea", &info) => 0;
lfs_stat(&lfs, "tea/coldtea/../hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "coffee/coldcoffee/../../tea/hottea", &info) => 0;
lfs_stat(&lfs, "coffee/coldcoffee/../../tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "coffee/../soda/../tea/hottea", &info) => 0;
lfs_stat(&lfs, "coffee/../soda/../tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_mkdir(&lfs1, "coffee/../milk4") => 0;
lfs1_stat(&lfs1, "coffee/../milk4", &info) => 0;
lfs_mkdir(&lfs, "coffee/../milk4") => 0;
lfs_stat(&lfs, "coffee/../milk4", &info) => 0;
strcmp(info.name, "milk4") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Trailing dot path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "tea/hottea/", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "tea/hottea/", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "tea/hottea/.", &info) => 0;
lfs_stat(&lfs, "tea/hottea/.", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "tea/hottea/./.", &info) => 0;
lfs_stat(&lfs, "tea/hottea/./.", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_stat(&lfs1, "tea/hottea/..", &info) => 0;
lfs_stat(&lfs, "tea/hottea/..", &info) => 0;
strcmp(info.name, "tea") => 0;
lfs1_stat(&lfs1, "tea/hottea/../.", &info) => 0;
lfs_stat(&lfs, "tea/hottea/../.", &info) => 0;
strcmp(info.name, "tea") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Root dot dot path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "coffee/../../../../../../tea/hottea", &info) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "coffee/../../../../../../tea/hottea", &info) => 0;
strcmp(info.name, "hottea") => 0;
lfs1_mkdir(&lfs1, "coffee/../../../../../../milk5") => 0;
lfs1_stat(&lfs1, "coffee/../../../../../../milk5", &info) => 0;
lfs_mkdir(&lfs, "coffee/../../../../../../milk5") => 0;
lfs_stat(&lfs, "coffee/../../../../../../milk5", &info) => 0;
strcmp(info.name, "milk5") => 0;
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Root tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_stat(&lfs1, "/", &info) => 0;
info.type => LFS1_TYPE_DIR;
lfs_mount(&lfs, &cfg) => 0;
lfs_stat(&lfs, "/", &info) => 0;
info.type => LFS_TYPE_DIR;
strcmp(info.name, "/") => 0;
lfs1_mkdir(&lfs1, "/") => LFS1_ERR_EXIST;
lfs1_file_open(&lfs1, &file[0], "/", LFS1_O_WRONLY | LFS1_O_CREAT)
=> LFS1_ERR_ISDIR;
lfs1_unmount(&lfs1) => 0;
lfs_mkdir(&lfs, "/") => LFS_ERR_EXIST;
lfs_file_open(&lfs, &file[0], "/", LFS_O_WRONLY | LFS_O_CREAT)
=> LFS_ERR_ISDIR;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Sketchy path tests ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "dirt/ground") => LFS1_ERR_NOENT;
lfs1_mkdir(&lfs1, "dirt/ground/earth") => LFS1_ERR_NOENT;
lfs1_unmount(&lfs1) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "dirt/ground") => LFS_ERR_NOENT;
lfs_mkdir(&lfs, "dirt/ground/earth") => LFS_ERR_NOENT;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -8,353 +8,353 @@ LARGESIZE=132
echo "=== Seek tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_mkdir(&lfs1, "hello") => 0;
lfs_format(&lfs, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_mkdir(&lfs, "hello") => 0;
for (int i = 0; i < $LARGESIZE; i++) {
sprintf((char*)buffer, "hello/kitty%d", i);
lfs1_file_open(&lfs1, &file[0], (char*)buffer,
LFS1_O_WRONLY | LFS1_O_CREAT | LFS1_O_APPEND) => 0;
lfs_file_open(&lfs, &file[0], (char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND) => 0;
size = strlen("kittycatcat");
memcpy(buffer, "kittycatcat", size);
for (int j = 0; j < $LARGESIZE; j++) {
lfs1_file_write(&lfs1, &file[0], buffer, size);
lfs_file_write(&lfs, &file[0], buffer, size);
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Simple dir seek ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "hello") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
int i;
for (i = 0; i < $SMALLSIZE; i++) {
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
pos = lfs1_dir_tell(&lfs1, &dir[0]);
pos = lfs_dir_tell(&lfs, &dir[0]);
}
pos >= 0 => 1;
lfs1_dir_seek(&lfs1, &dir[0], pos) => 0;
lfs_dir_seek(&lfs, &dir[0], pos) => 0;
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_rewind(&lfs1, &dir[0]) => 0;
lfs_dir_rewind(&lfs, &dir[0]) => 0;
sprintf((char*)buffer, "kitty%d", 0);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_seek(&lfs1, &dir[0], pos) => 0;
lfs_dir_seek(&lfs, &dir[0], pos) => 0;
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Large dir seek ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_dir_open(&lfs1, &dir[0], "hello") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_mount(&lfs, &cfg) => 0;
lfs_dir_open(&lfs, &dir[0], "hello") => 0;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
int i;
for (i = 0; i < $MEDIUMSIZE; i++) {
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
pos = lfs1_dir_tell(&lfs1, &dir[0]);
pos = lfs_dir_tell(&lfs, &dir[0]);
}
pos >= 0 => 1;
lfs1_dir_seek(&lfs1, &dir[0], pos) => 0;
lfs_dir_seek(&lfs, &dir[0], pos) => 0;
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_rewind(&lfs1, &dir[0]) => 0;
lfs_dir_rewind(&lfs, &dir[0]) => 0;
sprintf((char*)buffer, "kitty%d", 0);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, ".") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, "..") => 0;
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_seek(&lfs1, &dir[0], pos) => 0;
lfs_dir_seek(&lfs, &dir[0], pos) => 0;
sprintf((char*)buffer, "kitty%d", i);
lfs1_dir_read(&lfs1, &dir[0], &info) => 1;
lfs_dir_read(&lfs, &dir[0], &info) => 1;
strcmp(info.name, (char*)buffer) => 0;
lfs1_dir_close(&lfs1, &dir[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_dir_close(&lfs, &dir[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Simple file seek ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDONLY) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDONLY) => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
size = strlen("kittycatcat");
for (int i = 0; i < $SMALLSIZE; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
pos = lfs1_file_tell(&lfs1, &file[0]);
pos = lfs_file_tell(&lfs, &file[0]);
}
pos >= 0 => 1;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_rewind(&lfs1, &file[0]) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_rewind(&lfs, &file[0]) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], size, LFS1_SEEK_CUR) => 3*size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], size, LFS_SEEK_CUR) => 3*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_CUR) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_END) >= 0 => 1;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
size = lfs1_file_size(&lfs1, &file[0]);
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
size = lfs_file_size(&lfs, &file[0]);
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Large file seek ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDONLY) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDONLY) => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
size = strlen("kittycatcat");
for (int i = 0; i < $MEDIUMSIZE; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
pos = lfs1_file_tell(&lfs1, &file[0]);
pos = lfs_file_tell(&lfs, &file[0]);
}
pos >= 0 => 1;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_rewind(&lfs1, &file[0]) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_rewind(&lfs, &file[0]) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], size, LFS1_SEEK_CUR) => 3*size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], size, LFS_SEEK_CUR) => 3*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_CUR) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_CUR) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_END) >= 0 => 1;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
size = lfs1_file_size(&lfs1, &file[0]);
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
size = lfs_file_size(&lfs, &file[0]);
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Simple file seek and write ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDWR) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
size = strlen("kittycatcat");
for (int i = 0; i < $SMALLSIZE; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
pos = lfs1_file_tell(&lfs1, &file[0]);
pos = lfs_file_tell(&lfs, &file[0]);
}
pos >= 0 => 1;
memcpy(buffer, "doggodogdog", size);
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "doggodogdog", size) => 0;
lfs1_file_rewind(&lfs1, &file[0]) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_rewind(&lfs, &file[0]) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "doggodogdog", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_END) >= 0 => 1;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
size = lfs1_file_size(&lfs1, &file[0]);
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
size = lfs_file_size(&lfs, &file[0]);
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Large file seek and write ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDWR) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
lfs1_soff_t pos;
lfs_soff_t pos;
size = strlen("kittycatcat");
for (int i = 0; i < $MEDIUMSIZE; i++) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
if (i != $SMALLSIZE) {
memcmp(buffer, "kittycatcat", size) => 0;
}
pos = lfs1_file_tell(&lfs1, &file[0]);
pos = lfs_file_tell(&lfs, &file[0]);
}
pos >= 0 => 1;
memcpy(buffer, "doggodogdog", size);
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "doggodogdog", size) => 0;
lfs1_file_rewind(&lfs1, &file[0]) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_rewind(&lfs, &file[0]) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_seek(&lfs1, &file[0], pos, LFS1_SEEK_SET) => pos;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], pos, LFS_SEEK_SET) => pos;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "doggodogdog", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -size, LFS1_SEEK_END) >= 0 => 1;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], -size, LFS_SEEK_END) >= 0 => 1;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
size = lfs1_file_size(&lfs1, &file[0]);
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_CUR) => size;
size = lfs_file_size(&lfs, &file[0]);
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_CUR) => size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Boundary seek and write ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDWR) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
size = strlen("hedgehoghog");
const lfs1_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019};
const lfs_soff_t offsets[] = {512, 1020, 513, 1021, 511, 1019};
for (unsigned i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
lfs1_soff_t off = offsets[i];
for (int i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) {
lfs_soff_t off = offsets[i];
memcpy(buffer, "hedgehoghog", size);
lfs1_file_seek(&lfs1, &file[0], off, LFS1_SEEK_SET) => off;
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs1_file_seek(&lfs1, &file[0], off, LFS1_SEEK_SET) => off;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], off, LFS_SEEK_SET) => off;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], off, LFS_SEEK_SET) => off;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "hedgehoghog", size) => 0;
lfs1_file_seek(&lfs1, &file[0], 0, LFS1_SEEK_SET) => 0;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], 0, LFS_SEEK_SET) => 0;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "kittycatcat", size) => 0;
lfs1_file_sync(&lfs1, &file[0]) => 0;
lfs_file_sync(&lfs, &file[0]) => 0;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Out-of-bounds seek ---"
tests/test.py << TEST
lfs1_mount(&lfs1, &cfg) => 0;
lfs1_file_open(&lfs1, &file[0], "hello/kitty42", LFS1_O_RDWR) => 0;
lfs_mount(&lfs, &cfg) => 0;
lfs_file_open(&lfs, &file[0], "hello/kitty42", LFS_O_RDWR) => 0;
size = strlen("kittycatcat");
lfs1_file_size(&lfs1, &file[0]) => $LARGESIZE*size;
lfs1_file_seek(&lfs1, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
LFS1_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => 0;
lfs_file_size(&lfs, &file[0]) => $LARGESIZE*size;
lfs_file_seek(&lfs, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
LFS_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
lfs_file_read(&lfs, &file[0], buffer, size) => 0;
memcpy(buffer, "porcupineee", size);
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
lfs_file_write(&lfs, &file[0], buffer, size) => size;
lfs1_file_seek(&lfs1, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
LFS1_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], ($LARGESIZE+$SMALLSIZE)*size,
LFS_SEEK_SET) => ($LARGESIZE+$SMALLSIZE)*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "porcupineee", size) => 0;
lfs1_file_seek(&lfs1, &file[0], $LARGESIZE*size,
LFS1_SEEK_SET) => $LARGESIZE*size;
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_seek(&lfs, &file[0], $LARGESIZE*size,
LFS_SEEK_SET) => $LARGESIZE*size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "\0\0\0\0\0\0\0\0\0\0\0", size) => 0;
lfs1_file_seek(&lfs1, &file[0], -(($LARGESIZE+$SMALLSIZE)*size),
LFS1_SEEK_CUR) => LFS1_ERR_INVAL;
lfs1_file_tell(&lfs1, &file[0]) => ($LARGESIZE+1)*size;
lfs_file_seek(&lfs, &file[0], -(($LARGESIZE+$SMALLSIZE)*size),
LFS_SEEK_CUR) => LFS_ERR_INVAL;
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
lfs1_file_seek(&lfs1, &file[0], -(($LARGESIZE+2*$SMALLSIZE)*size),
LFS1_SEEK_END) => LFS1_ERR_INVAL;
lfs1_file_tell(&lfs1, &file[0]) => ($LARGESIZE+1)*size;
lfs_file_seek(&lfs, &file[0], -(($LARGESIZE+2*$SMALLSIZE)*size),
LFS_SEEK_END) => LFS_ERR_INVAL;
lfs_file_tell(&lfs, &file[0]) => ($LARGESIZE+1)*size;
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs1_unmount(&lfs1) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"

View File

@@ -8,7 +8,7 @@ LARGESIZE=8192
echo "=== Truncate tests ==="
rm -rf blocks
tests/test.py << TEST
lfs1_format(&lfs1, &cfg) => 0;
lfs_format(&lfs, &cfg) => 0;
TEST
truncate_test() {
@@ -17,98 +17,98 @@ STARTSEEKS="$2"
HOTSIZES="$3"
COLDSIZES="$4"
tests/test.py << TEST
static const lfs1_off_t startsizes[] = {$STARTSIZES};
static const lfs1_off_t startseeks[] = {$STARTSEEKS};
static const lfs1_off_t hotsizes[] = {$HOTSIZES};
static const lfs_off_t startsizes[] = {$STARTSIZES};
static const lfs_off_t startseeks[] = {$STARTSEEKS};
static const lfs_off_t hotsizes[] = {$HOTSIZES};
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
for (int i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
sprintf((char*)buffer, "hairyhead%d", i);
lfs1_file_open(&lfs1, &file[0], (const char*)buffer,
LFS1_O_WRONLY | LFS1_O_CREAT | LFS1_O_TRUNC) => 0;
lfs_file_open(&lfs, &file[0], (const char*)buffer,
LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC) => 0;
strcpy((char*)buffer, "hair");
size = strlen((char*)buffer);
for (lfs1_off_t j = 0; j < startsizes[i]; j += size) {
lfs1_file_write(&lfs1, &file[0], buffer, size) => size;
for (int j = 0; j < startsizes[i]; j += size) {
lfs_file_write(&lfs, &file[0], buffer, size) => size;
}
lfs1_file_size(&lfs1, &file[0]) => startsizes[i];
lfs_file_size(&lfs, &file[0]) => startsizes[i];
if (startseeks[i] != startsizes[i]) {
lfs1_file_seek(&lfs1, &file[0],
startseeks[i], LFS1_SEEK_SET) => startseeks[i];
lfs_file_seek(&lfs, &file[0],
startseeks[i], LFS_SEEK_SET) => startseeks[i];
}
lfs1_file_truncate(&lfs1, &file[0], hotsizes[i]) => 0;
lfs1_file_size(&lfs1, &file[0]) => hotsizes[i];
lfs_file_truncate(&lfs, &file[0], hotsizes[i]) => 0;
lfs_file_size(&lfs, &file[0]) => hotsizes[i];
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
static const lfs1_off_t startsizes[] = {$STARTSIZES};
static const lfs1_off_t hotsizes[] = {$HOTSIZES};
static const lfs1_off_t coldsizes[] = {$COLDSIZES};
static const lfs_off_t startsizes[] = {$STARTSIZES};
static const lfs_off_t hotsizes[] = {$HOTSIZES};
static const lfs_off_t coldsizes[] = {$COLDSIZES};
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
for (int i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
sprintf((char*)buffer, "hairyhead%d", i);
lfs1_file_open(&lfs1, &file[0], (const char*)buffer, LFS1_O_RDWR) => 0;
lfs1_file_size(&lfs1, &file[0]) => hotsizes[i];
lfs_file_open(&lfs, &file[0], (const char*)buffer, LFS_O_RDWR) => 0;
lfs_file_size(&lfs, &file[0]) => hotsizes[i];
size = strlen("hair");
lfs1_off_t j = 0;
int j = 0;
for (; j < startsizes[i] && j < hotsizes[i]; j += size) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
for (; j < hotsizes[i]; j += size) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "\0\0\0\0", size) => 0;
}
lfs1_file_truncate(&lfs1, &file[0], coldsizes[i]) => 0;
lfs1_file_size(&lfs1, &file[0]) => coldsizes[i];
lfs_file_truncate(&lfs, &file[0], coldsizes[i]) => 0;
lfs_file_size(&lfs, &file[0]) => coldsizes[i];
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
tests/test.py << TEST
static const lfs1_off_t startsizes[] = {$STARTSIZES};
static const lfs1_off_t hotsizes[] = {$HOTSIZES};
static const lfs1_off_t coldsizes[] = {$COLDSIZES};
static const lfs_off_t startsizes[] = {$STARTSIZES};
static const lfs_off_t hotsizes[] = {$HOTSIZES};
static const lfs_off_t coldsizes[] = {$COLDSIZES};
lfs1_mount(&lfs1, &cfg) => 0;
lfs_mount(&lfs, &cfg) => 0;
for (unsigned i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
for (int i = 0; i < sizeof(startsizes)/sizeof(startsizes[0]); i++) {
sprintf((char*)buffer, "hairyhead%d", i);
lfs1_file_open(&lfs1, &file[0], (const char*)buffer, LFS1_O_RDONLY) => 0;
lfs1_file_size(&lfs1, &file[0]) => coldsizes[i];
lfs_file_open(&lfs, &file[0], (const char*)buffer, LFS_O_RDONLY) => 0;
lfs_file_size(&lfs, &file[0]) => coldsizes[i];
size = strlen("hair");
lfs1_off_t j = 0;
int j = 0;
for (; j < startsizes[i] && j < hotsizes[i] && j < coldsizes[i];
j += size) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "hair", size) => 0;
}
for (; j < coldsizes[i]; j += size) {
lfs1_file_read(&lfs1, &file[0], buffer, size) => size;
lfs_file_read(&lfs, &file[0], buffer, size) => size;
memcmp(buffer, "\0\0\0\0", size) => 0;
}
lfs1_file_close(&lfs1, &file[0]) => 0;
lfs_file_close(&lfs, &file[0]) => 0;
}
lfs1_unmount(&lfs1) => 0;
lfs_unmount(&lfs) => 0;
TEST
}