Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/littlefs-project/littlefs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/emubd
diff options
context:
space:
mode:
authorChristopher Haster <chaster@utexas.edu>2017-04-22 19:42:05 +0300
committerChristopher Haster <chaster@utexas.edu>2017-04-22 23:42:05 +0300
commit789286a25748649f46afebec6566d00763a0074e (patch)
treeec3970bd33da5077944f0c30736cfa8276b22b5e /emubd
parent3b9d6630c8fab475307d95824c368d45cd6ba41a (diff)
Simplified config
Before, the lfs had multiple paths to determine config options: - lfs_config struct passed during initialization - lfs_bd_info struct passed during block device initialization - compile time options This allowed different developers to provide their own needs to the filesystem, such as the block device capabilities and the higher level user's own tweaks. However, this comes with additional complexity and action required when the configurations are incompatible. For now, this has been reduced to all information (including block device function pointers) being passed through the lfs_config struct. We just defer more complicated handling of configuration options to the top level user. This simplifies configuration handling and gives the top level user the responsibility to handle configuration, which they probably would have wanted to do anyways.
Diffstat (limited to 'emubd')
-rw-r--r--emubd/lfs_emubd.c218
-rw-r--r--emubd/lfs_emubd.h51
2 files changed, 95 insertions, 174 deletions
diff --git a/emubd/lfs_emubd.c b/emubd/lfs_emubd.c
index 7acd8f7..f1381cf 100644
--- a/emubd/lfs_emubd.c
+++ b/emubd/lfs_emubd.c
@@ -19,9 +19,12 @@
// Block device emulated on existing filesystem
-int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
- memset(&emu->info, 0, sizeof(emu->info));
- memset(&emu->stats, 0, sizeof(emu->stats));
+int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
+ lfs_emubd_t *emu = cfg->context;
+ emu->cfg.read_size = cfg->read_size;
+ emu->cfg.prog_size = cfg->prog_size;
+ emu->cfg.block_size = cfg->block_size;
+ emu->cfg.block_count = cfg->block_count;
// Allocate buffer for creating children files
size_t pathlen = strlen(path);
@@ -41,12 +44,6 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
return -errno;
}
- // Setup info based on configuration
- emu->info.read_size = LFS_EMUBD_READ_SIZE;
- emu->info.prog_size = LFS_EMUBD_PROG_SIZE;
- emu->info.erase_size = LFS_EMUBD_ERASE_SIZE;
- emu->info.total_size = LFS_EMUBD_TOTAL_SIZE;
-
// Load stats to continue incrementing
snprintf(emu->child, LFS_NAME_MAX, "stats");
FILE *f = fopen(emu->path, "r");
@@ -67,153 +64,131 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
return 0;
}
-void lfs_emubd_destroy(lfs_emubd_t *emu) {
- lfs_emubd_sync(emu);
+void lfs_emubd_destroy(const struct lfs_config *cfg) {
+ lfs_emubd_sync(cfg);
+ lfs_emubd_t *emu = cfg->context;
free(emu->path);
}
-int lfs_emubd_read(lfs_emubd_t *emu, lfs_block_t block,
+int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, lfs_size_t size, void *buffer) {
+ lfs_emubd_t *emu = cfg->context;
uint8_t *data = buffer;
// Check if read is valid
- assert(off % emu->info.read_size == 0);
- assert(size % emu->info.read_size == 0);
- assert((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size);
+ assert(off % cfg->read_size == 0);
+ assert(size % cfg->read_size == 0);
+ assert(block < cfg->block_count);
// Zero out buffer for debugging
memset(data, 0, size);
- // Iterate over blocks until enough data is read
- while (size > 0) {
- snprintf(emu->child, LFS_NAME_MAX, "%x", block);
- size_t count = lfs_min(emu->info.erase_size - off, size);
+ // Read data
+ snprintf(emu->child, LFS_NAME_MAX, "%x", block);
+
+ FILE *f = fopen(emu->path, "rb");
+ if (!f && errno != ENOENT) {
+ return -errno;
+ }
- FILE *f = fopen(emu->path, "rb");
- if (!f && errno != ENOENT) {
+ if (f) {
+ int err = fseek(f, off, SEEK_SET);
+ if (err) {
return -errno;
}
- if (f) {
- int err = fseek(f, off, SEEK_SET);
- if (err) {
- return -errno;
- }
-
- size_t res = fread(data, 1, count, f);
- if (res < count && !feof(f)) {
- return -errno;
- }
-
- err = fclose(f);
- if (err) {
- return -errno;
- }
+ size_t res = fread(data, 1, size, f);
+ if (res < size && !feof(f)) {
+ return -errno;
}
- size -= count;
- data += count;
- block += 1;
- off = 0;
+ err = fclose(f);
+ if (err) {
+ return -errno;
+ }
}
emu->stats.read_count += 1;
return 0;
}
-int lfs_emubd_prog(lfs_emubd_t *emu, lfs_block_t block,
+int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, lfs_size_t size, const void *buffer) {
+ lfs_emubd_t *emu = cfg->context;
const uint8_t *data = buffer;
// Check if write is valid
- assert(off % emu->info.prog_size == 0);
- assert(size % emu->info.prog_size == 0);
- assert((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size);
-
- // Iterate over blocks until enough data is read
- while (size > 0) {
- snprintf(emu->child, LFS_NAME_MAX, "%x", block);
- size_t count = lfs_min(emu->info.erase_size - off, size);
-
- FILE *f = fopen(emu->path, "r+b");
- if (!f && errno == ENOENT) {
- f = fopen(emu->path, "w+b");
- if (!f) {
- return -errno;
- }
- }
+ assert(off % cfg->prog_size == 0);
+ assert(size % cfg->prog_size == 0);
+ assert(block < cfg->block_count);
- int err = fseek(f, off, SEEK_SET);
- if (err) {
- return -errno;
- }
+ // Program data
+ snprintf(emu->child, LFS_NAME_MAX, "%x", block);
- size_t res = fwrite(data, 1, count, f);
- if (res < count) {
+ FILE *f = fopen(emu->path, "r+b");
+ if (!f && errno == ENOENT) {
+ f = fopen(emu->path, "w+b");
+ if (!f) {
return -errno;
}
+ }
- err = fclose(f);
- if (err) {
- return -errno;
- }
+ int err = fseek(f, off, SEEK_SET);
+ if (err) {
+ return -errno;
+ }
+
+ size_t res = fwrite(data, 1, size, f);
+ if (res < size) {
+ return -errno;
+ }
- size -= count;
- data += count;
- block += 1;
- off = 0;
+ err = fclose(f);
+ if (err) {
+ return -errno;
}
emu->stats.prog_count += 1;
return 0;
}
-int lfs_emubd_erase(lfs_emubd_t *emu, lfs_block_t block,
- lfs_off_t off, lfs_size_t size) {
+int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) {
+ lfs_emubd_t *emu = cfg->context;
// Check if erase is valid
- assert(off % emu->info.erase_size == 0);
- assert(size % emu->info.erase_size == 0);
- assert((uint64_t)block*emu->info.erase_size + off + size
- < emu->info.total_size);
-
- // Iterate and erase blocks
- while (size > 0) {
- snprintf(emu->child, LFS_NAME_MAX, "%x", block);
- struct stat st;
- int err = stat(emu->path, &st);
- if (err && errno != ENOENT) {
- return -errno;
- }
+ assert(block < cfg->block_count);
- if (!err && S_ISREG(st.st_mode)) {
- int err = unlink(emu->path);
- if (err) {
- return -errno;
- }
- }
+ // Erase the block
+ snprintf(emu->child, LFS_NAME_MAX, "%x", block);
+ struct stat st;
+ int err = stat(emu->path, &st);
+ if (err && errno != ENOENT) {
+ return -errno;
+ }
- size -= emu->info.erase_size;
- block += 1;
- off = 0;
+ if (!err && S_ISREG(st.st_mode)) {
+ int err = unlink(emu->path);
+ if (err) {
+ return -errno;
+ }
}
emu->stats.erase_count += 1;
return 0;
}
-int lfs_emubd_sync(lfs_emubd_t *emu) {
+int lfs_emubd_sync(const struct lfs_config *cfg) {
+ lfs_emubd_t *emu = cfg->context;
+
// Just write out info/stats for later lookup
- snprintf(emu->child, LFS_NAME_MAX, "info");
+ snprintf(emu->child, LFS_NAME_MAX, "config");
FILE *f = fopen(emu->path, "w");
if (!f) {
return -errno;
}
- size_t res = fwrite(&emu->info, sizeof(emu->info), 1, f);
+ size_t res = fwrite(&emu->cfg, sizeof(emu->cfg), 1, f);
if (res < 1) {
return -errno;
}
@@ -242,46 +217,3 @@ int lfs_emubd_sync(lfs_emubd_t *emu) {
return 0;
}
-int lfs_emubd_info(lfs_emubd_t *emu, struct lfs_bd_info *info) {
- *info = emu->info;
- return 0;
-}
-
-int lfs_emubd_stats(lfs_emubd_t *emu, struct lfs_bd_stats *stats) {
- *stats = emu->stats;
- return 0;
-}
-
-
-// Wrappers for void*s
-static int lfs_emubd_bd_read(void *bd, lfs_block_t block,
- lfs_off_t off, lfs_size_t size, void *buffer) {
- return lfs_emubd_read((lfs_emubd_t*)bd, block, off, size, buffer);
-}
-
-static int lfs_emubd_bd_prog(void *bd, lfs_block_t block,
- lfs_off_t off, lfs_size_t size, const void *buffer) {
- return lfs_emubd_prog((lfs_emubd_t*)bd, block, off, size, buffer);
-}
-
-static int lfs_emubd_bd_erase(void *bd, lfs_block_t block,
- lfs_off_t off, lfs_size_t size) {
- return lfs_emubd_erase((lfs_emubd_t*)bd, block, off, size);
-}
-
-static int lfs_emubd_bd_sync(void *bd) {
- return lfs_emubd_sync((lfs_emubd_t*)bd);
-}
-
-static int lfs_emubd_bd_info(void *bd, struct lfs_bd_info *info) {
- return lfs_emubd_info((lfs_emubd_t*)bd, info);
-}
-
-const struct lfs_bd_ops lfs_emubd_ops = {
- .read = lfs_emubd_bd_read,
- .prog = lfs_emubd_bd_prog,
- .erase = lfs_emubd_bd_erase,
- .sync = lfs_emubd_bd_sync,
- .info = lfs_emubd_bd_info,
-};
-
diff --git a/emubd/lfs_emubd.h b/emubd/lfs_emubd.h
index 89ee4ce..838dbd2 100644
--- a/emubd/lfs_emubd.h
+++ b/emubd/lfs_emubd.h
@@ -7,9 +7,8 @@
#ifndef LFS_EMUBD_H
#define LFS_EMUBD_H
-#include "lfs_config.h"
+#include "lfs.h"
#include "lfs_util.h"
-#include "lfs_bd.h"
// Config options
@@ -30,60 +29,50 @@
#endif
-// Stats for debugging and optimization
-struct lfs_bd_stats {
- uint64_t read_count;
- uint64_t prog_count;
- uint64_t erase_count;
-};
-
// The emu bd state
typedef struct lfs_emubd {
char *path;
char *child;
- struct lfs_bd_info info;
- struct lfs_bd_stats stats;
+
+ struct {
+ uint64_t read_count;
+ uint64_t prog_count;
+ uint64_t erase_count;
+ } stats;
+
+ struct {
+ uint32_t read_size;
+ uint32_t prog_size;
+ uint32_t block_size;
+ uint32_t block_count;
+ } cfg;
} lfs_emubd_t;
// Create a block device using path for the directory to store blocks
-int lfs_emubd_create(lfs_emubd_t *emu, const char *path);
+int lfs_emubd_create(const struct lfs_config *cfg, const char *path);
// Clean up memory associated with emu block device
-void lfs_emubd_destroy(lfs_emubd_t *emu);
+void lfs_emubd_destroy(const struct lfs_config *cfg);
// Read a block
-int lfs_emubd_read(lfs_emubd_t *bd, lfs_block_t block,
+int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, lfs_size_t size, void *buffer);
// Program a block
//
// The block must have previously been erased.
-int lfs_emubd_prog(lfs_emubd_t *bd, lfs_block_t block,
+int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
lfs_off_t off, lfs_size_t size, const void *buffer);
// Erase a block
//
// A block must be erased before being programmed. The
// state of an erased block is undefined.
-int lfs_emubd_erase(lfs_emubd_t *bd, lfs_block_t block,
- lfs_off_t off, lfs_size_t size);
+int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block);
// Sync the block device
-int lfs_emubd_sync(lfs_emubd_t *bd);
-
-// Get a description of the block device
-//
-// Any unknown information may be left unmodified
-int lfs_emubd_info(lfs_emubd_t *bd, struct lfs_bd_info *info);
-
-// Get stats of operations on the block device
-//
-// Used for debugging and optimizations
-int lfs_emubd_stats(lfs_emubd_t *bd, struct lfs_bd_stats *stats);
-
-// Block device operations
-extern const struct lfs_bd_ops lfs_emubd_ops;
+int lfs_emubd_sync(const struct lfs_config *cfg);
#endif