@@ -522,8 +522,7 @@ static int lfs_pair_shift(lfs_t *lfs, lfs_block_t pair[2],
522
522
523
523
/// Directory operations ///
524
524
525
- static int lfs_dir_alloc (lfs_t * lfs , lfs_dir_t * dir ,
526
- lfs_block_t parent [2 ], lfs_block_t tail [2 ]) {
525
+ static int lfs_dir_alloc (lfs_t * lfs , lfs_dir_t * dir , lfs_block_t tail [2 ]) {
527
526
// Allocate pair of dir blocks
528
527
for (int i = 0 ; i < 2 ; i ++ ) {
529
528
int err = lfs_alloc (lfs , & dir -> pair [i ]);
@@ -549,35 +548,10 @@ static int lfs_dir_alloc(lfs_t *lfs, lfs_dir_t *dir,
549
548
dir -> d .tail [1 ] = tail [1 ];
550
549
551
550
// Write out to memory
552
- if (!parent ) {
553
- return lfs_pair_commit (lfs , dir -> pair ,
554
- 1 , (struct lfs_commit_region []){
555
- {0 , sizeof (dir -> d ), & dir -> d }
556
- });
557
- } else {
558
- dir -> d .size += 2 * sizeof (struct lfs_disk_entry ) + 3 ;
559
- return lfs_pair_commit (lfs , dir -> pair ,
560
- 5 , (struct lfs_commit_region []){
561
- {0 , sizeof (dir -> d ), & dir -> d },
562
- {sizeof (dir -> d ), sizeof (struct lfs_disk_entry ),
563
- & (struct lfs_disk_entry ){
564
- .type = LFS_TYPE_DIR ,
565
- .len = sizeof (struct lfs_disk_entry )+1 ,
566
- .u .dir [0 ] = dir -> pair [0 ],
567
- .u .dir [1 ] = dir -> pair [1 ],
568
- }},
569
- {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry ), 1 , "." },
570
- {sizeof (dir -> d )+ sizeof (struct lfs_disk_entry )+1 ,
571
- sizeof (struct lfs_disk_entry ),
572
- & (struct lfs_disk_entry ){
573
- .type = LFS_TYPE_DIR ,
574
- .len = sizeof (struct lfs_disk_entry )+2 ,
575
- .u .dir [0 ] = parent [0 ] ? parent [0 ] : dir -> pair [0 ],
576
- .u .dir [1 ] = parent [1 ] ? parent [1 ] : dir -> pair [1 ],
577
- }},
578
- {sizeof (dir -> d )+ 2 * sizeof (struct lfs_disk_entry )+1 , 2 , ".." },
579
- });
580
- }
551
+ return lfs_pair_commit (lfs , dir -> pair ,
552
+ 1 , (struct lfs_commit_region []){
553
+ {0 , sizeof (dir -> d ), & dir -> d }
554
+ });
581
555
}
582
556
583
557
static int lfs_dir_fetch (lfs_t * lfs , lfs_dir_t * dir , lfs_block_t pair [2 ]) {
@@ -725,7 +699,7 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
725
699
lfs_dir_t olddir ;
726
700
memcpy (& olddir , dir , sizeof (olddir ));
727
701
728
- int err = lfs_dir_alloc (lfs , dir , 0 , olddir .d .tail );
702
+ int err = lfs_dir_alloc (lfs , dir , olddir .d .tail );
729
703
if (err ) {
730
704
return err ;
731
705
}
@@ -763,7 +737,7 @@ int lfs_mkdir(lfs_t *lfs, const char *path) {
763
737
764
738
// Build up new directory
765
739
lfs_dir_t dir ;
766
- err = lfs_dir_alloc (lfs , & dir , cwd .pair , cwd . d .tail );
740
+ err = lfs_dir_alloc (lfs , & dir , cwd .d .tail );
767
741
if (err ) {
768
742
return err ;
769
743
}
@@ -799,6 +773,8 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
799
773
if (err ) {
800
774
return err ;
801
775
} else if (strcmp (path , "/" ) == 0 ) {
776
+ // special offset for '.' and '..'
777
+ dir -> off = sizeof (dir -> d ) - 2 ;
802
778
return 0 ;
803
779
}
804
780
@@ -810,7 +786,14 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
810
786
return LFS_ERROR_NOT_DIR ;
811
787
}
812
788
813
- return lfs_dir_fetch (lfs , dir , entry .d .u .dir );
789
+ err = lfs_dir_fetch (lfs , dir , entry .d .u .dir );
790
+ if (err ) {
791
+ return err ;
792
+ }
793
+
794
+ // special offset for '.' and '..'
795
+ dir -> off = sizeof (dir -> d ) - 2 ;
796
+ return 0 ;
814
797
}
815
798
816
799
int lfs_dir_close (lfs_t * lfs , lfs_dir_t * dir ) {
@@ -821,6 +804,18 @@ int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) {
821
804
int lfs_dir_read (lfs_t * lfs , lfs_dir_t * dir , struct lfs_info * info ) {
822
805
memset (info , 0 , sizeof (* info ));
823
806
807
+ if (dir -> off == sizeof (dir -> d ) - 2 ) {
808
+ info -> type = LFS_TYPE_DIR ;
809
+ strcpy (info -> name , "." );
810
+ dir -> off += 1 ;
811
+ return 1 ;
812
+ } else if (dir -> off == sizeof (dir -> d ) - 1 ) {
813
+ info -> type = LFS_TYPE_DIR ;
814
+ strcpy (info -> name , ".." );
815
+ dir -> off += 1 ;
816
+ return 1 ;
817
+ }
818
+
824
819
lfs_entry_t entry ;
825
820
int err = lfs_dir_next (lfs , dir , & entry );
826
821
if (err ) {
@@ -1100,8 +1095,7 @@ int lfs_format(lfs_t *lfs, const struct lfs_config *config) {
1100
1095
1101
1096
// Write root directory
1102
1097
lfs_dir_t root ;
1103
- err = lfs_dir_alloc (lfs , & root ,
1104
- (lfs_block_t [2 ]){0 , 0 }, (lfs_block_t [2 ]){0 , 0 });
1098
+ err = lfs_dir_alloc (lfs , & root , (lfs_block_t [2 ]){0 , 0 });
1105
1099
if (err ) {
1106
1100
return err ;
1107
1101
}
@@ -1195,9 +1189,6 @@ int lfs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) {
1195
1189
return err ;
1196
1190
}
1197
1191
1198
- // skip '.' and '..'
1199
- dir .off += 2 * sizeof (struct lfs_disk_entry ) + 3 ;
1200
-
1201
1192
// iterate over contents
1202
1193
while ((0x7fffffff & dir .d .size ) >= dir .off + sizeof (file .entry .d )) {
1203
1194
int err = lfs_bd_read (lfs , dir .pair [0 ], dir .off ,
@@ -1248,14 +1239,6 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {
1248
1239
return err ;
1249
1240
}
1250
1241
1251
- // skip .. and . entries
1252
- for (int i = 0 ; i < 2 ; i ++ ) {
1253
- int err = lfs_dir_next (lfs , & parent , & entry );
1254
- if (err ) {
1255
- return err ;
1256
- }
1257
- }
1258
-
1259
1242
while (true) {
1260
1243
int err = lfs_dir_next (lfs , & parent , & entry );
1261
1244
if (err && err != LFS_ERROR_NO_ENTRY ) {
@@ -1339,12 +1322,13 @@ int lfs_remove(lfs_t *lfs, const char *path) {
1339
1322
1340
1323
lfs_dir_t dir ;
1341
1324
if (entry .d .type == LFS_TYPE_DIR ) {
1342
- // must be empty before removal
1325
+ // must be empty before removal, checking size
1326
+ // without masking top bit checks for any case where
1327
+ // dir is not empty
1343
1328
int err = lfs_dir_fetch (lfs , & dir , entry .d .u .dir );
1344
1329
if (err ) {
1345
1330
return err ;
1346
- } else if (dir .d .size != sizeof (dir .d ) +
1347
- 2 * sizeof (struct lfs_disk_entry ) + 3 ) {
1331
+ } else if (dir .d .size != sizeof (dir .d )) {
1348
1332
return LFS_ERROR_INVALID ;
1349
1333
}
1350
1334
}
@@ -1367,16 +1351,28 @@ int lfs_remove(lfs_t *lfs, const char *path) {
1367
1351
}
1368
1352
}
1369
1353
1370
- pdir .d .tail [0 ] = cwd .d .tail [0 ];
1371
- pdir .d .tail [1 ] = cwd .d .tail [1 ];
1372
- pdir .d .rev += 1 ;
1354
+ // TODO easier check for head block? (common case)
1355
+ if (!(pdir .d .size & 0x80000000 )) {
1356
+ int err = lfs_pair_shift (lfs , entry .dir ,
1357
+ 1 , (struct lfs_commit_region []) {
1358
+ {0 , sizeof (cwd .d ), & cwd .d },
1359
+ },
1360
+ entry .off , entry .d .len );
1361
+ if (err ) {
1362
+ return err ;
1363
+ }
1364
+ } else {
1365
+ pdir .d .tail [0 ] = cwd .d .tail [0 ];
1366
+ pdir .d .tail [1 ] = cwd .d .tail [1 ];
1367
+ pdir .d .rev += 1 ;
1373
1368
1374
- err = lfs_pair_commit (lfs , pdir .pair ,
1375
- 1 , (struct lfs_commit_region []) {
1376
- {0 , sizeof (pdir .d ), & pdir .d },
1377
- });
1378
- if (err ) {
1379
- return err ;
1369
+ err = lfs_pair_commit (lfs , pdir .pair ,
1370
+ 1 , (struct lfs_commit_region []) {
1371
+ {0 , sizeof (pdir .d ), & pdir .d },
1372
+ });
1373
+ if (err ) {
1374
+ return err ;
1375
+ }
1380
1376
}
1381
1377
} else {
1382
1378
int err = lfs_pair_shift (lfs , entry .dir ,
0 commit comments