Skip to content

Commit 789286a

Browse files
committed
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.
1 parent 3b9d663 commit 789286a

File tree

13 files changed

+249
-411
lines changed

13 files changed

+249
-411
lines changed

emubd/lfs_emubd.c

Lines changed: 75 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919

2020

2121
// Block device emulated on existing filesystem
22-
int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
23-
memset(&emu->info, 0, sizeof(emu->info));
24-
memset(&emu->stats, 0, sizeof(emu->stats));
22+
int lfs_emubd_create(const struct lfs_config *cfg, const char *path) {
23+
lfs_emubd_t *emu = cfg->context;
24+
emu->cfg.read_size = cfg->read_size;
25+
emu->cfg.prog_size = cfg->prog_size;
26+
emu->cfg.block_size = cfg->block_size;
27+
emu->cfg.block_count = cfg->block_count;
2528

2629
// Allocate buffer for creating children files
2730
size_t pathlen = strlen(path);
@@ -41,12 +44,6 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
4144
return -errno;
4245
}
4346

44-
// Setup info based on configuration
45-
emu->info.read_size = LFS_EMUBD_READ_SIZE;
46-
emu->info.prog_size = LFS_EMUBD_PROG_SIZE;
47-
emu->info.erase_size = LFS_EMUBD_ERASE_SIZE;
48-
emu->info.total_size = LFS_EMUBD_TOTAL_SIZE;
49-
5047
// Load stats to continue incrementing
5148
snprintf(emu->child, LFS_NAME_MAX, "stats");
5249
FILE *f = fopen(emu->path, "r");
@@ -67,153 +64,131 @@ int lfs_emubd_create(lfs_emubd_t *emu, const char *path) {
6764
return 0;
6865
}
6966

70-
void lfs_emubd_destroy(lfs_emubd_t *emu) {
71-
lfs_emubd_sync(emu);
67+
void lfs_emubd_destroy(const struct lfs_config *cfg) {
68+
lfs_emubd_sync(cfg);
7269

70+
lfs_emubd_t *emu = cfg->context;
7371
free(emu->path);
7472
}
7573

76-
int lfs_emubd_read(lfs_emubd_t *emu, lfs_block_t block,
74+
int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
7775
lfs_off_t off, lfs_size_t size, void *buffer) {
76+
lfs_emubd_t *emu = cfg->context;
7877
uint8_t *data = buffer;
7978

8079
// Check if read is valid
81-
assert(off % emu->info.read_size == 0);
82-
assert(size % emu->info.read_size == 0);
83-
assert((uint64_t)block*emu->info.erase_size + off + size
84-
< emu->info.total_size);
80+
assert(off % cfg->read_size == 0);
81+
assert(size % cfg->read_size == 0);
82+
assert(block < cfg->block_count);
8583

8684
// Zero out buffer for debugging
8785
memset(data, 0, size);
8886

89-
// Iterate over blocks until enough data is read
90-
while (size > 0) {
91-
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
92-
size_t count = lfs_min(emu->info.erase_size - off, size);
87+
// Read data
88+
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
89+
90+
FILE *f = fopen(emu->path, "rb");
91+
if (!f && errno != ENOENT) {
92+
return -errno;
93+
}
9394

94-
FILE *f = fopen(emu->path, "rb");
95-
if (!f && errno != ENOENT) {
95+
if (f) {
96+
int err = fseek(f, off, SEEK_SET);
97+
if (err) {
9698
return -errno;
9799
}
98100

99-
if (f) {
100-
int err = fseek(f, off, SEEK_SET);
101-
if (err) {
102-
return -errno;
103-
}
104-
105-
size_t res = fread(data, 1, count, f);
106-
if (res < count && !feof(f)) {
107-
return -errno;
108-
}
109-
110-
err = fclose(f);
111-
if (err) {
112-
return -errno;
113-
}
101+
size_t res = fread(data, 1, size, f);
102+
if (res < size && !feof(f)) {
103+
return -errno;
114104
}
115105

116-
size -= count;
117-
data += count;
118-
block += 1;
119-
off = 0;
106+
err = fclose(f);
107+
if (err) {
108+
return -errno;
109+
}
120110
}
121111

122112
emu->stats.read_count += 1;
123113
return 0;
124114
}
125115

126-
int lfs_emubd_prog(lfs_emubd_t *emu, lfs_block_t block,
116+
int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
127117
lfs_off_t off, lfs_size_t size, const void *buffer) {
118+
lfs_emubd_t *emu = cfg->context;
128119
const uint8_t *data = buffer;
129120

130121
// Check if write is valid
131-
assert(off % emu->info.prog_size == 0);
132-
assert(size % emu->info.prog_size == 0);
133-
assert((uint64_t)block*emu->info.erase_size + off + size
134-
< emu->info.total_size);
135-
136-
// Iterate over blocks until enough data is read
137-
while (size > 0) {
138-
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
139-
size_t count = lfs_min(emu->info.erase_size - off, size);
140-
141-
FILE *f = fopen(emu->path, "r+b");
142-
if (!f && errno == ENOENT) {
143-
f = fopen(emu->path, "w+b");
144-
if (!f) {
145-
return -errno;
146-
}
147-
}
122+
assert(off % cfg->prog_size == 0);
123+
assert(size % cfg->prog_size == 0);
124+
assert(block < cfg->block_count);
148125

149-
int err = fseek(f, off, SEEK_SET);
150-
if (err) {
151-
return -errno;
152-
}
126+
// Program data
127+
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
153128

154-
size_t res = fwrite(data, 1, count, f);
155-
if (res < count) {
129+
FILE *f = fopen(emu->path, "r+b");
130+
if (!f && errno == ENOENT) {
131+
f = fopen(emu->path, "w+b");
132+
if (!f) {
156133
return -errno;
157134
}
135+
}
158136

159-
err = fclose(f);
160-
if (err) {
161-
return -errno;
162-
}
137+
int err = fseek(f, off, SEEK_SET);
138+
if (err) {
139+
return -errno;
140+
}
141+
142+
size_t res = fwrite(data, 1, size, f);
143+
if (res < size) {
144+
return -errno;
145+
}
163146

164-
size -= count;
165-
data += count;
166-
block += 1;
167-
off = 0;
147+
err = fclose(f);
148+
if (err) {
149+
return -errno;
168150
}
169151

170152
emu->stats.prog_count += 1;
171153
return 0;
172154
}
173155

174-
int lfs_emubd_erase(lfs_emubd_t *emu, lfs_block_t block,
175-
lfs_off_t off, lfs_size_t size) {
156+
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block) {
157+
lfs_emubd_t *emu = cfg->context;
176158

177159
// Check if erase is valid
178-
assert(off % emu->info.erase_size == 0);
179-
assert(size % emu->info.erase_size == 0);
180-
assert((uint64_t)block*emu->info.erase_size + off + size
181-
< emu->info.total_size);
182-
183-
// Iterate and erase blocks
184-
while (size > 0) {
185-
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
186-
struct stat st;
187-
int err = stat(emu->path, &st);
188-
if (err && errno != ENOENT) {
189-
return -errno;
190-
}
160+
assert(block < cfg->block_count);
191161

192-
if (!err && S_ISREG(st.st_mode)) {
193-
int err = unlink(emu->path);
194-
if (err) {
195-
return -errno;
196-
}
197-
}
162+
// Erase the block
163+
snprintf(emu->child, LFS_NAME_MAX, "%x", block);
164+
struct stat st;
165+
int err = stat(emu->path, &st);
166+
if (err && errno != ENOENT) {
167+
return -errno;
168+
}
198169

199-
size -= emu->info.erase_size;
200-
block += 1;
201-
off = 0;
170+
if (!err && S_ISREG(st.st_mode)) {
171+
int err = unlink(emu->path);
172+
if (err) {
173+
return -errno;
174+
}
202175
}
203176

204177
emu->stats.erase_count += 1;
205178
return 0;
206179
}
207180

208-
int lfs_emubd_sync(lfs_emubd_t *emu) {
181+
int lfs_emubd_sync(const struct lfs_config *cfg) {
182+
lfs_emubd_t *emu = cfg->context;
183+
209184
// Just write out info/stats for later lookup
210-
snprintf(emu->child, LFS_NAME_MAX, "info");
185+
snprintf(emu->child, LFS_NAME_MAX, "config");
211186
FILE *f = fopen(emu->path, "w");
212187
if (!f) {
213188
return -errno;
214189
}
215190

216-
size_t res = fwrite(&emu->info, sizeof(emu->info), 1, f);
191+
size_t res = fwrite(&emu->cfg, sizeof(emu->cfg), 1, f);
217192
if (res < 1) {
218193
return -errno;
219194
}
@@ -242,46 +217,3 @@ int lfs_emubd_sync(lfs_emubd_t *emu) {
242217
return 0;
243218
}
244219

245-
int lfs_emubd_info(lfs_emubd_t *emu, struct lfs_bd_info *info) {
246-
*info = emu->info;
247-
return 0;
248-
}
249-
250-
int lfs_emubd_stats(lfs_emubd_t *emu, struct lfs_bd_stats *stats) {
251-
*stats = emu->stats;
252-
return 0;
253-
}
254-
255-
256-
// Wrappers for void*s
257-
static int lfs_emubd_bd_read(void *bd, lfs_block_t block,
258-
lfs_off_t off, lfs_size_t size, void *buffer) {
259-
return lfs_emubd_read((lfs_emubd_t*)bd, block, off, size, buffer);
260-
}
261-
262-
static int lfs_emubd_bd_prog(void *bd, lfs_block_t block,
263-
lfs_off_t off, lfs_size_t size, const void *buffer) {
264-
return lfs_emubd_prog((lfs_emubd_t*)bd, block, off, size, buffer);
265-
}
266-
267-
static int lfs_emubd_bd_erase(void *bd, lfs_block_t block,
268-
lfs_off_t off, lfs_size_t size) {
269-
return lfs_emubd_erase((lfs_emubd_t*)bd, block, off, size);
270-
}
271-
272-
static int lfs_emubd_bd_sync(void *bd) {
273-
return lfs_emubd_sync((lfs_emubd_t*)bd);
274-
}
275-
276-
static int lfs_emubd_bd_info(void *bd, struct lfs_bd_info *info) {
277-
return lfs_emubd_info((lfs_emubd_t*)bd, info);
278-
}
279-
280-
const struct lfs_bd_ops lfs_emubd_ops = {
281-
.read = lfs_emubd_bd_read,
282-
.prog = lfs_emubd_bd_prog,
283-
.erase = lfs_emubd_bd_erase,
284-
.sync = lfs_emubd_bd_sync,
285-
.info = lfs_emubd_bd_info,
286-
};
287-

emubd/lfs_emubd.h

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
#ifndef LFS_EMUBD_H
88
#define LFS_EMUBD_H
99

10-
#include "lfs_config.h"
10+
#include "lfs.h"
1111
#include "lfs_util.h"
12-
#include "lfs_bd.h"
1312

1413

1514
// Config options
@@ -30,60 +29,50 @@
3029
#endif
3130

3231

33-
// Stats for debugging and optimization
34-
struct lfs_bd_stats {
35-
uint64_t read_count;
36-
uint64_t prog_count;
37-
uint64_t erase_count;
38-
};
39-
4032
// The emu bd state
4133
typedef struct lfs_emubd {
4234
char *path;
4335
char *child;
44-
struct lfs_bd_info info;
45-
struct lfs_bd_stats stats;
36+
37+
struct {
38+
uint64_t read_count;
39+
uint64_t prog_count;
40+
uint64_t erase_count;
41+
} stats;
42+
43+
struct {
44+
uint32_t read_size;
45+
uint32_t prog_size;
46+
uint32_t block_size;
47+
uint32_t block_count;
48+
} cfg;
4649
} lfs_emubd_t;
4750

4851

4952
// Create a block device using path for the directory to store blocks
50-
int lfs_emubd_create(lfs_emubd_t *emu, const char *path);
53+
int lfs_emubd_create(const struct lfs_config *cfg, const char *path);
5154

5255
// Clean up memory associated with emu block device
53-
void lfs_emubd_destroy(lfs_emubd_t *emu);
56+
void lfs_emubd_destroy(const struct lfs_config *cfg);
5457

5558
// Read a block
56-
int lfs_emubd_read(lfs_emubd_t *bd, lfs_block_t block,
59+
int lfs_emubd_read(const struct lfs_config *cfg, lfs_block_t block,
5760
lfs_off_t off, lfs_size_t size, void *buffer);
5861

5962
// Program a block
6063
//
6164
// The block must have previously been erased.
62-
int lfs_emubd_prog(lfs_emubd_t *bd, lfs_block_t block,
65+
int lfs_emubd_prog(const struct lfs_config *cfg, lfs_block_t block,
6366
lfs_off_t off, lfs_size_t size, const void *buffer);
6467

6568
// Erase a block
6669
//
6770
// A block must be erased before being programmed. The
6871
// state of an erased block is undefined.
69-
int lfs_emubd_erase(lfs_emubd_t *bd, lfs_block_t block,
70-
lfs_off_t off, lfs_size_t size);
72+
int lfs_emubd_erase(const struct lfs_config *cfg, lfs_block_t block);
7173

7274
// Sync the block device
73-
int lfs_emubd_sync(lfs_emubd_t *bd);
74-
75-
// Get a description of the block device
76-
//
77-
// Any unknown information may be left unmodified
78-
int lfs_emubd_info(lfs_emubd_t *bd, struct lfs_bd_info *info);
79-
80-
// Get stats of operations on the block device
81-
//
82-
// Used for debugging and optimizations
83-
int lfs_emubd_stats(lfs_emubd_t *bd, struct lfs_bd_stats *stats);
84-
85-
// Block device operations
86-
extern const struct lfs_bd_ops lfs_emubd_ops;
75+
int lfs_emubd_sync(const struct lfs_config *cfg);
8776

8877

8978
#endif

0 commit comments

Comments
 (0)