Changed attr_max to be specific to custom attributes

While technically, both system and user attributes share the same disk
limitations, that's not what attr_max represents when considered from
the user's perspective. To the user, attr_max applies only to custom
attributes. This means attr_max should not impact other configurable
limitations, such as inline files, and the ordering should be
reconsidered with what the user finds most important.
This commit is contained in:
Christopher Haster
2018-10-02 18:28:37 -05:00
parent f010d2add1
commit ad96fca18f
2 changed files with 53 additions and 49 deletions

41
lfs.c
View File

@@ -388,18 +388,18 @@ static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock) {
superblock->version = lfs_fromle32(superblock->version);
superblock->block_size = lfs_fromle32(superblock->block_size);
superblock->block_count = lfs_fromle32(superblock->block_count);
superblock->name_max = lfs_fromle32(superblock->name_max);
superblock->inline_max = lfs_fromle32(superblock->inline_max);
superblock->attr_max = lfs_fromle32(superblock->attr_max);
superblock->name_max = lfs_fromle32(superblock->name_max);
}
static inline void lfs_superblock_tole32(lfs_superblock_t *superblock) {
superblock->version = lfs_tole32(superblock->version);
superblock->block_size = lfs_tole32(superblock->block_size);
superblock->block_count = lfs_tole32(superblock->block_count);
superblock->name_max = lfs_tole32(superblock->name_max);
superblock->inline_max = lfs_tole32(superblock->inline_max);
superblock->attr_max = lfs_tole32(superblock->attr_max);
superblock->name_max = lfs_tole32(superblock->name_max);
}
@@ -3054,6 +3054,12 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
}
// check that the size limits are sane
LFS_ASSERT(lfs->cfg->name_max <= LFS_NAME_MAX);
lfs->name_max = lfs->cfg->name_max;
if (!lfs->name_max) {
lfs->name_max = LFS_NAME_MAX;
}
LFS_ASSERT(lfs->cfg->inline_max <= LFS_INLINE_MAX);
LFS_ASSERT(lfs->cfg->inline_max <= lfs->cfg->cache_size);
lfs->inline_max = lfs->cfg->inline_max;
@@ -3067,12 +3073,6 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->attr_max = LFS_ATTR_MAX;
}
LFS_ASSERT(lfs->cfg->name_max <= LFS_NAME_MAX);
lfs->name_max = lfs->cfg->name_max;
if (!lfs->name_max) {
lfs->name_max = LFS_NAME_MAX;
}
// setup default state
lfs->root[0] = 0xffffffff;
lfs->root[1] = 0xffffffff;
@@ -3132,9 +3132,9 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
.block_size = lfs->cfg->block_size,
.block_count = lfs->cfg->block_count,
.attr_max = lfs->attr_max,
.name_max = lfs->name_max,
.inline_max = lfs->inline_max,
.attr_max = lfs->attr_max,
};
lfs_superblock_tole32(&superblock);
@@ -3204,17 +3204,6 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
}
// check superblock configuration
if (superblock.attr_max) {
if (superblock.attr_max > lfs->attr_max) {
LFS_ERROR("Unsupported attr_max (%"PRIu32" > %"PRIu32")",
superblock.attr_max, lfs->attr_max);
err = LFS_ERR_INVAL;
goto cleanup;
}
lfs->attr_max = superblock.attr_max;
}
if (superblock.name_max) {
if (superblock.name_max > lfs->name_max) {
LFS_ERROR("Unsupported name_max (%"PRIu32" > %"PRIu32")",
@@ -3236,6 +3225,18 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
lfs->inline_max = superblock.inline_max;
}
if (superblock.attr_max) {
if (superblock.attr_max > lfs->attr_max) {
LFS_ERROR("Unsupported attr_max (%"PRIu32" > %"PRIu32")",
superblock.attr_max, lfs->attr_max);
err = LFS_ERR_INVAL;
goto cleanup;
}
lfs->attr_max = superblock.attr_max;
}
}
// has globals?

61
lfs.h
View File

@@ -44,29 +44,28 @@ typedef int32_t lfs_soff_t;
typedef uint32_t lfs_block_t;
// Maximum size of all attributes per file in bytes, may be redefined but a
// a smaller LFS_ATTR_MAX has no benefit. Stored in 12-bits and limited
// to <= 0xfff. Stored in superblock and must be respected by other
// littlefs drivers.
#ifndef LFS_ATTR_MAX
#define LFS_ATTR_MAX 0x1ffe
#endif
// Maximum name size in bytes, may be redefined to reduce the size of the
// info struct. Limited to <= LFS_ATTR_MAX. Stored in superblock and must
// be respected by other littlefs drivers.
// info struct. Limited to <= 8190. Stored in superblock and must be
// respected by other littlefs drivers.
#ifndef LFS_NAME_MAX
#define LFS_NAME_MAX 0xff
#endif
// Maximum inline file size in bytes. Large inline files require a larger
// cache size, but if a file can be inline it does not need its own data
// block. Limited to <= LFS_ATTR_MAX and <= cache_size. Stored in superblock
// and must be respected by other littlefs drivers.
// Maximum inline file size in bytes, may be redefined to limit RAM usage,
// but littlefs will automatically limit the LFS_INLINE_MAX to the
// configured cache_size. Limited to <= 8190. Stored in superblock and must
// be respected by other littlefs drivers.
#ifndef LFS_INLINE_MAX
#define LFS_INLINE_MAX 0x1ffe
#endif
// Maximum size of custom attributes in bytes, may be redefined, but there is
// no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 8190. Stored
// in superblock and must be respected by other littlefs drivers.
#ifndef LFS_ATTR_MAX
#define LFS_ATTR_MAX 0x1ffe
#endif
// Possible error codes, these are negative to allow
// valid positive return values
enum lfs_error {
@@ -213,24 +212,25 @@ struct lfs_config {
// lookahead block.
void *lookahead_buffer;
// Optional upper limit on file attributes in bytes. No downside for larger
// attributes size but must be less than LFS_ATTR_MAX. Defaults to
// LFS_ATTR_MAX when zero.Stored in superblock and must be respected by
// other littlefs drivers.
lfs_size_t attr_max;
// 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_max;
// Optional upper limit on inlined files in bytes. Large inline files
// require a larger cache size, but if a file can be inlined it does not
// need its own data block. Must be smaller than cache_size and less than
// LFS_INLINE_MAX. Defaults to min(LFS_INLINE_MAX, read_size) when zero.
// Stored in superblock and must be respected by other littlefs drivers.
// Optional upper limit on inlined files in bytes. Inline files must be
// backed by RAM, but if a file fits in RAM it can be inlined into its
// directory block without needing its own data block. Must be <=
// cache_size and LFS_INLINE_MAX. Defaults to min(LFS_INLINE_MAX,
// cache_size) when zero. Stored in superblock and must be respected by
// other littlefs drivers.
lfs_size_t inline_max;
// Optional upper limit on custom attributes in bytes. No downside for
// larger attributes size but must be <= LFS_ATTR_MAX. Defaults to
// LFS_ATTR_MAX when zero. Stored in superblock and must be respected by
// other littlefs drivers.
lfs_size_t attr_max;
};
// File info structure
@@ -238,10 +238,13 @@ 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
// Size of the file, only valid for REG files. Limited to 32-bits.
lfs_size_t size;
// Name of the file stored as a null-terminated string
// Name of the file stored as a null-terminated string. Limited to
// LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
// reduce RAM. LFS_NAME_MAX is stored in superblock and must be
// respected by other littlefs drivers.
char name[LFS_NAME_MAX+1];
};
@@ -340,9 +343,9 @@ typedef struct lfs_superblock {
lfs_size_t block_size;
lfs_size_t block_count;
lfs_size_t attr_max;
lfs_size_t name_max;
lfs_size_t inline_max;
lfs_size_t attr_max;
} lfs_superblock_t;
// The littlefs filesystem type
@@ -377,9 +380,9 @@ typedef struct lfs {
const struct lfs_config *cfg;
lfs_size_t block_size;
lfs_size_t block_count;
lfs_size_t attr_max;
lfs_size_t name_max;
lfs_size_t inline_max;
lfs_size_t attr_max;
} lfs_t;