@@ -365,6 +365,9 @@ static void lfs_superblock_fromle32(struct lfs_disk_superblock *d) {
365
365
d -> block_size = lfs_fromle32 (d -> block_size );
366
366
d -> block_count = lfs_fromle32 (d -> block_count );
367
367
d -> version = lfs_fromle32 (d -> version );
368
+ d -> inline_size = lfs_fromle32 (d -> inline_size );
369
+ d -> attrs_size = lfs_fromle32 (d -> attrs_size );
370
+ d -> name_size = lfs_fromle32 (d -> name_size );
368
371
}
369
372
370
373
static void lfs_superblock_tole32 (struct lfs_disk_superblock * d ) {
@@ -373,6 +376,9 @@ static void lfs_superblock_tole32(struct lfs_disk_superblock *d) {
373
376
d -> block_size = lfs_tole32 (d -> block_size );
374
377
d -> block_count = lfs_tole32 (d -> block_count );
375
378
d -> version = lfs_tole32 (d -> version );
379
+ d -> inline_size = lfs_tole32 (d -> inline_size );
380
+ d -> attrs_size = lfs_tole32 (d -> attrs_size );
381
+ d -> name_size = lfs_tole32 (d -> name_size );
376
382
}
377
383
378
384
@@ -1018,6 +1024,12 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1018
1024
return err ? err : LFS_ERR_EXIST ;
1019
1025
}
1020
1026
1027
+ // check that name fits
1028
+ lfs_size_t nlen = strlen (path );
1029
+ if (nlen > lfs -> name_size ) {
1030
+ return LFS_ERR_NAMETOOLONG ;
1031
+ }
1032
+
1021
1033
// build up new directory
1022
1034
lfs_alloc_ack (lfs );
1023
1035
@@ -1037,7 +1049,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1037
1049
entry .d .type = LFS_STRUCT_DIR | LFS_TYPE_DIR ;
1038
1050
entry .d .elen = sizeof (entry .d ) - 4 ;
1039
1051
entry .d .alen = 0 ;
1040
- entry .d .nlen = strlen ( path ) ;
1052
+ entry .d .nlen = nlen ;
1041
1053
entry .d .u .dir [0 ] = dir .pair [0 ];
1042
1054
entry .d .u .dir [1 ] = dir .pair [1 ];
1043
1055
entry .size = 0 ;
@@ -1046,7 +1058,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1046
1058
cwd .d .tail [1 ] = dir .pair [1 ];
1047
1059
err = lfs_dir_set (lfs , & cwd , & entry , (struct lfs_region []){
1048
1060
{LFS_FROM_MEM , 0 , & entry .d , sizeof (entry .d )},
1049
- {LFS_FROM_MEM , 0 , path , entry . d . nlen }}, 2 );
1061
+ {LFS_FROM_MEM , 0 , path , nlen }}, 2 );
1050
1062
if (err ) {
1051
1063
return err ;
1052
1064
}
@@ -1427,16 +1439,22 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
1427
1439
return LFS_ERR_NOENT ;
1428
1440
}
1429
1441
1442
+ // check that name fits
1443
+ lfs_size_t nlen = strlen (path );
1444
+ if (nlen > lfs -> name_size ) {
1445
+ return LFS_ERR_NAMETOOLONG ;
1446
+ }
1447
+
1430
1448
// create entry to remember name
1431
1449
entry .d .type = LFS_STRUCT_INLINE | LFS_TYPE_REG ;
1432
1450
entry .d .elen = 0 ;
1433
1451
entry .d .alen = 0 ;
1434
- entry .d .nlen = strlen ( path ) ;
1452
+ entry .d .nlen = nlen ;
1435
1453
entry .size = 0 ;
1436
1454
1437
1455
err = lfs_dir_set (lfs , & cwd , & entry , (struct lfs_region []){
1438
1456
{LFS_FROM_MEM , 0 , & entry .d , 4 },
1439
- {LFS_FROM_MEM , 0 , path , entry . d . nlen }}, 2 );
1457
+ {LFS_FROM_MEM , 0 , path , nlen }}, 2 );
1440
1458
if (err ) {
1441
1459
return err ;
1442
1460
}
@@ -1571,10 +1589,6 @@ relocate:;
1571
1589
1572
1590
static int lfs_file_flush (lfs_t * lfs , lfs_file_t * file ) {
1573
1591
if (file -> flags & LFS_F_READING ) {
1574
- if (!(file -> flags & LFS_F_INLINE )) {
1575
- // just drop read cache
1576
- file -> cache .block = 0xffffffff ;
1577
- }
1578
1592
file -> flags &= ~LFS_F_READING ;
1579
1593
}
1580
1594
@@ -1807,9 +1821,8 @@ lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
1807
1821
// TODO need to move out if no longer fits in block also
1808
1822
// TODO store INLINE_MAX in superblock?
1809
1823
// TODO what if inline files is > block size (ie 128)
1810
- if ((file -> flags & LFS_F_INLINE ) && (
1811
- (file -> pos + nsize >= LFS_INLINE_MAX ) ||
1812
- (file -> pos + nsize >= lfs -> cfg -> read_size ))) {
1824
+ if ((file -> flags & LFS_F_INLINE ) &&
1825
+ file -> pos + nsize >= lfs -> inline_size ) {
1813
1826
file -> block = 0xfffffffe ;
1814
1827
file -> off = file -> pos ;
1815
1828
@@ -2137,6 +2150,12 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2137
2150
bool prevexists = (err != LFS_ERR_NOENT );
2138
2151
bool samepair = (lfs_paircmp (oldcwd .pair , newcwd .pair ) == 0 );
2139
2152
2153
+ // check that name fits
2154
+ lfs_size_t nlen = strlen (newpath );
2155
+ if (nlen > lfs -> name_size ) {
2156
+ return LFS_ERR_NAMETOOLONG ;
2157
+ }
2158
+
2140
2159
// must have same type
2141
2160
if (prevexists && preventry .d .type != oldentry .d .type ) {
2142
2161
return LFS_ERR_ISDIR ;
@@ -2174,7 +2193,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2174
2193
lfs_entry_t newentry = preventry ;
2175
2194
newentry .d = oldentry .d ;
2176
2195
newentry .d .type &= ~LFS_STRUCT_MOVED ;
2177
- newentry .d .nlen = strlen ( newpath ) ;
2196
+ newentry .d .nlen = nlen ;
2178
2197
if (!prevexists ) {
2179
2198
newentry .size = 0 ;
2180
2199
}
@@ -2185,8 +2204,7 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2185
2204
oldcwd .pair [0 ], oldentry .off , (struct lfs_region []){
2186
2205
{LFS_FROM_MEM , 0 , & newentry .d , 4 },
2187
2206
{LFS_FROM_DROP , 0 , NULL , -4 },
2188
- {LFS_FROM_MEM , newsize - newentry .d .nlen ,
2189
- newpath , newentry .d .nlen }}, 3 },
2207
+ {LFS_FROM_MEM , newsize - nlen , newpath , nlen }}, 3 },
2190
2208
newsize },
2191
2209
{LFS_FROM_DROP , 0 , NULL , - preventry .size }}, prevexists ? 2 : 1 );
2192
2210
if (err ) {
@@ -2272,6 +2290,26 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
2272
2290
LFS_ASSERT (4 * lfs_npw2 (0xffffffff / (lfs -> cfg -> block_size - 2 * 4 ))
2273
2291
<= lfs -> cfg -> block_size );
2274
2292
2293
+ // check that the size limits are sane
2294
+ LFS_ASSERT (lfs -> cfg -> inline_size <= LFS_INLINE_MAX );
2295
+ LFS_ASSERT (lfs -> cfg -> inline_size <= lfs -> cfg -> read_size );
2296
+ lfs -> inline_size = lfs -> cfg -> inline_size ;
2297
+ if (!lfs -> inline_size ) {
2298
+ lfs -> inline_size = lfs_min (LFS_INLINE_MAX , lfs -> cfg -> read_size );
2299
+ }
2300
+
2301
+ LFS_ASSERT (lfs -> cfg -> attrs_size <= LFS_ATTRS_MAX );
2302
+ lfs -> attrs_size = lfs -> cfg -> attrs_size ;
2303
+ if (!lfs -> attrs_size ) {
2304
+ lfs -> attrs_size = LFS_ATTRS_MAX ;
2305
+ }
2306
+
2307
+ LFS_ASSERT (lfs -> cfg -> name_size <= LFS_NAME_MAX );
2308
+ lfs -> name_size = lfs -> cfg -> name_size ;
2309
+ if (!lfs -> name_size ) {
2310
+ lfs -> name_size = LFS_NAME_MAX ;
2311
+ }
2312
+
2275
2313
// setup default state
2276
2314
lfs -> root [0 ] = 0xffffffff ;
2277
2315
lfs -> root [1 ] = 0xffffffff ;
@@ -2336,13 +2374,16 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
2336
2374
superdir .d .tail [0 ] = lfs -> root [0 ];
2337
2375
superdir .d .tail [1 ] = lfs -> root [1 ];
2338
2376
2339
- // write one superblocks
2377
+ // write one superblock
2340
2378
lfs_superblock_t superblock ;
2341
2379
superblock .d .version = LFS_DISK_VERSION ,
2342
2380
superblock .d .root [0 ] = lfs -> root [0 ];
2343
2381
superblock .d .root [1 ] = lfs -> root [1 ];
2344
2382
superblock .d .block_size = lfs -> cfg -> block_size ;
2345
2383
superblock .d .block_count = lfs -> cfg -> block_count ;
2384
+ superblock .d .inline_size = lfs -> inline_size ;
2385
+ superblock .d .attrs_size = lfs -> attrs_size ;
2386
+ superblock .d .name_size = lfs -> name_size ;
2346
2387
2347
2388
lfs_entry_t superentry ;
2348
2389
superentry .d .type = LFS_STRUCT_DIR | LFS_TYPE_SUPERBLOCK ;
@@ -2385,33 +2426,41 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
2385
2426
2386
2427
// load superblock
2387
2428
lfs_dir_t dir ;
2429
+ lfs_entry_t entry ;
2388
2430
lfs_superblock_t superblock ;
2389
2431
char magic [8 ];
2432
+
2390
2433
err = lfs_dir_fetch (lfs , & dir , (const lfs_block_t [2 ]){0 , 1 });
2391
- if (err && err != LFS_ERR_CORRUPT ) {
2434
+ if (err ) {
2435
+ if (err == LFS_ERR_CORRUPT ) {
2436
+ LFS_ERROR ("Invalid superblock at %d %d" , 0 , 1 );
2437
+ }
2392
2438
return err ;
2393
2439
}
2394
2440
2395
- if (!err ) {
2396
- err = lfs_dir_get (lfs , & dir ,
2397
- sizeof (dir .d )+ 4 , & superblock .d , sizeof (superblock .d ));
2398
- lfs_superblock_fromle32 (& superblock .d );
2399
- if (err ) {
2400
- return err ;
2401
- }
2441
+ err = lfs_dir_get (lfs , & dir , sizeof (dir .d ), & entry .d , sizeof (entry .d ));
2442
+ if (err ) {
2443
+ return err ;
2444
+ }
2402
2445
2403
- err = lfs_dir_get (lfs , & dir ,
2404
- sizeof (dir .d )+ 4 + sizeof (superblock .d ), magic , sizeof (magic ));
2405
- if (err ) {
2406
- return err ;
2407
- }
2446
+ memset (& superblock .d , 0 , sizeof (superblock .d ));
2447
+ err = lfs_dir_get (lfs , & dir ,
2448
+ sizeof (dir .d )+ 4 , & superblock .d ,
2449
+ lfs_min (sizeof (superblock .d ), entry .d .elen ));
2450
+ lfs_superblock_fromle32 (& superblock .d );
2451
+ if (err ) {
2452
+ return err ;
2453
+ }
2408
2454
2409
- lfs -> root [0 ] = superblock .d .root [0 ];
2410
- lfs -> root [1 ] = superblock .d .root [1 ];
2455
+ err = lfs_dir_get (lfs , & dir ,
2456
+ sizeof (dir .d )+ 4 + entry .d .elen + entry .d .alen , magic ,
2457
+ lfs_min (sizeof (magic ), entry .d .nlen ));
2458
+ if (err ) {
2459
+ return err ;
2411
2460
}
2412
2461
2413
- if (err || memcmp (magic , "littlefs" , 8 ) != 0 ) {
2414
- LFS_ERROR ("Invalid superblock at %d %d" , dir . pair [ 0 ], dir . pair [ 1 ] );
2462
+ if (memcmp (magic , "littlefs" , 8 ) != 0 ) {
2463
+ LFS_ERROR ("Invalid superblock at %d %d" , 0 , 1 );
2415
2464
return LFS_ERR_CORRUPT ;
2416
2465
}
2417
2466
@@ -2423,6 +2472,39 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
2423
2472
return LFS_ERR_INVAL ;
2424
2473
}
2425
2474
2475
+ if (superblock .d .inline_size ) {
2476
+ if (superblock .d .inline_size > lfs -> inline_size ) {
2477
+ LFS_ERROR ("Unsupported inline size (%d > %d)" ,
2478
+ superblock .d .inline_size , lfs -> inline_size );
2479
+ return LFS_ERR_INVAL ;
2480
+ }
2481
+
2482
+ lfs -> inline_size = superblock .d .inline_size ;
2483
+ }
2484
+
2485
+ if (superblock .d .attrs_size ) {
2486
+ if (superblock .d .attrs_size > lfs -> attrs_size ) {
2487
+ LFS_ERROR ("Unsupported attrs size (%d > %d)" ,
2488
+ superblock .d .attrs_size , lfs -> attrs_size );
2489
+ return LFS_ERR_INVAL ;
2490
+ }
2491
+
2492
+ lfs -> attrs_size = superblock .d .attrs_size ;
2493
+ }
2494
+
2495
+ if (superblock .d .name_size ) {
2496
+ if (superblock .d .name_size > lfs -> name_size ) {
2497
+ LFS_ERROR ("Unsupported name size (%d > %d)" ,
2498
+ superblock .d .name_size , lfs -> name_size );
2499
+ return LFS_ERR_INVAL ;
2500
+ }
2501
+
2502
+ lfs -> name_size = superblock .d .name_size ;
2503
+ }
2504
+
2505
+ lfs -> root [0 ] = superblock .d .root [0 ];
2506
+ lfs -> root [1 ] = superblock .d .root [1 ];
2507
+
2426
2508
return 0 ;
2427
2509
}
2428
2510
0 commit comments