Browse Source

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.
Christopher Haster 7 years ago
parent
commit
ad96fca18f
2 changed files with 53 additions and 49 deletions
  1. 21 20
      lfs.c
  2. 32 29
      lfs.h

+ 21 - 20
lfs.c

@@ -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?

+ 32 - 29
lfs.h

@@ -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;