@@ -29,6 +29,49 @@ static uint32_t lfs_crc(const uint8_t *data, lfs_size_t size, uint32_t crc) {
29
29
static lfs_error_t lfs_alloc (lfs_t * lfs , lfs_ino_t * ino );
30
30
static lfs_error_t lfs_free (lfs_t * lfs , lfs_ino_t ino );
31
31
32
+ // Disk structures
33
+ //lfs_disk_struct lfs_disk_free {
34
+ // lfs_ino_t head;
35
+ // uint32_t ioff;
36
+ // uint32_t icount;
37
+ // uint32_t rev;
38
+ //};
39
+ //
40
+ //lfs_disk_struct lfs_disk_dir {
41
+ // uint32_t rev;
42
+ // uint32_t count;
43
+ // lfs_ino_t tail[2];
44
+ // struct lfs_disk_free free;
45
+ //};
46
+ //
47
+ //lfs_disk_struct lfs_disk_dirent {
48
+ // uint16_t type;
49
+ // uint16_t len;
50
+ //};
51
+ //
52
+ //lfs_disk_struct lfs_disk_superblock {
53
+ // struct lfs_disk_dir dir;
54
+ // struct lfs_disk_dirent header;
55
+ // char magic[4];
56
+ // uint32_t read_size;
57
+ // uint32_t write_size;
58
+ // uint32_t erase_size;
59
+ // uint32_t erase_count;
60
+ //};
61
+ //
62
+ //lfs_disk_struct lfs_disk_dirent_file {
63
+ // struct lfs_disk_dirent header;
64
+ // lfs_ino_t head;
65
+ // lfs_size_t size;
66
+ // char name[LFS_NAME_MAX];
67
+ //};
68
+ //
69
+ //lfs_disk_struct lfs_disk_dirent_dir {
70
+ // struct lfs_disk_dirent header;
71
+ // lfs_ino_t ino[2];
72
+ // char name[LFS_NAME_MAX];
73
+ //};
74
+
32
75
33
76
// Next index offset
34
77
static lfs_off_t lfs_inext (lfs_t * lfs , lfs_off_t ioff ) {
@@ -114,21 +157,220 @@ static lfs_error_t lfs_iappend(lfs_t *lfs, lfs_ino_t *headp,
114
157
115
158
// Memory managment
116
159
static lfs_error_t lfs_alloc (lfs_t * lfs , lfs_ino_t * ino ) {
117
- lfs_error_t err = lfs_ifind (lfs , lfs -> free .head ,
118
- lfs -> free .icount , lfs -> free .ioff , ino );
160
+ // TODO save slot for freeing?
161
+ lfs_error_t err = lfs_ifind (lfs , lfs -> free .d .head ,
162
+ lfs -> free .d .icount , lfs -> free .d .ioff , ino );
119
163
if (err ) {
120
164
return err ;
121
165
}
122
166
123
- lfs -> free .ioff = lfs_inext (lfs , lfs -> free .ioff );
167
+ lfs -> free .d . ioff = lfs_inext (lfs , lfs -> free . d .ioff );
124
168
125
169
return lfs -> ops -> erase (lfs -> bd , * ino , 0 , lfs -> info .erase_size );
126
170
}
127
171
128
172
static lfs_error_t lfs_free (lfs_t * lfs , lfs_ino_t ino ) {
129
- return lfs_iappend (lfs , & lfs -> free .head , & lfs -> free .icount , ino );
173
+ return lfs_iappend (lfs , & lfs -> free .d .head , & lfs -> free .d .icount , ino );
174
+ }
175
+
176
+ // create a dir
177
+ // create entry
178
+ // update entry
179
+
180
+
181
+ //static lfs_error_t lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir);
182
+ //static lfs_error_t lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry);
183
+ //static lfs_error_t lfs_dir_destroy(lfs_t *lfs, lfs_dir_t *dir);
184
+ //static lfs_error_t lfs_entry_alloc(lfs_t *lfs, lfs_dir_t *dir, lfs_entry_t *entry);
185
+ //static lfs_error_t lfs_entry_update(lfs_t *lfs, lfs_entry_t *entry);
186
+ //static lfs_error_t lfs_entry_destroy(lfs_t *lfs, lfs_dir_t *dir);
187
+
188
+ // Directory operations
189
+ static lfs_error_t lfs_dir_alloc (lfs_t * lfs , lfs_dir_t * dir ) {
190
+ // Allocate pair of dir blocks
191
+ for (int i = 0 ; i < 2 ; i ++ ) {
192
+ int err = lfs_alloc (lfs , & dir -> dno [i ]);
193
+ if (err ) {
194
+ return err ;
195
+ }
196
+ }
197
+
198
+ // Rather than clobbering one of the blocks we just pretend
199
+ // the revision may be valid
200
+ int err = lfs -> ops -> read (lfs -> bd , (void * )& dir -> d .rev , dir -> dno [1 ], 0 , 4 );
201
+ if (err ) {
202
+ return err ;
203
+ }
204
+ dir -> d .rev += 1 ;
205
+
206
+ // Other defaults
207
+ dir -> d .size = sizeof (struct lfs_disk_dir );
208
+ dir -> d .tail [0 ] = 0 ;
209
+ dir -> d .tail [1 ] = 0 ;
210
+ dir -> d .parent [0 ] = 0 ;
211
+ dir -> d .parent [1 ] = 0 ;
212
+ return 0 ;
213
+ }
214
+
215
+ lfs_error_t lfs_dir_update (lfs_t * lfs , lfs_dir_t * dir , lfs_entry_t * entry ) {
216
+ // TODO flush this
217
+ dir -> d .free = lfs -> free .d ;
218
+
219
+ // Start by erasing target block
220
+ int err = lfs -> ops -> erase (lfs -> bd , dir -> dno [0 ], 0 , lfs -> info .erase_size );
221
+
222
+ // Write header and start calculating crc
223
+ uint32_t crc = lfs_crc ((void * )& dir -> d , sizeof (dir -> d ), 0xffffffff );
224
+ err = lfs -> ops -> write (lfs -> bd , (void * )& dir -> d ,
225
+ dir -> dno [0 ], 0 , sizeof (dir -> d ));
226
+ if (err ) {
227
+ return err ;
228
+ }
229
+
230
+ // Copy over entries and write optional entry update
231
+ // TODO handle optional entry
232
+ for (lfs_off_t i = sizeof (dir -> d ); i < lfs -> info .erase_size - 4 ; i += 4 ) {
233
+ uint32_t data ;
234
+ err = lfs -> ops -> read (lfs -> bd , (void * )& data , dir -> dno [1 ], i , 4 );
235
+ if (err ) {
236
+ return err ;
237
+ }
238
+
239
+ crc = lfs_crc ((void * )& data , 4 , crc );
240
+ err = lfs -> ops -> write (lfs -> bd , (void * )& data , dir -> dno [0 ], i , 4 );
241
+ if (err ) {
242
+ return err ;
243
+ }
244
+ }
245
+
246
+ // Write resulting crc
247
+ err = lfs -> ops -> write (lfs -> bd , (void * )& crc ,
248
+ dir -> dno [0 ], lfs -> info .erase_size - 4 , 4 );
249
+ if (err ) {
250
+ return err ;
251
+ }
252
+
253
+ // Flip dnos to indicate next write of the dir pair
254
+ lfs_ino_t temp = dir -> dno [0 ];
255
+ dir -> dno [0 ] = dir -> dno [1 ];
256
+ dir -> dno [1 ] = temp ;
257
+
258
+ return 0 ;
130
259
}
131
260
261
+
262
+ //static lfs_error_t lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir) {
263
+ // memset(dir, 0, sizeof(lfs_dir_t));
264
+ //
265
+ // for (int i = 0; i < 2; i++) {
266
+ // int err = lfs_alloc(lfs, &dir->dno[i]);
267
+ // if (err) {
268
+ // return err;
269
+ // }
270
+ // }
271
+ //
272
+ // // Rather than clobbering one of the blocks we just pretend
273
+ // // the revision may be valid
274
+ // int err = lfs->ops->read(lfs->bd, (void*)&dir->rev, dir->dno[1], 0, 4);
275
+ // if (err) {
276
+ // return err;
277
+ // }
278
+ // dir->rev += 1;
279
+ //
280
+ // // TODO move this to a flush of some sort?
281
+ // struct lfs_disk_dir disk_dir = {
282
+ // .rev = dir->rev,
283
+ // .count = dir->len,
284
+ // .tail[0] = dir->tail[0],
285
+ // .tail[1] = dir->tail[1],
286
+ // .free.head = lfs->free.head,
287
+ // .free.ioff = lfs->free.ioff,
288
+ // .free.icount = lfs->free.icount,
289
+ // .free.rev = lfs->free.rev,
290
+ // };
291
+ //
292
+ // err = lfs->ops->write(lfs->bd, (void*)&disk_dir,
293
+ // dir->dno[0], 0, sizeof(struct lfs_disk_dir));
294
+ // if (err) {
295
+ // return err;
296
+ // }
297
+ //
298
+ // uint32_t crc = 0xffffffff;
299
+ // for (lfs_off_t i = 0; i < lfs->info.erase_size-4; i += 4) {
300
+ // uint32_t data;
301
+ // err = lfs->ops->read(lfs->bd, (void*)&data, dir->dno[0], i, 4);
302
+ // if (err) {
303
+ // return err;
304
+ // }
305
+ //
306
+ // crc = lfs_crc((void*)&data, 4, crc);
307
+ // }
308
+ //
309
+ // err = lfs->ops->write(lfs->bd, (void*)&crc,
310
+ // dir->dno[0], lfs->info.erase_size-4, 4);
311
+ // if (err) {
312
+ // return err;
313
+ // }
314
+ //
315
+ // lfs_ino_t temp = dir->dno[0];
316
+ // dir->dno[0] = dir->dno[1];
317
+ // dir->dno[1] = temp;
318
+ //
319
+ // return 0;
320
+ //}
321
+
322
+ //lfs_error_t lfs_dir_update(lfs_t *lfs, lfs_dir_t *dir,
323
+ // lfs_dirent_t *ent, const char *name) {
324
+ //
325
+ //
326
+ //
327
+ // struct lfs_disk_dir disk_dir = {
328
+ // .rev = dir->rev,
329
+ // .count = dir->len,
330
+ // .tail[0] = dir->tail[0],
331
+ // .tail[1] = dir->tail[1],
332
+ // // TODO flush this?
333
+ // .free.head = lfs->free.head,
334
+ // .free.ioff = lfs->free.ioff,
335
+ // .free.icount = lfs->free.icount,
336
+ // .free.rev = lfs->free.rev,
337
+ // };
338
+ //
339
+ // err = lfs->ops->write(lfs->bd, (void*)&disk_dir,
340
+ // dir->dno[0], 0, sizeof(struct lfs_disk_dir));
341
+ // if (err) {
342
+ // return err;
343
+ // }
344
+ //
345
+ // if (ent) {
346
+ // // TODO update entry
347
+ // }
348
+ //
349
+ // uint32_t crc = 0xffffffff;
350
+ // for (lfs_off_t i = 0; i < lfs->info.erase_size-4; i += 4) {
351
+ // uint32_t data;
352
+ // err = lfs->ops->read(lfs->bd, (void*)&data, dir->dno[0], i, 4);
353
+ // if (err) {
354
+ // return err;
355
+ // }
356
+ //
357
+ // crc = lfs_crc((void*)&data, 4, crc);
358
+ // }
359
+ //
360
+ // err = lfs->ops->write(lfs->bd, (void*)&crc,
361
+ // dir->dno[0], lfs->info.erase_size-4, 4);
362
+ // if (err) {
363
+ // return err;
364
+ // }
365
+ //
366
+ // lfs_ino_t temp = dir->dno[0];
367
+ // dir->dno[0] = dir->dno[1];
368
+ // dir->dno[1] = temp;
369
+ //
370
+ // return 0;
371
+ //}
372
+
373
+
132
374
// Little filesystem operations
133
375
lfs_error_t lfs_create (lfs_t * lfs , lfs_bd_t * bd , const struct lfs_bd_ops * ops ) {
134
376
lfs -> bd = bd ;
@@ -157,10 +399,10 @@ lfs_error_t lfs_format(lfs_t *lfs) {
157
399
// TODO make sure that erase clobbered blocks
158
400
159
401
{ // Create free list
160
- lfs -> free .head = 4 ;
161
- lfs -> free .ioff = 1 ;
162
- lfs -> free .icount = 1 ;
163
- lfs -> free .rev = 1 ;
402
+ lfs -> free .d . head = 4 ;
403
+ lfs -> free .d . ioff = 1 ;
404
+ lfs -> free .d . icount = 1 ;
405
+ lfs -> free .d . rev = 1 ;
164
406
165
407
lfs_size_t block_count = lfs -> info .total_size / lfs -> info .erase_size ;
166
408
for (lfs_ino_t i = 5 ; i < block_count ; i ++ ) {
@@ -171,68 +413,66 @@ lfs_error_t lfs_format(lfs_t *lfs) {
171
413
}
172
414
}
173
415
416
+ lfs_dir_t root ;
174
417
{
175
418
// Write root directory
176
- struct __attribute__((packed )) {
177
- lfs_word_t rev ;
178
- lfs_size_t len ;
179
- lfs_ino_t tail [2 ];
180
- struct lfs_free_list free ;
181
- } header = {1 , 0 , {0 , 0 }, lfs -> free };
182
- err = lfs -> ops -> write (lfs -> bd , (void * )& header , 2 , 0 , sizeof (header ));
419
+ int err = lfs_dir_alloc (lfs , & root );
183
420
if (err ) {
184
421
return err ;
185
422
}
186
423
187
- uint32_t crc = lfs_crc ((void * )& header , sizeof (header ), 0xffffffff );
424
+ err = lfs_dir_update (lfs , & root , 0 );
425
+ if (err ) {
426
+ return err ;
427
+ }
428
+ }
188
429
189
- for (lfs_size_t i = sizeof (header ); i < info .erase_size - 4 ; i += 4 ) {
190
- uint32_t data ;
191
- err = lfs -> ops -> read (lfs -> bd , (void * )& data , 2 , i , 4 );
430
+ {
431
+ // Write superblocks
432
+ lfs_ino_t sno [2 ] = {0 , 1 };
433
+ lfs_superblock_t superblock = {
434
+ .d .rev = 1 ,
435
+ .d .count = 0 ,
436
+ .d .root = {root .dno [0 ], root .dno [1 ]},
437
+ .d .magic = {"littlefs" },
438
+ .d .block_size = info .erase_size ,
439
+ .d .block_count = info .total_size / info .erase_size ,
440
+ };
441
+
442
+ for (int i = 0 ; i < 2 ; i ++ ) {
443
+ err = lfs -> ops -> erase (lfs -> bd , sno [i ], 0 , info .erase_size );
192
444
if (err ) {
193
445
return err ;
194
446
}
195
447
196
- crc = lfs_crc ((void * )& data , 4 , crc );
197
- }
448
+ err = lfs -> ops -> write (lfs -> bd , (void * )& superblock .d ,
449
+ sno [i ], 0 , sizeof (superblock .d ));
450
+ if (err ) {
451
+ return err ;
452
+ }
198
453
199
- err = lfs -> ops -> write (lfs -> bd , (void * )& crc , 2 , info .erase_size - 4 , 4 );
200
- if (err ) {
201
- return err ;
202
- }
203
- }
454
+ uint32_t crc = lfs_crc ((void * )& superblock .d ,
455
+ sizeof (superblock .d ), 0xffffffff );
204
456
205
- {
206
- // Write superblock
207
- struct __attribute__((packed )) {
208
- lfs_word_t rev ;
209
- lfs_word_t len ;
210
- lfs_word_t tail [2 ];
211
- struct lfs_free_list free ;
212
- char magic [4 ];
213
- struct lfs_bd_info info ;
214
- } header = {1 , 0 , {2 , 3 }, {0 }, {"lfs" }, info };
215
- err = lfs -> ops -> write (lfs -> bd , (void * )& header , 0 , 0 , sizeof (header ));
216
- if (err ) {
217
- return err ;
218
- }
457
+ for (lfs_size_t i = sizeof (superblock );
458
+ i < info .erase_size - 4 ; i += 4 ) {
459
+ uint32_t data ;
460
+ err = lfs -> ops -> read (lfs -> bd , (void * )& data , 0 , i , 4 );
461
+ if (err ) {
462
+ return err ;
463
+ }
219
464
220
- uint32_t crc = lfs_crc ((void * )& header , sizeof (header ), 0xffffffff );
465
+ crc = lfs_crc ((void * )& data , 4 , crc );
466
+ }
221
467
222
- for (lfs_size_t i = sizeof (header ); i < info .erase_size - 4 ; i += 4 ) {
223
- uint32_t data ;
224
- err = lfs -> ops -> read (lfs -> bd , (void * )& data , 0 , i , 4 );
468
+ err = lfs -> ops -> write (lfs -> bd , (void * )& crc ,
469
+ sno [i ], info .erase_size - 4 , 4 );
225
470
if (err ) {
226
471
return err ;
227
472
}
228
-
229
- crc = lfs_crc ((void * )& data , 4 , crc );
230
473
}
231
474
232
- err = lfs -> ops -> write (lfs -> bd , (void * )& crc , 0 , info .erase_size - 4 , 4 );
233
- if (err ) {
234
- return err ;
235
- }
475
+ // TODO verify superblocks written correctly
236
476
}
237
477
238
478
0 commit comments