@@ -364,7 +364,7 @@ static void lfs_alloc_ack(lfs_t *lfs) {
364
364
// d->block_count = lfs_fromle32(d->block_count);
365
365
// d->version = lfs_fromle32(d->version);
366
366
// d->inline_size = lfs_fromle32(d->inline_size);
367
- // d->attrs_size = lfs_fromle32(d->attrs_size );
367
+ // d->attr_size = lfs_fromle32(d->attr_size );
368
368
// d->name_size = lfs_fromle32(d->name_size);
369
369
//}
370
370
//
@@ -375,7 +375,7 @@ static void lfs_alloc_ack(lfs_t *lfs) {
375
375
// d->block_count = lfs_tole32(d->block_count);
376
376
// d->version = lfs_tole32(d->version);
377
377
// d->inline_size = lfs_tole32(d->inline_size);
378
- // d->attrs_size = lfs_tole32(d->attrs_size );
378
+ // d->attr_size = lfs_tole32(d->attr_size );
379
379
// d->name_size = lfs_tole32(d->name_size);
380
380
//}
381
381
@@ -430,7 +430,7 @@ static inline bool lfs_pairsync(
430
430
(((uint32_t)(type) << 22) | ((uint32_t)(id) << 12) | (uint32_t)(size))
431
431
432
432
#define LFS_MKATTR (type , id , buffer , size , next ) \
433
- &(const lfs_mattr_t){(next), LFS_MKTAG(type, id, size), (buffer)}
433
+ &(const lfs_mattr_t){LFS_MKTAG(type, id, size), (buffer), (next )}
434
434
435
435
static inline bool lfs_tagisvalid (uint32_t tag ) {
436
436
return !(tag & 0x80000000 );
@@ -526,13 +526,20 @@ static int32_t lfs_commitget(lfs_t *lfs, lfs_block_t block, lfs_off_t off,
526
526
return LFS_ERR_NOENT ;
527
527
}
528
528
529
+ static int lfs_commitattrs (lfs_t * lfs , struct lfs_commit * commit ,
530
+ uint16_t id , const struct lfs_attr * attrs );
531
+
529
532
static int lfs_commitmove (lfs_t * lfs , struct lfs_commit * commit ,
530
533
uint16_t fromid , uint16_t toid ,
531
534
const lfs_mdir_t * dir , const lfs_mattr_t * attrs );
532
535
533
536
static int lfs_commitattr (lfs_t * lfs , struct lfs_commit * commit ,
534
537
uint32_t tag , const void * buffer ) {
535
- if (lfs_tagtype (tag ) == LFS_FROM_MOVE ) {
538
+ if (lfs_tagtype (tag ) == LFS_FROM_ATTRS ) {
539
+ // special case for custom attributes
540
+ return lfs_commitattrs (lfs , commit ,
541
+ lfs_tagid (tag ), buffer );
542
+ } else if (lfs_tagtype (tag ) == LFS_FROM_MOVE ) {
536
543
// special case for moves
537
544
return lfs_commitmove (lfs , commit ,
538
545
lfs_tagsize (tag ), lfs_tagid (tag ),
@@ -586,6 +593,19 @@ static int lfs_commitattr(lfs_t *lfs, struct lfs_commit *commit,
586
593
return 0 ;
587
594
}
588
595
596
+ static int lfs_commitattrs (lfs_t * lfs , struct lfs_commit * commit ,
597
+ uint16_t id , const struct lfs_attr * attrs ) {
598
+ for (const struct lfs_attr * a = attrs ; a ; a = a -> next ) {
599
+ int err = lfs_commitattr (lfs , commit ,
600
+ LFS_MKTAG (0x100 | a -> type , id , a -> size ), a -> buffer );
601
+ if (err ) {
602
+ return err ;
603
+ }
604
+ }
605
+
606
+ return 0 ;
607
+ }
608
+
589
609
static int lfs_commitmove (lfs_t * lfs , struct lfs_commit * commit ,
590
610
uint16_t fromid , uint16_t toid ,
591
611
const lfs_mdir_t * dir , const lfs_mattr_t * attrs ) {
@@ -1378,9 +1398,6 @@ static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir,
1378
1398
}
1379
1399
1380
1400
info -> type = lfs_tagtype (tag );
1381
- if (lfs_tagsize (tag ) > lfs -> name_size ) {
1382
- return LFS_ERR_RANGE ;
1383
- }
1384
1401
1385
1402
struct lfs_ctz ctz ;
1386
1403
tag = lfs_dir_get (lfs , dir , 0x7c3ff000 ,
@@ -1410,7 +1427,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
1410
1427
1411
1428
lfs_mdir_t cwd ;
1412
1429
int32_t res = lfs_dir_lookup (lfs , & cwd , & path );
1413
- if (res != LFS_ERR_NOENT || ! path ) {
1430
+ if (!( res == LFS_ERR_NOENT && path ) ) {
1414
1431
return (res < 0 ) ? res : LFS_ERR_EXIST ;
1415
1432
}
1416
1433
@@ -1792,8 +1809,9 @@ static int lfs_ctztraverse(lfs_t *lfs,
1792
1809
1793
1810
1794
1811
/// Top level file operations ///
1795
- int lfs_file_open (lfs_t * lfs , lfs_file_t * file ,
1796
- const char * path , int flags ) {
1812
+ int lfs_file_opencfg (lfs_t * lfs , lfs_file_t * file ,
1813
+ const char * path , int flags ,
1814
+ const struct lfs_file_config * cfg ) {
1797
1815
// deorphan if we haven't yet, needed at most once after poweron
1798
1816
if ((flags & 3 ) != LFS_O_RDONLY && !lfs -> deorphaned ) {
1799
1817
int err = lfs_deorphan (lfs );
@@ -1805,7 +1823,7 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
1805
1823
// allocate entry for file if it doesn't exist
1806
1824
lfs_mdir_t cwd ;
1807
1825
int32_t tag = lfs_dir_lookup (lfs , & cwd , & path );
1808
- if (tag < 0 && (tag != LFS_ERR_NOENT || ! path )) {
1826
+ if (tag < 0 && ! (tag == LFS_ERR_NOENT && path )) {
1809
1827
return tag ;
1810
1828
}
1811
1829
@@ -1859,16 +1877,42 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
1859
1877
}
1860
1878
1861
1879
// setup file struct
1880
+ file -> cfg = cfg ;
1862
1881
file -> pair [0 ] = cwd .pair [0 ];
1863
1882
file -> pair [1 ] = cwd .pair [1 ];
1864
1883
file -> id = lfs_tagid (tag );
1865
1884
file -> flags = flags ;
1866
1885
file -> pos = 0 ;
1867
1886
file -> attrs = NULL ;
1868
1887
1888
+ if (cfg && cfg -> attrs ) {
1889
+ // fetch attrs
1890
+ for (const struct lfs_attr * a = cfg -> attrs ; a ; a = a -> next ) {
1891
+ if ((file -> flags & 3 ) != LFS_O_WRONLY ) {
1892
+ int32_t res = lfs_dir_get (lfs , & cwd , 0x7ffff000 ,
1893
+ LFS_MKTAG (0x100 | a -> type , file -> id , a -> size ), a -> buffer );
1894
+ if (res < 0 && res != LFS_ERR_NOENT ) {
1895
+ return res ;
1896
+ }
1897
+ }
1898
+
1899
+ if ((file -> flags & 3 ) != LFS_O_RDONLY ) {
1900
+ if (a -> size > lfs -> attr_size ) {
1901
+ return LFS_ERR_NOSPC ;
1902
+ }
1903
+
1904
+ file -> flags |= LFS_F_DIRTY ;
1905
+ }
1906
+ }
1907
+
1908
+ file -> attrs = cfg -> attrs ;
1909
+ }
1910
+
1869
1911
// allocate buffer if needed
1870
1912
file -> cache .block = 0xffffffff ;
1871
- if (lfs -> cfg -> file_buffer ) {
1913
+ if (file -> cfg && file -> cfg -> buffer ) {
1914
+ file -> cache .buffer = file -> cfg -> buffer ;
1915
+ } else if (lfs -> cfg -> file_buffer ) {
1872
1916
file -> cache .buffer = lfs -> cfg -> file_buffer ;
1873
1917
} else if ((file -> flags & 3 ) == LFS_O_RDONLY ) {
1874
1918
file -> cache .buffer = lfs_malloc (lfs -> cfg -> read_size );
@@ -1909,6 +1953,11 @@ int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
1909
1953
return 0 ;
1910
1954
}
1911
1955
1956
+ int lfs_file_open (lfs_t * lfs , lfs_file_t * file ,
1957
+ const char * path , int flags ) {
1958
+ return lfs_file_opencfg (lfs , file , path , flags , NULL );
1959
+ }
1960
+
1912
1961
int lfs_file_close (lfs_t * lfs , lfs_file_t * file ) {
1913
1962
int err = lfs_file_sync (lfs , file );
1914
1963
@@ -1921,7 +1970,7 @@ int lfs_file_close(lfs_t *lfs, lfs_file_t *file) {
1921
1970
}
1922
1971
1923
1972
// clean up memory
1924
- if (!lfs -> cfg -> file_buffer ) {
1973
+ if (!( file -> cfg && file -> cfg -> buffer ) && ! lfs -> cfg -> file_buffer ) {
1925
1974
lfs_free (file -> cache .buffer );
1926
1975
}
1927
1976
@@ -2071,15 +2120,17 @@ int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) {
2071
2120
int err = lfs_dir_commit (lfs , & cwd ,
2072
2121
LFS_MKATTR (LFS_TYPE_CTZSTRUCT , file -> id ,
2073
2122
& file -> ctz .head , sizeof (file -> ctz ),
2074
- file -> attrs ));
2123
+ LFS_MKATTR (LFS_FROM_ATTRS , file -> id , file -> attrs , 0 ,
2124
+ NULL )));
2075
2125
if (err ) {
2076
2126
return err ;
2077
2127
}
2078
2128
} else {
2079
2129
int err = lfs_dir_commit (lfs , & cwd ,
2080
2130
LFS_MKATTR (LFS_TYPE_INLINESTRUCT , file -> id ,
2081
2131
file -> cache .buffer , file -> ctz .size ,
2082
- file -> attrs ));
2132
+ LFS_MKATTR (LFS_FROM_ATTRS , file -> id , file -> attrs , 0 ,
2133
+ NULL )));
2083
2134
if (err ) {
2084
2135
return err ;
2085
2136
}
@@ -2688,7 +2739,85 @@ int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) {
2688
2739
return 0 ;
2689
2740
}
2690
2741
2691
- //int lfs_getattrs(lfs_t *lfs, const char *path,
2742
+ lfs_ssize_t lfs_getattr (lfs_t * lfs , const char * path ,
2743
+ uint8_t type , void * buffer , lfs_size_t size ) {
2744
+ lfs_mdir_t cwd ;
2745
+ int32_t res = lfs_dir_lookup (lfs , & cwd , & path );
2746
+ if (res < 0 ) {
2747
+ return res ;
2748
+ }
2749
+
2750
+ res = lfs_dir_get (lfs , & cwd , 0x7ffff000 ,
2751
+ LFS_MKTAG (0x100 | type , lfs_tagid (res ),
2752
+ lfs_min (size , lfs -> attr_size )), buffer );
2753
+ if (res < 0 ) {
2754
+ if (res == LFS_ERR_NOENT ) {
2755
+ return LFS_ERR_NOATTR ;
2756
+ }
2757
+ return res ;
2758
+ }
2759
+
2760
+ return lfs_tagsize (res );
2761
+ }
2762
+
2763
+ int lfs_setattr (lfs_t * lfs , const char * path ,
2764
+ uint8_t type , const void * buffer , lfs_size_t size ) {
2765
+ if (size > lfs -> attr_size ) {
2766
+ return LFS_ERR_NOSPC ;
2767
+ }
2768
+
2769
+ lfs_mdir_t cwd ;
2770
+ int32_t res = lfs_dir_lookup (lfs , & cwd , & path );
2771
+ if (res < 0 ) {
2772
+ return res ;
2773
+ }
2774
+
2775
+ return lfs_dir_commit (lfs , & cwd ,
2776
+ LFS_MKATTR (0x100 | type , lfs_tagid (res ), buffer , size ,
2777
+ NULL ));
2778
+ }
2779
+
2780
+ lfs_ssize_t lfs_fs_getattr (lfs_t * lfs ,
2781
+ uint8_t type , void * buffer , lfs_size_t size ) {
2782
+ lfs_mdir_t superdir ;
2783
+ int err = lfs_dir_fetch (lfs , & superdir , (const lfs_block_t [2 ]){0 , 1 });
2784
+ if (err ) {
2785
+ return err ;
2786
+ }
2787
+
2788
+ int32_t res = lfs_dir_get (lfs , & superdir , 0x7ffff000 ,
2789
+ LFS_MKTAG (0x100 | type , 0 ,
2790
+ lfs_min (size , lfs -> attr_size )), buffer );
2791
+ if (res < 0 ) {
2792
+ if (res == LFS_ERR_NOENT ) {
2793
+ return LFS_ERR_NOATTR ;
2794
+ }
2795
+ return res ;
2796
+ }
2797
+
2798
+ return lfs_tagsize (res );
2799
+ }
2800
+
2801
+ int lfs_fs_setattr (lfs_t * lfs ,
2802
+ uint8_t type , const void * buffer , lfs_size_t size ) {
2803
+ if (size > lfs -> attr_size ) {
2804
+ return LFS_ERR_NOSPC ;
2805
+ }
2806
+
2807
+ lfs_mdir_t superdir ;
2808
+ int err = lfs_dir_fetch (lfs , & superdir , (const lfs_block_t [2 ]){0 , 1 });
2809
+ if (err ) {
2810
+ return err ;
2811
+ }
2812
+
2813
+ return lfs_dir_commit (lfs , & superdir ,
2814
+ LFS_MKATTR (0x100 | type , 0 , buffer , size ,
2815
+ NULL ));
2816
+ }
2817
+
2818
+ //
2819
+ //
2820
+ //
2692
2821
// const struct lfs_attr *attrs, int count) {
2693
2822
// lfs_mdir_t cwd;
2694
2823
// int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
@@ -2777,10 +2906,10 @@ static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) {
2777
2906
lfs -> inline_size = lfs_min (LFS_INLINE_MAX , lfs -> cfg -> read_size );
2778
2907
}
2779
2908
2780
- LFS_ASSERT (lfs -> cfg -> attrs_size <= LFS_ATTRS_MAX );
2781
- lfs -> attrs_size = lfs -> cfg -> attrs_size ;
2782
- if (!lfs -> attrs_size ) {
2783
- lfs -> attrs_size = LFS_ATTRS_MAX ;
2909
+ LFS_ASSERT (lfs -> cfg -> attr_size <= LFS_ATTR_MAX );
2910
+ lfs -> attr_size = lfs -> cfg -> attr_size ;
2911
+ if (!lfs -> attr_size ) {
2912
+ lfs -> attr_size = LFS_ATTR_MAX ;
2784
2913
}
2785
2914
2786
2915
LFS_ASSERT (lfs -> cfg -> name_size <= LFS_NAME_MAX );
@@ -2873,7 +3002,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) {
2873
3002
.block_size = lfs -> cfg -> block_size ,
2874
3003
.block_count = lfs -> cfg -> block_count ,
2875
3004
.inline_size = lfs -> inline_size ,
2876
- .attrs_size = lfs -> attrs_size ,
3005
+ .attr_size = lfs -> attr_size ,
2877
3006
.name_size = lfs -> name_size ,
2878
3007
};
2879
3008
@@ -2954,14 +3083,14 @@ int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) {
2954
3083
lfs -> inline_size = superblock .inline_size ;
2955
3084
}
2956
3085
2957
- if (superblock .attrs_size ) {
2958
- if (superblock .attrs_size > lfs -> attrs_size ) {
2959
- LFS_ERROR ("Unsupported attrs size (%d > %d)" ,
2960
- superblock .attrs_size , lfs -> attrs_size );
3086
+ if (superblock .attr_size ) {
3087
+ if (superblock .attr_size > lfs -> attr_size ) {
3088
+ LFS_ERROR ("Unsupported attr size (%d > %d)" ,
3089
+ superblock .attr_size , lfs -> attr_size );
2961
3090
return LFS_ERR_INVAL ;
2962
3091
}
2963
3092
2964
- lfs -> attrs_size = superblock .attrs_size ;
3093
+ lfs -> attr_size = superblock .attr_size ;
2965
3094
}
2966
3095
2967
3096
if (superblock .name_size ) {
0 commit comments