littlefs-project / littlefs

A little fail-safe filesystem designed for microcontrollers
BSD 3-Clause "New" or "Revised" License
5.11k stars 789 forks source link

Hard tail, soft tail, and pointers in LFS_TYPE_DIRSTRUCT? #834

Open test-sg opened 1 year ago

test-sg commented 1 year ago

What are these pointers? I can understand the English literally, but what exactly do they mean, and how are they used?

  1. Pointers in LFS_TYPE_DIRSTRUCT: points to the first metadata-pair in the directory. Does it mean it points to the first 'child' directory or file?
  2. Soft tail: points to the next metadata pair in the filesystem. What's the use? Is there any example?
  3. Hard tail: points to the next metadata pair in the directory. Is this similar to 1.? Except that it points to 2nd, 3rd, .. 'child' directory or file of the parent directory?

Sometimes 1. and 2. point to the same metadata-pair. Why?

geky commented 1 year ago

Ah yeah, the literal definition of the names really don't do any good here...

The hard/soft doesn't really mean anything except that the "tail pointer" can be in two states.

Some pictures may help here.

littlefs's metadata is really arranged into two overlapping data structures.

A filesystem tree, where each directory is a linked-list of metadata-pairs:

           .-------.  .-------.
           | dir A |->| dir A |
           |       |  |       |
           |       |  |       |
           '-------'  '-------' 
             |   |        '-------------------------. <- dir pointer
    .--------'   '----------.                       |
    v                       v                       v
.-------.  .-------.    .-------.  .-------.    .-------.
|dir A/B|->|dir A/B|    |dir A/C|->|dir A/C|    |dir A/D|
|       |  |       |    |       |^ |       |    |       |
|       |  |       |    |       || |       |    |       |
'-------'  '-------'    '-------'| '-------'    '-------'
                                 |
                             tail pointer

And a linked-list that allows for cheap traversal:

.-------.  .-------.    .-------.  .-------.    .-------.  .-------.    .-------.
| dir A |->| dir A |--->|dir A/B|->|dir A/B|--->|dir A/C|->|dir A/C|--->|dir A/D|
|       |^ |       |    |       |  |       | ^  |       |  |       |    |       |
|       || |       |    |       |  |       | |  |       |  |       |    |       |
'-------'| '-------'    '-------'  '-------' |  '-------'  '-------'    '-------'
         |                                   |
     tail pointer                      also a tail pointer

But if we look at the linked-list view, we don't actually know when one directory stops and another starts. This is where the hard/soft types of tails come in:

Putting these two views together, the total data structure looks like this:

              "hard" tail pointer
                       |
              .-------.v .-------.
              | dir A |->| dir A |-. <- "soft" tail pointer
              |       |  |       | |
.-------------|       |--|       |-'
|             '-------'  '-------' 
|               |   |        '-------------------------. <- dir pointer
|      .--------'   '----------.                       |
|      v                       v                       v
|  .-------.  .-------.    .-------.  .-------.    .-------.
'->|dir A/B|->|dir A/B|--->|dir A/C|->|dir A/C|--->|dir A/D|
   |       |^ |       |    |       |  |       | ^  |       |
   |       || |       |    |       |  |       | |  |       |
   '-------'| '-------'    '-------'  '-------' |  '-------'
            |                                   |
   "hard" tail pointer                 "soft" tail pointer

This is also why LFS_TYPE_DIRSTRUCT and LFSR_TYPE_SOFTTAIL can sometimes, but not always, point to the same metadata-pair.

The directories can appear in the linked-list in any order, the linked-list may look different for the same filesystem tree, depending on the order the directories were created in.

The "hard", "soft", and "tail" names have sort of lost all of there original meaning at this point...