Files
littlefs/tests
Christopher Haster e8b68c4e88 Tweaked how recursive removes interact with dir read again
Hopefully third times the charm.

The previous solution pretty bluntly did not work outside of the
recursive remove case, because the moment we mark the rid as deleted,
the directory positions no longer get updates. It's not possible to
update the directory position because we don't know how it maps into our
mtree without a full seek from the dstart.

After staring at it a bit, I think this solution should work:

1. Instead of marking the mid/rid as removed when dropping an mdir, we
   set the weight to zero and the trunk to zero, causing mdir lookups to
   return NOENT without actually going to disk.

   This is very important since later mdirs could be allocated on the
   same block, and going to disk can result in a corrupted lookup.

2. Eagerly seek to the next mid/rid after every lfsr_dir_read call. This
   puts us in a position where rid can be >= the current mdir weight
   without issues, and avoids degenerate cases that may be caused by
   recursive removes.

3. If we remove an opened dir, instead of marking the mdir as deleted,
   move the rid to the next rid. If the mdir was dropped, this leaves us
   with rid == mdir weight, and the mdir trunk == 0.

   The rid == mdir weight also occurs when we are creating a new file, so
   we have a bit of common behavior we can rely on. We just need to make
   sure that mdir updates respect the rid == mdir weight situation.

4. On each lfsr_dir_read call, we do an mtree seek of zero. This just
   serves to fix our mdir if our rid == mdir weight, without much
   additional code (yay for code reuse).

The use of weight=0, trunk=0, for a dropped mdir here is key, and makes
me wonder if this is a better indicator of a dropped mdir than another
reserved mid value. This probably deserves some investigation later.
2023-07-25 13:19:39 -05:00
..