@@ -256,34 +256,39 @@ static inline bool lfs_pairisnull(const lfs_block_t pair[2]) {
256
256
static inline int lfs_paircmp (
257
257
const lfs_block_t paira [2 ],
258
258
const lfs_block_t pairb [2 ]) {
259
- return !(( paira [0 ] == pairb [0 ] && paira [1 ] == pairb [1 ]) ||
260
- ( paira [0 ] == pairb [1 ] && paira [1 ] == pairb [0 ]) );
259
+ return !(paira [0 ] == pairb [0 ] || paira [1 ] == pairb [1 ] ||
260
+ paira [0 ] == pairb [1 ] || paira [1 ] == pairb [0 ]);
261
261
}
262
262
263
263
static int lfs_dir_alloc (lfs_t * lfs , lfs_dir_t * dir ) {
264
- // Allocate pair of dir blocks
264
+ // allocate pair of dir blocks
265
265
for (int i = 0 ; i < 2 ; i ++ ) {
266
266
int err = lfs_alloc (lfs , & dir -> pair [i ]);
267
267
if (err ) {
268
268
return err ;
269
269
}
270
270
}
271
271
272
- // Rather than clobbering one of the blocks we just pretend
272
+ // we couldn't find unique blocks, we're out of space
273
+ if (dir -> pair [0 ] == dir -> pair [1 ]) {
274
+ return LFS_ERR_NOSPC ;
275
+ }
276
+
277
+ // rather than clobbering one of the blocks we just pretend
273
278
// the revision may be valid
274
279
int err = lfs_bd_read (lfs , dir -> pair [0 ], 0 , & dir -> d .rev , 4 );
275
280
if (err ) {
276
281
return err ;
277
282
}
278
283
279
- // Set defaults
284
+ // set defaults
280
285
dir -> d .rev += 1 ;
281
286
dir -> d .size = sizeof (dir -> d );
282
287
dir -> d .tail [0 ] = 0 ;
283
288
dir -> d .tail [1 ] = 0 ;
284
289
dir -> off = sizeof (dir -> d );
285
290
286
- // Don 't write out yet, let caller take care of that
291
+ // don 't write out yet, let caller take care of that
287
292
return 0 ;
288
293
}
289
294
@@ -484,13 +489,21 @@ static int lfs_dir_append(lfs_t *lfs, lfs_dir_t *dir,
484
489
return lfs_dir_commit (lfs , dir , entry , data );
485
490
}
486
491
492
+ // we need to allocate a new dir block
487
493
if (!(0x80000000 & dir -> d .size )) {
488
494
lfs_dir_t newdir ;
489
495
int err = lfs_dir_alloc (lfs , & newdir );
490
496
if (err ) {
491
497
return err ;
492
498
}
493
499
500
+ // our allocator doesn't track blocks before being appended,
501
+ // so even if we found some blocks, they may not be unique
502
+ if (entry -> d .type == LFS_TYPE_DIR &&
503
+ lfs_paircmp (entry -> d .u .dir , newdir .pair ) == 0 ) {
504
+ return LFS_ERR_NOSPC ;
505
+ }
506
+
494
507
newdir .d .tail [0 ] = dir -> d .tail [0 ];
495
508
newdir .d .tail [1 ] = dir -> d .tail [1 ];
496
509
entry -> off = newdir .d .size ;
@@ -1677,7 +1690,7 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {
1677
1690
.d .tail [1 ] = lfs -> root [1 ],
1678
1691
};
1679
1692
1680
- while (parent . d . tail [ 0 ] ) {
1693
+ while (true ) {
1681
1694
lfs_entry_t entry ;
1682
1695
int err = lfs_dir_fetch (lfs , & parent , parent .d .tail );
1683
1696
if (err ) {
@@ -1699,9 +1712,11 @@ static int lfs_parent(lfs_t *lfs, const lfs_block_t dir[2]) {
1699
1712
return true;
1700
1713
}
1701
1714
}
1702
- }
1703
1715
1704
- return false;
1716
+ if (lfs_pairisnull (parent .d .tail )) {
1717
+ return false;
1718
+ }
1719
+ }
1705
1720
}
1706
1721
1707
1722
int lfs_deorphan (lfs_t * lfs ) {
@@ -1715,31 +1730,34 @@ int lfs_deorphan(lfs_t *lfs) {
1715
1730
return err ;
1716
1731
}
1717
1732
1718
- while (pdir .d .tail [ 0 ] ) {
1733
+ while (! lfs_pairisnull ( pdir .d .tail ) ) {
1719
1734
int err = lfs_dir_fetch (lfs , & cdir , pdir .d .tail );
1720
1735
if (err ) {
1721
1736
return err ;
1722
1737
}
1723
1738
1724
- // check if we have a parent
1725
- int parent = lfs_parent (lfs , pdir .d .tail );
1726
- if (parent < 0 ) {
1727
- return parent ;
1728
- }
1739
+ // only check head blocks
1740
+ if (!(0x80000000 & pdir .d .size )) {
1741
+ // check if we have a parent
1742
+ int parent = lfs_parent (lfs , pdir .d .tail );
1743
+ if (parent < 0 ) {
1744
+ return parent ;
1745
+ }
1729
1746
1730
- if (!parent ) {
1731
- // we are an orphan
1732
- LFS_DEBUG ("Orphan %d %d" , pdir .d .tail [0 ], pdir .d .tail [1 ]);
1747
+ if (!parent ) {
1748
+ // we are an orphan
1749
+ LFS_DEBUG ("Orphan %d %d" , pdir .d .tail [0 ], pdir .d .tail [1 ]);
1733
1750
1734
- pdir .d .tail [0 ] = cdir .d .tail [0 ];
1735
- pdir .d .tail [1 ] = cdir .d .tail [1 ];
1751
+ pdir .d .tail [0 ] = cdir .d .tail [0 ];
1752
+ pdir .d .tail [1 ] = cdir .d .tail [1 ];
1736
1753
1737
- err = lfs_dir_commit (lfs , & pdir , NULL , NULL );
1738
- if (err ) {
1739
- return err ;
1740
- }
1754
+ err = lfs_dir_commit (lfs , & pdir , NULL , NULL );
1755
+ if (err ) {
1756
+ return err ;
1757
+ }
1741
1758
1742
- break ;
1759
+ break ;
1760
+ }
1743
1761
}
1744
1762
1745
1763
memcpy (& pdir , & cdir , sizeof (pdir ));
0 commit comments