@@ -320,17 +320,17 @@ static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) {
320
320
struct lfs_mattr {
321
321
lfs_tag_t tag ;
322
322
const void * buffer ;
323
- const struct lfs_mattr * next ;
324
323
};
325
324
326
- #define LFS_MKATTR (type , id , buffer , size , next ) \
327
- &(const struct lfs_mattr){LFS_MKTAG(type, id, size), (buffer), (next)}
328
-
329
325
struct lfs_diskoff {
330
326
lfs_block_t block ;
331
327
lfs_off_t off ;
332
328
};
333
329
330
+ #define LFS_MKATTRS (...) \
331
+ (struct lfs_mattr[]){__VA_ARGS__}, \
332
+ sizeof((struct lfs_mattr[]){__VA_ARGS__}) / sizeof(struct lfs_mattr)
333
+
334
334
// operations on global state
335
335
static inline void lfs_gstate_xor (struct lfs_gstate * a ,
336
336
const struct lfs_gstate * b ) {
@@ -409,7 +409,7 @@ static inline void lfs_superblock_tole32(lfs_superblock_t *superblock) {
409
409
410
410
/// Internal operations predeclared here ///
411
411
static int lfs_dir_commit (lfs_t * lfs , lfs_mdir_t * dir ,
412
- const struct lfs_mattr * attrs );
412
+ const struct lfs_mattr * attrs , int attrcount );
413
413
static int lfs_dir_compact (lfs_t * lfs ,
414
414
lfs_mdir_t * dir , const struct lfs_mattr * attrs , int attrcount ,
415
415
lfs_mdir_t * source , uint16_t begin , uint16_t end );
@@ -600,13 +600,9 @@ static int lfs_dir_traverse(lfs_t *lfs,
600
600
buffer = & disk ;
601
601
ptag = tag ;
602
602
} else if (attrcount > 0 ) {
603
- const struct lfs_mattr * a = attrs ;
604
- for (int j = 0 ; j < attrcount - 1 ; j ++ ) {
605
- a = a -> next ;
606
- }
607
-
608
- tag = a -> tag ;
609
- buffer = a -> buffer ;
603
+ tag = attrs [0 ].tag ;
604
+ buffer = attrs [0 ].buffer ;
605
+ attrs += 1 ;
610
606
attrcount -= 1 ;
611
607
} else if (!hasseenmove &&
612
608
lfs_gstate_hasmovehere (& lfs -> gpending , dir -> pair )) {
@@ -647,7 +643,9 @@ static int lfs_dir_traverse(lfs_t *lfs,
647
643
}
648
644
649
645
// handle special cases for mcu-side operations
650
- if (lfs_tag_type3 (tag ) == LFS_FROM_MOVE ) {
646
+ if (lfs_tag_type3 (tag ) == LFS_FROM_NOOP ) {
647
+ // do nothing
648
+ } else if (lfs_tag_type3 (tag ) == LFS_FROM_MOVE ) {
651
649
uint16_t fromid = lfs_tag_size (tag );
652
650
uint16_t toid = lfs_tag_id (tag );
653
651
int err = lfs_dir_traverse (lfs ,
@@ -660,9 +658,10 @@ static int lfs_dir_traverse(lfs_t *lfs,
660
658
return err ;
661
659
}
662
660
} else if (lfs_tag_type3 (tag ) == LFS_FROM_USERATTRS ) {
663
- for (const struct lfs_attr * a = buffer ; a ; a = a -> next ) {
664
- int err = cb (data , LFS_MKTAG (LFS_TYPE_USERATTR + a -> type ,
665
- lfs_tag_id (tag ) + diff , a -> size ), a -> buffer );
661
+ for (unsigned i = 0 ; i < lfs_tag_size (tag ); i ++ ) {
662
+ const struct lfs_attr * a = buffer ;
663
+ int err = cb (data , LFS_MKTAG (LFS_TYPE_USERATTR + a [i ].type ,
664
+ lfs_tag_id (tag ) + diff , a [i ].size ), a [i ].buffer );
666
665
if (err ) {
667
666
return err ;
668
667
}
@@ -1266,9 +1265,8 @@ static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) {
1266
1265
1267
1266
// steal tail
1268
1267
lfs_pair_tole32 (tail -> tail );
1269
- err = lfs_dir_commit (lfs , dir ,
1270
- LFS_MKATTR (LFS_TYPE_TAIL + tail -> split , 0x3ff , tail -> tail , 8 ,
1271
- NULL ));
1268
+ err = lfs_dir_commit (lfs , dir , LFS_MKATTRS (
1269
+ {LFS_MKTAG (LFS_TYPE_TAIL + tail -> split , 0x3ff , 8 ), tail -> tail }));
1272
1270
lfs_pair_fromle32 (tail -> tail );
1273
1271
if (err ) {
1274
1272
return err ;
@@ -1557,27 +1555,24 @@ static int lfs_dir_compact(lfs_t *lfs,
1557
1555
}
1558
1556
1559
1557
static int lfs_dir_commit (lfs_t * lfs , lfs_mdir_t * dir ,
1560
- const struct lfs_mattr * attrs ) {
1558
+ const struct lfs_mattr * attrs , int attrcount ) {
1561
1559
// calculate changes to the directory
1562
1560
lfs_tag_t deletetag = 0xffffffff ;
1563
1561
lfs_tag_t createtag = 0xffffffff ;
1564
- int attrcount = 0 ;
1565
- for (const struct lfs_mattr * a = attrs ; a ; a = a -> next ) {
1566
- if (lfs_tag_type3 (a -> tag ) == LFS_TYPE_CREATE ) {
1567
- createtag = a -> tag ;
1562
+ for (int i = 0 ; i < attrcount ; i ++ ) {
1563
+ if (lfs_tag_type3 (attrs [i ].tag ) == LFS_TYPE_CREATE ) {
1564
+ createtag = attrs [i ].tag ;
1568
1565
dir -> count += 1 ;
1569
- } else if (lfs_tag_type3 (a -> tag ) == LFS_TYPE_DELETE ) {
1570
- deletetag = a -> tag ;
1566
+ } else if (lfs_tag_type3 (attrs [ i ]. tag ) == LFS_TYPE_DELETE ) {
1567
+ deletetag = attrs [ i ]. tag ;
1571
1568
LFS_ASSERT (dir -> count > 0 );
1572
1569
dir -> count -= 1 ;
1573
- } else if (lfs_tag_type1 (a -> tag ) == LFS_TYPE_TAIL ) {
1574
- dir -> tail [0 ] = ((lfs_block_t * )a -> buffer )[0 ];
1575
- dir -> tail [1 ] = ((lfs_block_t * )a -> buffer )[1 ];
1576
- dir -> split = (lfs_tag_chunk (a -> tag ) & 1 );
1570
+ } else if (lfs_tag_type1 (attrs [ i ]. tag ) == LFS_TYPE_TAIL ) {
1571
+ dir -> tail [0 ] = ((lfs_block_t * )attrs [ i ]. buffer )[0 ];
1572
+ dir -> tail [1 ] = ((lfs_block_t * )attrs [ i ]. buffer )[1 ];
1573
+ dir -> split = (lfs_tag_chunk (attrs [ i ]. tag ) & 1 );
1577
1574
lfs_pair_fromle32 (dir -> tail );
1578
1575
}
1579
-
1580
- attrcount += 1 ;
1581
1576
}
1582
1577
1583
1578
// do we have a pending move?
@@ -1755,9 +1750,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1755
1750
1756
1751
// setup dir
1757
1752
lfs_pair_tole32 (pred .tail );
1758
- err = lfs_dir_commit (lfs , & dir ,
1759
- LFS_MKATTR (LFS_TYPE_SOFTTAIL , 0x3ff , pred .tail , 8 ,
1760
- NULL ));
1753
+ err = lfs_dir_commit (lfs , & dir , LFS_MKATTRS (
1754
+ {LFS_MKTAG (LFS_TYPE_SOFTTAIL , 0x3ff , 8 ), pred .tail }));
1761
1755
lfs_pair_fromle32 (pred .tail );
1762
1756
if (err ) {
1763
1757
return err ;
@@ -1768,9 +1762,8 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1768
1762
// update tails, this creates a desync
1769
1763
lfs_fs_preporphans (lfs , +1 );
1770
1764
lfs_pair_tole32 (dir .pair );
1771
- err = lfs_dir_commit (lfs , & pred ,
1772
- LFS_MKATTR (LFS_TYPE_SOFTTAIL , 0x3ff , dir .pair , 8 ,
1773
- NULL ));
1765
+ err = lfs_dir_commit (lfs , & pred , LFS_MKATTRS (
1766
+ {LFS_MKTAG (LFS_TYPE_SOFTTAIL , 0x3ff , 8 ), dir .pair }));
1774
1767
lfs_pair_fromle32 (dir .pair );
1775
1768
if (err ) {
1776
1769
return err ;
@@ -1780,14 +1773,13 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1780
1773
1781
1774
// now insert into our parent block
1782
1775
lfs_pair_tole32 (dir .pair );
1783
- err = lfs_dir_commit (lfs , & cwd ,
1784
- LFS_MKATTR (LFS_TYPE_DIRSTRUCT , id , dir .pair , sizeof (dir .pair ),
1785
- LFS_MKATTR (LFS_TYPE_DIR , id , path , nlen ,
1786
- LFS_MKATTR (LFS_TYPE_CREATE , id , NULL , 0 ,
1787
- (!cwd .split )
1788
- ? LFS_MKATTR (LFS_TYPE_SOFTTAIL , 0x3ff , dir .pair , 8 ,
1789
- NULL )
1790
- : NULL ))));
1776
+ err = lfs_dir_commit (lfs , & cwd , LFS_MKATTRS (
1777
+ {LFS_MKTAG (LFS_TYPE_CREATE , id , 0 )},
1778
+ {LFS_MKTAG (LFS_TYPE_DIR , id , nlen ), path },
1779
+ {LFS_MKTAG (LFS_TYPE_DIRSTRUCT , id , 8 ), dir .pair },
1780
+ {!cwd .split
1781
+ ? LFS_MKTAG (LFS_TYPE_SOFTTAIL , 0x3ff , 8 )
1782
+ : LFS_MKTAG (LFS_FROM_NOOP , 0 , 0 ), dir .pair }));
1791
1783
lfs_pair_fromle32 (dir .pair );
1792
1784
if (err ) {
1793
1785
return err ;
@@ -2188,11 +2180,10 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
2188
2180
}
2189
2181
2190
2182
// get next slot and create entry to remember name
2191
- err = lfs_dir_commit (lfs , & file -> m ,
2192
- LFS_MKATTR (LFS_TYPE_INLINESTRUCT , file -> id , NULL , 0 ,
2193
- LFS_MKATTR (LFS_TYPE_REG , file -> id , path , nlen ,
2194
- LFS_MKATTR (LFS_TYPE_CREATE , file -> id , NULL , 0 ,
2195
- NULL ))));
2183
+ err = lfs_dir_commit (lfs , & file -> m , LFS_MKATTRS (
2184
+ {LFS_MKTAG (LFS_TYPE_CREATE , file -> id , 0 )},
2185
+ {LFS_MKTAG (LFS_TYPE_REG , file -> id , nlen ), path },
2186
+ {LFS_MKTAG (LFS_TYPE_INLINESTRUCT , file -> id , 0 )}));
2196
2187
if (err ) {
2197
2188
err = LFS_ERR_NAMETOOLONG ;
2198
2189
goto cleanup ;
@@ -2221,20 +2212,21 @@ int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
2221
2212
}
2222
2213
2223
2214
// fetch attrs
2224
- for (const struct lfs_attr * a = file -> cfg -> attrs ; a ; a = a -> next ) {
2215
+ for (unsigned i = 0 ; i < file -> cfg -> attr_count ; i ++ ) {
2225
2216
if ((file -> flags & 3 ) != LFS_O_WRONLY ) {
2226
2217
lfs_stag_t res = lfs_dir_get (lfs , & file -> m ,
2227
2218
LFS_MKTAG (0x7ff , 0x3ff , 0 ),
2228
- LFS_MKTAG (LFS_TYPE_USERATTR + a -> type , file -> id , a -> size ),
2229
- a -> buffer );
2219
+ LFS_MKTAG (LFS_TYPE_USERATTR + file -> cfg -> attrs [i ].type ,
2220
+ file -> id , file -> cfg -> attrs [i ].size ),
2221
+ file -> cfg -> attrs [i ].buffer );
2230
2222
if (res < 0 && res != LFS_ERR_NOENT ) {
2231
2223
err = res ;
2232
2224
goto cleanup ;
2233
2225
}
2234
2226
}
2235
2227
2236
2228
if ((file -> flags & 3 ) != LFS_O_RDONLY ) {
2237
- if (a -> size > lfs -> attr_max ) {
2229
+ if (file -> cfg -> attrs [ i ]. size > lfs -> attr_max ) {
2238
2230
err = LFS_ERR_NOSPC ;
2239
2231
goto cleanup ;
2240
2232
}
@@ -2476,11 +2468,10 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
2476
2468
}
2477
2469
2478
2470
// commit file data and attributes
2479
- err = lfs_dir_commit (lfs , & file -> m ,
2480
- LFS_MKATTR (LFS_FROM_USERATTRS ,
2481
- file -> id , file -> cfg -> attrs , 0 ,
2482
- LFS_MKATTR (type , file -> id , buffer , size ,
2483
- NULL )));
2471
+ err = lfs_dir_commit (lfs , & file -> m , LFS_MKATTRS (
2472
+ {LFS_MKTAG (type , file -> id , size ), buffer },
2473
+ {LFS_MKTAG (LFS_FROM_USERATTRS , file -> id ,
2474
+ file -> cfg -> attr_count ), file -> cfg -> attrs }));
2484
2475
if (err ) {
2485
2476
if (err == LFS_ERR_NOSPC && (file -> flags & LFS_F_INLINE )) {
2486
2477
goto relocate ;
@@ -2850,9 +2841,8 @@ int lfs_remove(lfs_t *lfs, const char *path) {
2850
2841
}
2851
2842
2852
2843
// delete the entry
2853
- err = lfs_dir_commit (lfs , & cwd ,
2854
- LFS_MKATTR (LFS_TYPE_DELETE , lfs_tag_id (tag ), NULL , 0 ,
2855
- NULL ));
2844
+ err = lfs_dir_commit (lfs , & cwd , LFS_MKATTRS (
2845
+ {LFS_MKTAG (LFS_TYPE_DELETE , lfs_tag_id (tag ), 0 )}));
2856
2846
if (err ) {
2857
2847
return err ;
2858
2848
}
@@ -2943,21 +2933,22 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2943
2933
lfs_fs_prepmove (lfs , newoldtagid , oldcwd .pair );
2944
2934
2945
2935
// move over all attributes
2946
- err = lfs_dir_commit (lfs , & newcwd ,
2947
- LFS_MKATTR (LFS_FROM_MOVE , newid , & oldcwd , lfs_tag_id (oldtag ),
2948
- LFS_MKATTR (lfs_tag_type3 (oldtag ), newid , newpath , strlen (newpath ),
2949
- LFS_MKATTR (LFS_TYPE_CREATE , newid , NULL , 0 ,
2950
- (prevtag != LFS_ERR_NOENT )
2951
- ? LFS_MKATTR (LFS_TYPE_DELETE , newid , NULL , 0 , NULL )
2952
- : NULL ))));
2936
+ err = lfs_dir_commit (lfs , & newcwd , LFS_MKATTRS (
2937
+ {prevtag != LFS_ERR_NOENT
2938
+ ? LFS_MKTAG (LFS_TYPE_DELETE , newid , 0 )
2939
+ : LFS_MKTAG (LFS_FROM_NOOP , 0 , 0 )},
2940
+ {LFS_MKTAG (LFS_TYPE_CREATE , newid , 0 )},
2941
+ {LFS_MKTAG (lfs_tag_type3 (oldtag ), newid , strlen (newpath )),
2942
+ newpath },
2943
+ {LFS_MKTAG (LFS_FROM_MOVE , newid , lfs_tag_id (oldtag )), & oldcwd }));
2953
2944
if (err ) {
2954
2945
return err ;
2955
2946
}
2956
2947
2957
2948
// let commit clean up after move (if we're different! otherwise move
2958
2949
// logic already fixed it for us)
2959
2950
if (lfs_pair_cmp (oldcwd .pair , newcwd .pair ) != 0 ) {
2960
- err = lfs_dir_commit (lfs , & oldcwd , NULL );
2951
+ err = lfs_dir_commit (lfs , & oldcwd , NULL , 0 );
2961
2952
if (err ) {
2962
2953
return err ;
2963
2954
}
@@ -3031,9 +3022,8 @@ static int lfs_commitattr(lfs_t *lfs, const char *path,
3031
3022
}
3032
3023
}
3033
3024
3034
- return lfs_dir_commit (lfs , & cwd ,
3035
- LFS_MKATTR (LFS_TYPE_USERATTR + type , id , buffer , size ,
3036
- NULL ));
3025
+ return lfs_dir_commit (lfs , & cwd , LFS_MKATTRS (
3026
+ {LFS_MKTAG (LFS_TYPE_USERATTR + type , id , size ), buffer }));
3037
3027
}
3038
3028
3039
3029
int lfs_setattr (lfs_t * lfs , const char * path ,
@@ -3198,12 +3188,11 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
3198
3188
};
3199
3189
3200
3190
lfs_superblock_tole32 (& superblock );
3201
- err = lfs_dir_commit (lfs , & root ,
3202
- LFS_MKATTR (LFS_TYPE_INLINESTRUCT , 0 ,
3203
- & superblock , sizeof (superblock ),
3204
- LFS_MKATTR (LFS_TYPE_SUPERBLOCK , 0 , "littlefs" , 8 ,
3205
- LFS_MKATTR (LFS_TYPE_CREATE , 0 , NULL , 0 ,
3206
- NULL ))));
3191
+ err = lfs_dir_commit (lfs , & root , LFS_MKATTRS (
3192
+ {LFS_MKTAG (LFS_TYPE_CREATE , 0 , 0 )},
3193
+ {LFS_MKTAG (LFS_TYPE_SUPERBLOCK , 0 , 8 ), "littlefs" },
3194
+ {LFS_MKTAG (LFS_TYPE_INLINESTRUCT , 0 , sizeof (superblock )),
3195
+ & superblock }));
3207
3196
if (err ) {
3208
3197
goto cleanup ;
3209
3198
}
@@ -3516,8 +3505,7 @@ static int lfs_fs_relocate(lfs_t *lfs,
3516
3505
lfs_fs_preporphans (lfs , +1 );
3517
3506
3518
3507
lfs_pair_tole32 (newpair );
3519
- int err = lfs_dir_commit (lfs , & parent ,
3520
- & (struct lfs_mattr ){.tag = tag , .buffer = newpair });
3508
+ int err = lfs_dir_commit (lfs , & parent , LFS_MKATTRS ({tag , newpair }));
3521
3509
lfs_pair_fromle32 (newpair );
3522
3510
if (err ) {
3523
3511
return err ;
@@ -3537,9 +3525,8 @@ static int lfs_fs_relocate(lfs_t *lfs,
3537
3525
if (err != LFS_ERR_NOENT ) {
3538
3526
// replace bad pair, either we clean up desync, or no desync occured
3539
3527
lfs_pair_tole32 (newpair );
3540
- err = lfs_dir_commit (lfs , & parent ,
3541
- LFS_MKATTR (LFS_TYPE_TAIL + parent .split , 0x3ff , newpair , 8 ,
3542
- NULL ));
3528
+ err = lfs_dir_commit (lfs , & parent , LFS_MKATTRS (
3529
+ {LFS_MKTAG (LFS_TYPE_TAIL + parent .split , 0x3ff , 8 ), newpair }));
3543
3530
lfs_pair_fromle32 (newpair );
3544
3531
if (err ) {
3545
3532
return err ;
@@ -3600,7 +3587,7 @@ static int lfs_fs_demove(lfs_t *lfs) {
3600
3587
}
3601
3588
3602
3589
// rely on cancel logic inside commit
3603
- err = lfs_dir_commit (lfs , & movedir , NULL );
3590
+ err = lfs_dir_commit (lfs , & movedir , NULL , 0 );
3604
3591
if (err ) {
3605
3592
return err ;
3606
3593
}
@@ -3660,9 +3647,8 @@ static int lfs_fs_deorphan(lfs_t *lfs) {
3660
3647
pair [0 ], pair [1 ]);
3661
3648
3662
3649
lfs_pair_tole32 (pair );
3663
- err = lfs_dir_commit (lfs , & pdir ,
3664
- LFS_MKATTR (LFS_TYPE_SOFTTAIL , 0x3ff , pair , 8 ,
3665
- NULL ));
3650
+ err = lfs_dir_commit (lfs , & pdir , LFS_MKATTRS (
3651
+ {LFS_MKTAG (LFS_TYPE_SOFTTAIL , 0x3ff , 8 ), pair }));
3666
3652
lfs_pair_fromle32 (pair );
3667
3653
if (err ) {
3668
3654
return err ;
0 commit comments