Compare commits

...

13 Commits

Author SHA1 Message Date
Christopher Haster
21ef0b7169 WIP added some comments 2018-04-03 09:37:14 -05:00
Christopher Haster
fec133dfba WIP Bumped versions 2018-04-03 08:38:25 -05:00
Christopher Haster
9b4530f8de WIP cleaned up TODOs 2018-04-03 08:29:28 -05:00
Christopher Haster
3a12b40fff WIP added support for inline files up to 1023 bytes 2018-04-03 08:28:09 -05:00
Christopher Haster
12aa4bde06 WIP Added limits on name/attrs/inline sizes 2018-04-01 15:36:29 -05:00
Christopher Haster
09c7df83db WIP Refactored lfs_dir_set function to umbrella append/update/remove 2018-03-27 22:49:21 -05:00
Christopher Haster
5387f52de5 WIP Added lfs_dir_get 2018-03-23 18:36:02 -05:00
Christopher Haster
c5b11d2a62 WIP moved superblock to entry append 2018-03-23 16:11:36 -05:00
Christopher Haster
66cdab8327 WIP fixed bugs 2018-03-23 05:29:18 -05:00
Christopher Haster
8aba03d25f WIP Fixed issue with modifying dir after append in update 2018-03-18 20:37:13 -05:00
Christopher Haster
9064fa6dbb WIP Better implementation of inline files, now with overflowing 2018-03-17 20:32:16 -05:00
Christopher Haster
fcc5c764e4 WIP moved asserts out 2018-03-17 12:10:09 -05:00
Christopher Haster
37f799d8a2 WIP added hacky taped on inline files 2018-03-17 10:29:41 -05:00
5 changed files with 697 additions and 485 deletions

857
lfs.c

File diff suppressed because it is too large Load Diff

75
lfs.h
View File

@@ -27,14 +27,14 @@
// Software library version
// Major (top-nibble), incremented on backwards incompatible changes
// Minor (bottom-nibble), incremented on feature additions
#define LFS_VERSION 0x00010003
#define LFS_VERSION 0x00010004
#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 LFS_DISK_VERSION 0x00010001
#define LFS_DISK_VERSION 0x00010002
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
@@ -50,9 +50,27 @@ typedef int32_t lfs_soff_t;
typedef uint32_t lfs_block_t;
// Max name size in bytes
// Maximum inline file size in bytes. Large inline files require a larger
// read and prog cache, but if a file can be inline it does not need its own
// data block. LFS_ATTRS_MAX + LFS_INLINE_MAX must be <= 0xffff. Stored in
// superblock and must be respected by other littlefs drivers.
#ifndef LFS_INLINE_MAX
#define LFS_INLINE_MAX 0x3ff
#endif
// Maximum size of all attributes per file in bytes, may be redefined but a
// a smaller LFS_ATTRS_MAX has no benefit. LFS_ATTRS_MAX + LFS_INLINE_MAX
// must be <= 0xffff. Stored in superblock and must be respected by other
// littlefs drivers.
#ifndef LFS_ATTRS_MAX
#define LFS_ATTRS_MAX 0x3f
#endif
// Max name size in bytes, may be redefined to reduce the size of the
// info struct. Stored in superblock and must be respected by other
// littlefs drivers.
#ifndef LFS_NAME_MAX
#define LFS_NAME_MAX 255
#define LFS_NAME_MAX 0xff
#endif
// Possible error codes, these are negative to allow
@@ -70,6 +88,7 @@ enum lfs_error {
LFS_ERR_INVAL = -22, // Invalid parameter
LFS_ERR_NOSPC = -28, // No space left on device
LFS_ERR_NOMEM = -12, // No more memory available
LFS_ERR_NAMETOOLONG = -36, // File name too long
};
// File types
@@ -82,6 +101,7 @@ enum lfs_type {
// on disk structure
LFS_STRUCT_CTZ = 0x10,
LFS_STRUCT_DIR = 0x20,
LFS_STRUCT_INLINE = 0x30,
LFS_STRUCT_MOVED = 0x80,
};
@@ -97,10 +117,11 @@ enum lfs_open_flags {
LFS_O_APPEND = 0x0800, // Move to end of file on every write
// internally used flags
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
LFS_F_DIRTY = 0x010000, // File does not match storage
LFS_F_WRITING = 0x020000, // File has been written since last flush
LFS_F_READING = 0x040000, // File has been read since last flush
LFS_F_ERRED = 0x080000, // An error occured during write
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
};
// File seek flags
@@ -177,6 +198,25 @@ struct lfs_config {
// Optional, statically allocated buffer for files. Must be program sized.
// If enabled, only one file may be opened at a time.
void *file_buffer;
// Optional upper limit on inlined files in bytes. Large inline files
// require a larger read and prog cache, but if a file can be inlined it
// does not need its own data block. Must be smaller than the read size
// and prog size. Defaults to min(LFS_INLINE_MAX, read_size) when zero.
// Stored in superblock and must be respected by other littlefs drivers.
lfs_size_t inline_size;
// Optional upper limit on attributes per file in bytes. No downside for
// larger attributes size but must be less than LFS_ATTRS_MAX. Defaults to
// LFS_ATTRS_MAX when zero.Stored in superblock and must be respected by
// other littlefs drivers.
lfs_size_t attrs_size;
// Optional upper limit on length of file names in bytes. No downside for
// larger names except the size of the info struct which is controlled by
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
// superblock and must be respected by other littlefs drivers.
lfs_size_t name_size;
};
@@ -228,6 +268,7 @@ typedef struct lfs_file {
lfs_size_t size;
uint32_t flags;
lfs_size_t inline_size;
lfs_off_t pos;
lfs_block_t block;
lfs_off_t off;
@@ -251,15 +292,15 @@ typedef struct lfs_dir {
typedef struct lfs_superblock {
struct lfs_disk_superblock {
uint8_t type;
uint8_t elen;
uint8_t alen;
uint8_t nlen;
lfs_block_t root[2];
uint32_t block_size;
uint32_t block_count;
lfs_size_t block_size;
lfs_size_t block_count;
uint32_t version;
char magic[8];
lfs_size_t inline_size;
lfs_size_t attrs_size;
lfs_size_t name_size;
} d;
} lfs_superblock_t;
@@ -284,6 +325,10 @@ typedef struct lfs {
lfs_free_t free;
bool deorphaned;
lfs_size_t inline_size;
lfs_size_t attrs_size;
lfs_size_t name_size;
} lfs_t;

View File

@@ -274,9 +274,12 @@ TEST
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
// create one block whole for half a directory
// create one block hole for half a directory
lfs_file_open(&lfs, &file[0], "bump", LFS_O_WRONLY | LFS_O_CREAT) => 0;
lfs_file_write(&lfs, &file[0], (void*)"hi", 2) => 2;
for (lfs_size_t i = 0; i < cfg.block_size; i += 2) {
memcpy(&buffer[i], "hi", 2);
}
lfs_file_write(&lfs, &file[0], buffer, cfg.block_size) => cfg.block_size;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_file_open(&lfs, &file[0], "exhaustion", LFS_O_WRONLY | LFS_O_CREAT);
@@ -289,13 +292,16 @@ tests/test.py << TEST
}
lfs_file_close(&lfs, &file[0]) => 0;
// open whole
// open hole
lfs_remove(&lfs, "bump") => 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;
for (lfs_size_t i = 0; i < cfg.block_size; i += 2) {
memcpy(&buffer[i], "hi", 2);
}
lfs_file_write(&lfs, &file[0], buffer, cfg.block_size) => LFS_ERR_NOSPC;
lfs_file_close(&lfs, &file[0]) => 0;
lfs_unmount(&lfs) => 0;

View File

@@ -73,7 +73,7 @@ lfs_mktree
lfs_chktree
echo "--- Block corruption ---"
for i in {0..33}
for i in {2..33}
do
rm -rf blocks
mkdir blocks
@@ -83,12 +83,12 @@ do
done
echo "--- Block persistance ---"
for i in {0..33}
for i in {2..33}
do
rm -rf blocks
mkdir blocks
lfs_mktree
chmod a-w blocks/$(printf '%x' $i)
chmod a-w blocks/$(printf '%x' $i) || true
lfs_mktree
lfs_chktree
done

View File

@@ -30,20 +30,10 @@ echo "--- Invalid mount ---"
tests/test.py << TEST
lfs_format(&lfs, &cfg) => 0;
TEST
rm blocks/0 blocks/1
rm -f blocks/0 blocks/1
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => LFS_ERR_CORRUPT;
TEST
echo "--- Valid corrupt mount ---"
tests/test.py << TEST
lfs_format(&lfs, &cfg) => 0;
TEST
rm blocks/0
tests/test.py << TEST
lfs_mount(&lfs, &cfg) => 0;
lfs_unmount(&lfs) => 0;
TEST
echo "--- Results ---"
tests/stats.py