Compare commits

..

1 Commits

Author SHA1 Message Date
Christopher Haster
2db5dc80c2 Update copyright notice 2022-03-20 23:03:52 -05:00
13 changed files with 47 additions and 46 deletions

View File

@@ -1,3 +1,4 @@
Copyright (c) 2022, The littlefs authors.
Copyright (c) 2017, Arm Limited. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

14
SPEC.md
View File

@@ -233,19 +233,19 @@ Metadata tag fields:
into a 3-bit abstract type and an 8-bit chunk field. Note that the value
`0x000` is invalid and not assigned a type.
1. **Type1 (3-bits)** - Abstract type of the tag. Groups the tags into
8 categories that facilitate bitmasked lookups.
3. **Type1 (3-bits)** - Abstract type of the tag. Groups the tags into
8 categories that facilitate bitmasked lookups.
2. **Chunk (8-bits)** - Chunk field used for various purposes by the different
abstract types. type1+chunk+id form a unique identifier for each tag in the
metadata block.
4. **Chunk (8-bits)** - Chunk field used for various purposes by the different
abstract types. type1+chunk+id form a unique identifier for each tag in the
metadata block.
3. **Id (10-bits)** - File id associated with the tag. Each file in a metadata
5. **Id (10-bits)** - File id associated with the tag. Each file in a metadata
block gets a unique id which is used to associate tags with that file. The
special value `0x3ff` is used for any tags that are not associated with a
file, such as directory and global metadata.
4. **Length (10-bits)** - Length of the data in bytes. The special value
6. **Length (10-bits)** - Length of the data in bytes. The special value
`0x3ff` indicates that this tag has been deleted.
## Metadata types

View File

@@ -1,6 +1,7 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -80,7 +81,7 @@ int lfs_filebd_read(const struct lfs_config *cfg, lfs_block_t block,
LFS_ASSERT(size % cfg->read_size == 0);
LFS_ASSERT(block < cfg->block_count);
// zero for reproducibility (in case file is truncated)
// zero for reproducability (in case file is truncated)
if (bd->cfg->erase_value != -1) {
memset(buffer, bd->cfg->erase_value, size);
}

View File

@@ -1,6 +1,7 @@
/*
* Block device emulated in a file
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

View File

@@ -1,6 +1,7 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,12 +33,10 @@ int lfs_rambd_createcfg(const struct lfs_config *cfg,
}
}
// zero for reproducibility?
// zero for reproducability?
if (bd->cfg->erase_value != -1) {
memset(bd->buffer, bd->cfg->erase_value,
cfg->block_size * cfg->block_count);
} else {
memset(bd->buffer, 0, cfg->block_size * cfg->block_count);
}
LFS_RAMBD_TRACE("lfs_rambd_createcfg -> %d", 0);

View File

@@ -1,6 +1,7 @@
/*
* Block device emulated in RAM
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

View File

@@ -2,6 +2,7 @@
* Testing block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

View File

@@ -2,6 +2,7 @@
* Testing block device, wraps filebd and rambd while providing a bunch
* of hooks for testing littlefs in various conditions.
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

23
lfs.c
View File

@@ -1,6 +1,7 @@
/*
* The little filesystem
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +12,6 @@
#define LFS_BLOCK_INLINE ((lfs_block_t)-2)
/// Caching block device operations ///
static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) {
// do not zero, cheaper if cache is readonly or only going to be
// written with identical data (during relocates)
@@ -269,26 +269,22 @@ static inline int lfs_pair_cmp(
paira[0] == pairb[1] || paira[1] == pairb[0]);
}
#ifndef LFS_READONLY
static inline bool lfs_pair_sync(
const lfs_block_t paira[2],
const lfs_block_t pairb[2]) {
return (paira[0] == pairb[0] && paira[1] == pairb[1]) ||
(paira[0] == pairb[1] && paira[1] == pairb[0]);
}
#endif
static inline void lfs_pair_fromle32(lfs_block_t pair[2]) {
pair[0] = lfs_fromle32(pair[0]);
pair[1] = lfs_fromle32(pair[1]);
}
#ifndef LFS_READONLY
static inline void lfs_pair_tole32(lfs_block_t pair[2]) {
pair[0] = lfs_tole32(pair[0]);
pair[1] = lfs_tole32(pair[1]);
}
#endif
// operations on 32-bit entry tags
typedef uint32_t lfs_tag_t;
@@ -370,7 +366,6 @@ static inline bool lfs_gstate_iszero(const lfs_gstate_t *a) {
return true;
}
#ifndef LFS_READONLY
static inline bool lfs_gstate_hasorphans(const lfs_gstate_t *a) {
return lfs_tag_size(a->tag);
}
@@ -382,7 +377,6 @@ static inline uint8_t lfs_gstate_getorphans(const lfs_gstate_t *a) {
static inline bool lfs_gstate_hasmove(const lfs_gstate_t *a) {
return lfs_tag_type1(a->tag);
}
#endif
static inline bool lfs_gstate_hasmovehere(const lfs_gstate_t *a,
const lfs_block_t *pair) {
@@ -395,13 +389,11 @@ static inline void lfs_gstate_fromle32(lfs_gstate_t *a) {
a->pair[1] = lfs_fromle32(a->pair[1]);
}
#ifndef LFS_READONLY
static inline void lfs_gstate_tole32(lfs_gstate_t *a) {
a->tag = lfs_tole32(a->tag);
a->pair[0] = lfs_tole32(a->pair[0]);
a->pair[1] = lfs_tole32(a->pair[1]);
}
#endif
// other endianness operations
static void lfs_ctz_fromle32(struct lfs_ctz *ctz) {
@@ -425,7 +417,6 @@ static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock) {
superblock->attr_max = lfs_fromle32(superblock->attr_max);
}
#ifndef LFS_READONLY
static inline void lfs_superblock_tole32(lfs_superblock_t *superblock) {
superblock->version = lfs_tole32(superblock->version);
superblock->block_size = lfs_tole32(superblock->block_size);
@@ -434,7 +425,6 @@ static inline void lfs_superblock_tole32(lfs_superblock_t *superblock) {
superblock->file_max = lfs_tole32(superblock->file_max);
superblock->attr_max = lfs_tole32(superblock->attr_max);
}
#endif
#ifndef LFS_NO_ASSERT
static bool lfs_mlist_isopen(struct lfs_mlist *head,
@@ -1460,7 +1450,7 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) {
}
}
// zero for reproducibility in case initial block is unreadable
// zero for reproducability in case initial block is unreadable
dir->rev = 0;
// rather than clobbering one of the blocks we just pretend
@@ -1520,6 +1510,7 @@ static int lfs_dir_split(lfs_t *lfs,
lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount,
lfs_mdir_t *source, uint16_t split, uint16_t end) {
// create tail directory
lfs_alloc_ack(lfs);
lfs_mdir_t tail;
int err = lfs_dir_alloc(lfs, &tail);
if (err) {
@@ -2740,6 +2731,7 @@ static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) {
}
#endif
#ifndef LFS_READONLY
static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
if (file->flags & LFS_F_READING) {
if (!(file->flags & LFS_F_INLINE)) {
@@ -2748,7 +2740,6 @@ static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) {
file->flags &= ~LFS_F_READING;
}
#ifndef LFS_READONLY
if (file->flags & LFS_F_WRITING) {
lfs_off_t pos = file->pos;
@@ -2815,10 +2806,10 @@ relocate:
file->pos = pos;
}
#endif
return 0;
}
#endif
#ifndef LFS_READONLY
static int lfs_file_rawsync(lfs_t *lfs, lfs_file_t *file) {
@@ -3091,11 +3082,13 @@ static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
return npos;
}
#ifndef LFS_READONLY
// write out everything beforehand, may be noop if rdonly
int err = lfs_file_flush(lfs, file);
if (err) {
return err;
}
#endif
// update pos
file->pos = npos;
@@ -4082,7 +4075,7 @@ static int lfs_fs_relocate(lfs_t *lfs,
lfs_fs_prepmove(lfs, 0x3ff, NULL);
}
// replace bad pair, either we clean up desync, or no desync occurred
// replace bad pair, either we clean up desync, or no desync occured
lfs_pair_tole32(newpair);
err = lfs_dir_commit(lfs, &parent, LFS_MKATTRS(
{LFS_MKTAG_IF(moveid != 0x3ff,

37
lfs.h
View File

@@ -1,6 +1,7 @@
/*
* The little filesystem
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -159,49 +160,49 @@ struct lfs_config {
// information to the block device operations
void *context;
// Read a region in a block. Negative error codes are propagated
// Read a region in a block. Negative error codes are propogated
// to the user.
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 propagated to the user.
// been erased. Negative error codes are propogated to the user.
// 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 propagated to the user.
// are propogated to the user.
// 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 propagated to the user.
// are propogated to the user.
int (*sync)(const struct lfs_config *c);
#ifdef LFS_THREADSAFE
// Lock the underlying block device. Negative error codes
// are propagated to the user.
// are propogated to the user.
int (*lock)(const struct lfs_config *c);
// Unlock the underlying block device. Negative error codes
// are propagated to the user.
// are propogated to the user.
int (*unlock)(const struct lfs_config *c);
#endif
// Minimum size of a block read in bytes. All read operations will be a
// Minimum size of a block read. All read operations will be a
// multiple of this value.
lfs_size_t read_size;
// Minimum size of a block program in bytes. All program operations will be
// a multiple of this value.
// Minimum size of a block program. All program operations will be a
// multiple of this value.
lfs_size_t prog_size;
// Size of an erasable block in bytes. This does not impact ram consumption
// and may be larger than the physical erase size. However, non-inlined
// files take up at minimum one block. Must be a multiple of the read and
// program sizes.
// Size of an erasable block. This does not impact ram consumption and
// may be larger than the physical erase size. However, non-inlined files
// take up at minimum one block. Must be a multiple of the read
// and program sizes.
lfs_size_t block_size;
// Number of erasable blocks on the device.
@@ -215,11 +216,11 @@ struct lfs_config {
// Set to -1 to disable block-level wear-leveling.
int32_t block_cycles;
// Size of block caches in bytes. Each cache buffers a portion of a block in
// RAM. The littlefs needs a read cache, a program cache, and one additional
// Size of block caches. Each cache buffers a portion of a block in RAM.
// The littlefs needs a read cache, a program cache, and one additional
// cache per file. Larger caches can improve performance by storing more
// data and reducing the number of disk accesses. Must be a multiple of the
// read and program sizes, and a factor of the block size.
// data and reducing the number of disk accesses. Must be a multiple of
// the read and program sizes, and a factor of the block size.
lfs_size_t cache_size;
// Size of the lookahead buffer in bytes. A larger lookahead buffer
@@ -485,7 +486,7 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
// Returns the size of the attribute, or a negative error code on failure.
// Note, the returned size is the size of the attribute on disk, irrespective
// of the size of the buffer. This can be used to dynamically allocate a buffer
// or check for existence.
// or check for existance.
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
uint8_t type, void *buffer, lfs_size_t size);

View File

@@ -1,6 +1,7 @@
/*
* lfs util functions
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

View File

@@ -1,6 +1,7 @@
/*
* lfs utility functions
*
* Copyright (c) 2022, The littlefs authors.
* Copyright (c) 2017, Arm Limited. All rights reserved.
* SPDX-License-Identifier: BSD-3-Clause
*/

View File

@@ -565,7 +565,7 @@ class TestSuite:
path=self.path))
mk.write('\n')
# add truly global defines globally
# add truely global defines globally
for k, v in sorted(self.defines.items()):
mk.write('%s.test: override CFLAGS += -D%s=%r\n'
% (self.path, k, v))
@@ -656,7 +656,7 @@ def main(**args):
for path in glob.glob(testpath):
suites.append(TestSuite(path, classes, defines, filter, **args))
# sort for reproducibility
# sort for reproducability
suites = sorted(suites)
# generate permutations