Ver código fonte

Structured some of the bulk of the codebase

- Removed lfs_config.h, distributed between lfs.h and lfs_util.h
- Moved some functions that felt out of place
Christopher Haster 8 anos atrás
pai
commit
5790ec2ce4
5 arquivos alterados com 255 adições e 257 exclusões
  1. 217 212
      lfs.c
  2. 27 8
      lfs.h
  3. 0 33
      lfs_config.h
  4. 2 2
      lfs_util.c
  5. 9 2
      lfs_util.h

+ 217 - 212
lfs.c

@@ -8,7 +8,6 @@
 #include "lfs_util.h"
 
 #include <string.h>
-#include <stdbool.h>
 #include <stdlib.h>
 
 
@@ -1086,6 +1085,43 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
     return lfs_dir_commit(lfs, &cwd, &file->entry, NULL);
 }
 
+lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
+        void *buffer, lfs_size_t size) {
+    uint8_t *data = buffer;
+    size = lfs_min(size, file->entry.d.u.file.size - file->rpos);
+    lfs_size_t nsize = size;
+
+    if ((file->flags & 3) == LFS_O_WRONLY) {
+        return LFS_ERROR_INVALID;
+    }
+
+    while (nsize > 0) {
+        // check if we need a new block
+        if (!file->rblock || file->roff == lfs->cfg->block_size) {
+            int err = lfs_index_find(lfs,
+                    file->entry.d.u.file.head, file->entry.d.u.file.size,
+                    file->rpos, &file->rblock, &file->roff);
+            if (err) {
+                return err;
+            }
+        }
+
+        // read as much as we can in current block
+        lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->roff);
+        int err = lfs_bd_read(lfs, file->rblock, file->roff, diff, data);
+        if (err) {
+            return err;
+        }
+
+        file->rpos += diff;
+        file->roff += diff;
+        data += diff;
+        nsize -= diff;
+    }
+
+    return size;
+}
+
 lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
         const void *buffer, lfs_size_t size) {
     const uint8_t *data = buffer;
@@ -1144,43 +1180,6 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
     return size;
 }
 
-lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
-        void *buffer, lfs_size_t size) {
-    uint8_t *data = buffer;
-    size = lfs_min(size, file->entry.d.u.file.size - file->rpos);
-    lfs_size_t nsize = size;
-
-    if ((file->flags & 3) == LFS_O_WRONLY) {
-        return LFS_ERROR_INVALID;
-    }
-
-    while (nsize > 0) {
-        // check if we need a new block
-        if (!file->rblock || file->roff == lfs->cfg->block_size) {
-            int err = lfs_index_find(lfs,
-                    file->entry.d.u.file.head, file->entry.d.u.file.size,
-                    file->rpos, &file->rblock, &file->roff);
-            if (err) {
-                return err;
-            }
-        }
-
-        // read as much as we can in current block
-        lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->roff);
-        int err = lfs_bd_read(lfs, file->rblock, file->roff, diff, data);
-        if (err) {
-            return err;
-        }
-
-        file->rpos += diff;
-        file->roff += diff;
-        data += diff;
-        nsize -= diff;
-    }
-
-    return size;
-}
-
 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
         lfs_soff_t off, int whence) {
     // write out everything beforehand, may be noop if rdonly
@@ -1215,10 +1214,6 @@ lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
     return prev;
 }
 
-lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
-    return lfs_max(file->wpos, file->entry.d.u.file.size);
-}
-
 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) {
     return file->rpos;
 }
@@ -1232,8 +1227,180 @@ int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file) {
     return 0;
 }
 
+lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
+    return lfs_max(file->wpos, file->entry.d.u.file.size);
+}
+
+
+/// General fs oprations ///
+int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
+    lfs_dir_t cwd;
+    int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
+    if (err) {
+        return err;
+    }
+
+    lfs_entry_t entry;
+    err = lfs_dir_find(lfs, &cwd, &entry, &path);
+    if (err) {
+        return err;
+    }
+
+    // TODO abstract out info assignment
+    memset(info, 0, sizeof(*info));
+    info->type = entry.d.type & 0xff;
+    if (info->type == LFS_TYPE_REG) {
+        info->size = entry.d.u.file.size;
+    }
+
+    err = lfs_bd_read(lfs, cwd.pair[0], entry.off + sizeof(entry.d),
+            entry.d.len - sizeof(entry.d), info->name);
+    if (err) {
+        return err;
+    }
+
+    return 0;
+}
+
+int lfs_remove(lfs_t *lfs, const char *path) {
+    lfs_dir_t cwd;
+    int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
+    if (err) {
+        return err;
+    }
+
+    lfs_entry_t entry;
+    err = lfs_dir_find(lfs, &cwd, &entry, &path);
+    if (err) {
+        return err;
+    }
+
+    lfs_dir_t dir;
+    if (entry.d.type == LFS_TYPE_DIR) {
+        // must be empty before removal, checking size
+        // without masking top bit checks for any case where
+        // dir is not empty
+        int err = lfs_dir_fetch(lfs, &dir, entry.d.u.dir);
+        if (err) {
+            return err;
+        } else if (dir.d.size != sizeof(dir.d)) {
+            return LFS_ERROR_INVALID;
+        }
+    }
+
+    // remove the entry
+    err = lfs_dir_remove(lfs, &cwd, &entry);
+    if (err) {
+        return err;
+    }
+
+    // if we were a directory, just run a deorphan step, this should
+    // collect us, although is expensive
+    if (entry.d.type == LFS_TYPE_DIR) {
+        int err = lfs_deorphan(lfs);
+        if (err) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
+    // find old entry
+    lfs_dir_t oldcwd;
+    int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root);
+    if (err) {
+        return err;
+    }
+
+    lfs_entry_t oldentry;
+    err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
+    if (err) {
+        return err;
+    }
+
+    // allocate new entry
+    lfs_dir_t newcwd;
+    err = lfs_dir_fetch(lfs, &newcwd, lfs->root);
+    if (err) {
+        return err;
+    }
+
+    lfs_entry_t preventry;
+    err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
+    if (err && err != LFS_ERROR_NO_ENTRY) {
+        return err;
+    }
+    bool prevexists = (err != LFS_ERROR_NO_ENTRY);
+
+    // must have same type
+    if (prevexists && preventry.d.type != oldentry.d.type) {
+        return LFS_ERROR_INVALID;
+    }
+
+    lfs_dir_t dir;
+    if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
+        // must be empty before removal, checking size
+        // without masking top bit checks for any case where
+        // dir is not empty
+        int err = lfs_dir_fetch(lfs, &dir, preventry.d.u.dir);
+        if (err) {
+            return err;
+        } else if (dir.d.size != sizeof(dir.d)) {
+            return LFS_ERROR_INVALID;
+        }
+    }
+
+    // move to new location
+    lfs_entry_t newentry = preventry;
+    newentry.d = oldentry.d;
+    newentry.d.len = sizeof(newentry.d) + strlen(newpath);
+
+    if (prevexists) {
+        int err = lfs_dir_commit(lfs, &newcwd, &newentry, newpath);
+        if (err) {
+            return err;
+        }
+    } else {
+        int err = lfs_dir_append(lfs, &newcwd, &newentry, newpath);
+        if (err) {
+            return err;
+        }
+    }
+
+    // fetch again in case newcwd == oldcwd
+    // TODO handle this better?
+    err = lfs_dir_fetch(lfs, &oldcwd, oldcwd.pair);
+    if (err) {
+        return err;
+    }
+
+    err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
+    if (err) {
+        return err;
+    }
+
+    // remove from old location
+    err = lfs_dir_remove(lfs, &oldcwd, &oldentry);
+    if (err) {
+        return err;
+    }
+
+    // if we were a directory, just run a deorphan step, this should
+    // collect us, although is expensive
+    if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
+        int err = lfs_deorphan(lfs);
+        if (err) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
 
-/// Generic filesystem operations ///
+/// Filesystem operations ///
 static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
     lfs->cfg = cfg;
     lfs->words = lfs->cfg->block_size / sizeof(uint32_t);
@@ -1372,6 +1539,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
     if (!err) {
         err = lfs_bd_read(lfs, dir.pair[0],
                 sizeof(dir.d), sizeof(superblock.d), &superblock.d);
+
+        lfs->root[0] = superblock.d.root[0];
+        lfs->root[1] = superblock.d.root[1];
     }
 
     if (err == LFS_ERROR_CORRUPT ||
@@ -1384,11 +1554,9 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
         LFS_ERROR("Invalid version %d.%d\n",
                 0xffff & (superblock.d.version >> 16),
                 0xffff & (superblock.d.version >> 0));
+        return LFS_ERROR_INVALID;
     }
 
-    lfs->root[0] = superblock.d.root[0];
-    lfs->root[1] = superblock.d.root[1];
-
     return err;
 }
 
@@ -1396,6 +1564,8 @@ int lfs_unmount(lfs_t *lfs) {
     return lfs_deinit(lfs);
 }
 
+
+/// Littlefs specific operations ///
 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
     // iterate over metadata pairs
     lfs_dir_t dir;
@@ -1510,7 +1680,7 @@ int lfs_deorphan(lfs_t *lfs) {
 
         if (!parent) {
             // we are an orphan
-            LFS_INFO("Orphan %d %d", pdir.d.tail[0], pdir.d.tail[1]);
+            LFS_DEBUG("Orphan %d %d", pdir.d.tail[0], pdir.d.tail[1]);
 
             pdir.d.tail[0] = cdir.d.tail[0];
             pdir.d.tail[1] = cdir.d.tail[1];
@@ -1529,168 +1699,3 @@ int lfs_deorphan(lfs_t *lfs) {
     return 0;
 }
 
-int lfs_remove(lfs_t *lfs, const char *path) {
-    lfs_dir_t cwd;
-    int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
-    if (err) {
-        return err;
-    }
-
-    lfs_entry_t entry;
-    err = lfs_dir_find(lfs, &cwd, &entry, &path);
-    if (err) {
-        return err;
-    }
-
-    lfs_dir_t dir;
-    if (entry.d.type == LFS_TYPE_DIR) {
-        // must be empty before removal, checking size
-        // without masking top bit checks for any case where
-        // dir is not empty
-        int err = lfs_dir_fetch(lfs, &dir, entry.d.u.dir);
-        if (err) {
-            return err;
-        } else if (dir.d.size != sizeof(dir.d)) {
-            return LFS_ERROR_INVALID;
-        }
-    }
-
-    // remove the entry
-    err = lfs_dir_remove(lfs, &cwd, &entry);
-    if (err) {
-        return err;
-    }
-
-    // if we were a directory, just run a deorphan step, this should
-    // collect us, although is expensive
-    if (entry.d.type == LFS_TYPE_DIR) {
-        int err = lfs_deorphan(lfs);
-        if (err) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
-    // find old entry
-    lfs_dir_t oldcwd;
-    int err = lfs_dir_fetch(lfs, &oldcwd, lfs->root);
-    if (err) {
-        return err;
-    }
-
-    lfs_entry_t oldentry;
-    err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
-    if (err) {
-        return err;
-    }
-
-    // allocate new entry
-    lfs_dir_t newcwd;
-    err = lfs_dir_fetch(lfs, &newcwd, lfs->root);
-    if (err) {
-        return err;
-    }
-
-    lfs_entry_t preventry;
-    err = lfs_dir_find(lfs, &newcwd, &preventry, &newpath);
-    if (err && err != LFS_ERROR_NO_ENTRY) {
-        return err;
-    }
-    bool prevexists = (err != LFS_ERROR_NO_ENTRY);
-
-    // must have same type
-    if (prevexists && preventry.d.type != oldentry.d.type) {
-        return LFS_ERROR_INVALID;
-    }
-
-    lfs_dir_t dir;
-    if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
-        // must be empty before removal, checking size
-        // without masking top bit checks for any case where
-        // dir is not empty
-        int err = lfs_dir_fetch(lfs, &dir, preventry.d.u.dir);
-        if (err) {
-            return err;
-        } else if (dir.d.size != sizeof(dir.d)) {
-            return LFS_ERROR_INVALID;
-        }
-    }
-
-    // move to new location
-    lfs_entry_t newentry = preventry;
-    newentry.d = oldentry.d;
-    newentry.d.len = sizeof(newentry.d) + strlen(newpath);
-
-    if (prevexists) {
-        int err = lfs_dir_commit(lfs, &newcwd, &newentry, newpath);
-        if (err) {
-            return err;
-        }
-    } else {
-        int err = lfs_dir_append(lfs, &newcwd, &newentry, newpath);
-        if (err) {
-            return err;
-        }
-    }
-
-    // fetch again in case newcwd == oldcwd
-    // TODO handle this better?
-    err = lfs_dir_fetch(lfs, &oldcwd, oldcwd.pair);
-    if (err) {
-        return err;
-    }
-
-    err = lfs_dir_find(lfs, &oldcwd, &oldentry, &oldpath);
-    if (err) {
-        return err;
-    }
-
-    // remove from old location
-    err = lfs_dir_remove(lfs, &oldcwd, &oldentry);
-    if (err) {
-        return err;
-    }
-
-    // if we were a directory, just run a deorphan step, this should
-    // collect us, although is expensive
-    if (prevexists && preventry.d.type == LFS_TYPE_DIR) {
-        int err = lfs_deorphan(lfs);
-        if (err) {
-            return err;
-        }
-    }
-
-    return 0;
-}
-
-int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
-    lfs_dir_t cwd;
-    int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
-    if (err) {
-        return err;
-    }
-
-    lfs_entry_t entry;
-    err = lfs_dir_find(lfs, &cwd, &entry, &path);
-    if (err) {
-        return err;
-    }
-
-    // TODO abstract out info assignment
-    memset(info, 0, sizeof(*info));
-    info->type = entry.d.type & 0xff;
-    if (info->type == LFS_TYPE_REG) {
-        info->size = entry.d.u.file.size;
-    }
-
-    err = lfs_bd_read(lfs, cwd.pair[0], entry.off + sizeof(entry.d),
-            entry.d.len - sizeof(entry.d), info->name);
-    if (err) {
-        return err;
-    }
-
-    return 0;
-}

+ 27 - 8
lfs.h

@@ -7,9 +7,25 @@
 #ifndef LFS_H
 #define LFS_H
 
-#include "lfs_config.h"
+#include <stdint.h>
+#include <stdbool.h>
 
 
+// Type definitions
+typedef uint32_t lfs_size_t;
+typedef uint32_t lfs_off_t;
+
+typedef int32_t  lfs_ssize_t;
+typedef int32_t  lfs_soff_t;
+
+typedef uint32_t lfs_block_t;
+
+
+// Configurable littlefs constants
+#ifndef LFS_NAME_MAX
+#define LFS_NAME_MAX 255
+#endif
+
 // The littefs constants
 enum lfs_error {
     LFS_ERROR_OK       = 0,
@@ -109,7 +125,7 @@ struct lfs_info {
 };
 
 
-// Internal data structures
+// littlefs data structures
 typedef struct lfs_entry {
     lfs_block_t pair[2];
     lfs_off_t off;
@@ -169,8 +185,7 @@ typedef struct lfs_superblock {
     } d;
 } lfs_superblock_t;
 
-
-// Little filesystem type
+// littlefs type
 typedef struct lfs {
     const struct lfs_config *cfg;
     lfs_size_t words;       // number of 32-bit words that can fit in a block
@@ -191,15 +206,17 @@ typedef struct lfs {
 } lfs_t;
 
 
-// Functions
+// filesystem functions
 int lfs_format(lfs_t *lfs, const struct lfs_config *config);
 int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
 int lfs_unmount(lfs_t *lfs);
 
+// general operations
 int lfs_remove(lfs_t *lfs, const char *path);
 int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
 int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
 
+// directory operations
 int lfs_mkdir(lfs_t *lfs, const char *path);
 int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
 int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
@@ -208,20 +225,22 @@ int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
 lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
 int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
 
+// file operations
 int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
         const char *path, int flags);
 int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
 int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
-lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
-        const void *buffer, lfs_size_t size);
 lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
         void *buffer, lfs_size_t size);
+lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
+        const void *buffer, lfs_size_t size);
 lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
         lfs_soff_t off, int whence);
-lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
 lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
 int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
+lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
 
+// miscellaneous lfs specific operations
 int lfs_deorphan(lfs_t *lfs);
 int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
 

+ 0 - 33
lfs_config.h

@@ -1,33 +0,0 @@
-/*
- * Configuration and type definitions
- *
- * Copyright (c) 2017 Christopher Haster
- * Distributed under the MIT license
- */
-#ifndef LFS_CONFIG_H
-#define LFS_CONFIG_H
-
-#include <stdint.h>
-
-// Type definitions
-typedef uint32_t lfs_size_t;
-typedef uint32_t lfs_off_t;
-
-typedef int32_t  lfs_ssize_t;
-typedef int32_t  lfs_soff_t;
-
-typedef uint32_t lfs_block_t;
-
-// Maximum length of file name
-#ifndef LFS_NAME_MAX
-#define LFS_NAME_MAX 255
-#endif
-
-// Logging operations
-#include <stdio.h>
-#define LFS_ERROR(fmt, ...) printf("lfs error: " fmt "\n", __VA_ARGS__)
-#define LFS_WARN(fmt, ...)  printf("lfs warn: " fmt "\n", __VA_ARGS__)
-#define LFS_INFO(fmt, ...)  printf("lfs info: " fmt "\n", __VA_ARGS__)
-
-
-#endif

+ 2 - 2
lfs_util.c

@@ -7,7 +7,7 @@
 #include "lfs_util.h"
 
 
-uint32_t lfs_crc(uint32_t crc, lfs_size_t size, const void *buffer) {
+uint32_t lfs_crc(uint32_t crc, size_t size, const void *buffer) {
     static const uint32_t rtable[16] = {
         0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
         0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
@@ -17,7 +17,7 @@ uint32_t lfs_crc(uint32_t crc, lfs_size_t size, const void *buffer) {
 
     const uint8_t *data = buffer;
 
-    for (lfs_size_t i = 0; i < size; i++) {
+    for (size_t i = 0; i < size; i++) {
         crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf];
         crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf];
     }

+ 9 - 2
lfs_util.h

@@ -7,8 +7,9 @@
 #ifndef LFS_UTIL_H
 #define LFS_UTIL_H
 
-#include "lfs_config.h"
 #include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
 
 
 // Builtin functions
@@ -32,7 +33,13 @@ static inline int lfs_scmp(uint32_t a, uint32_t b) {
     return (int)(unsigned)(a - b);
 }
 
-uint32_t lfs_crc(uint32_t crc, lfs_size_t size, const void *buffer);
+uint32_t lfs_crc(uint32_t crc, size_t size, const void *buffer);
+
+
+// Logging functions
+#define LFS_DEBUG(fmt, ...) printf("lfs debug: " fmt "\n", __VA_ARGS__)
+#define LFS_WARN(fmt, ...)  printf("lfs warn: " fmt "\n", __VA_ARGS__)
+#define LFS_ERROR(fmt, ...) printf("lfs error: " fmt "\n", __VA_ARGS__)
 
 
 #endif