1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openharmony-third_party_littlefs

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
SPEC.md 25 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 18:14 a21bfae

Техническая спецификация LittleFS

Это техническая спецификация файловой системы LittleFS с версией на диске lfs2.1. Этот документ описывает технические детали того, как LittleFS хранится на диске для интроспекции и инструментовки. Предполагается, что вы знакомы с дизайном LittleFS, для получения дополнительной информации о том, как работает LittleFS, обратитесь к DESIGN.md.

   | | |     .---._____
  .-----.   |          |
--|o    |---| littlefs |
--|     |---|          |
  '-----'   '----------'
   | | |

Некоторые быстрые заметки

  • LittleFS — это блочная файловая система. Диск разделён на массив блоков одинакового размера, которые используются в качестве логической единицы хранения.

  • Указатели блоков хранятся в 32 битах, специальное значение 0xffffffff представляет нулевой адрес блока.

  • Помимо логического размера блока (который обычно соответствует размеру стираемого блока), LittleFS также использует размер программного блока и размер читаемого блока. Они определяют выравнивание операций блочного устройства, но не обязательно должны быть согласованы для обеспечения переносимости.

  • По умолчанию все значения в LittleFS хранятся в порядке байтов с прямым порядком.

Пары каталогов / метаданных

Пары метаданных образуют основу LittleFS и обеспечивают систему распределённых атомарных обновлений. Даже суперблок хранится в паре метаданных.

Как следует из названия, пара метаданных хранится в двух блоках, один из которых обеспечивает резервную копию во время циклов стирания на случай потери питания. Эти два блока не обязательно последовательны и могут находиться где угодно на диске, поэтому «указатель» на пару метаданных сохраняется в виде двух указателей блоков.

Кроме того, каждый блок метаданных ведёт себя как добавляемый журнал, содержащий переменное количество фиксаций. Фиксации можно добавлять в журнал метаданных, чтобы обновлять метаданные без необходимости циклов стирания. Обратите внимание, что последующие фиксации могут заменять метаданные в предыдущих фиксациях. Только самые последние метаданные следует считать действительными.

Высокоуровневая структура блока метаданных довольно проста:

  .---------------------------------------.
.-|  revision count   |      entries      |  \
| |-------------------+                   |  |
| |                                       |  |
| |                                       |  +-- 1st commit
| |                                       |  |
| |                   +-------------------|  |
| |                   |        CRC        |  /
| |-------------------+-------------------|
| |                entries                |  \
| |                                       |  |
| |                                       |  +-- 2nd commit
| |    +-------------------+--------------|  |
| |    |        CRC        |    padding   |  /
| |----+-------------------+--------------|
| |                entries                |  \
| |                                       |  |
| |                                       |  +-- 3rd commit
| |         +-------------------+---------|  |
| |         |        CRC        |         |  /
| |---------+-------------------+         |
| |           unwritten storage           |  more commits
| |                                       |       |
| '---------------------------------------'
'---------------------------------------'

Каждый блок метаданных содержит 32-битный счётчик ревизий, за которым следует несколько фиксаций. Каждая фиксация содержит переменное число записей метаданных, за которыми следует 32-битная контрольная сумма циклическим избыточным кодом (CRC).

Также обратите внимание, что записи не обязательно выровнены по словам. Это позволяет нам хранить метаданные более компактно, однако мы можем записывать только по адресам, выровненным по нашему размеру программного блока. Это означает, что каждая фиксация может иметь заполнение для выравнивания.

Поля блока метаданных:

  1. Счётчик ревизий (32 бита) — увеличивается при каждом цикле стирания. Если оба блока содержат действительные фиксации, следует использовать только блок с самым последним счётчиком ревизий. Для избежания проблем с целочисленным переполнением необходимо использовать сравнение последовательностей.

  2. Контрольная сумма CRC В 3-битный абстрактный тип и 8-битное поле чанка. Обратите внимание, что значение 0x000 является недопустимым и не присваивается типу.

  3. Тип 1 (3 бита) — абстрактный тип тега. Группирует теги в 8 категорий, которые облегчают поиск с использованием битовых масок.

  4. Чанк (8 бит) — поле чанка используется для различных целей различными абстрактными типами. Тип 1 + чанк + идентификатор образуют уникальный идентификатор каждого тега в блоке метаданных.

  5. Идентификатор (10 бит) — идентификатор файла, связанный с тегом. Каждый файл в блоке метаданных получает уникальный идентификатор, который используется для связывания тегов с этим файлом. Специальное значение 0x3ff используется для любых тегов, которые не связаны с файлом, таких как каталог и глобальные метаданные.

  6. Длина (10 бит) — длина данных в байтах. Специальное значение 0x3ff указывает на то, что этот тег был удалён.

Типы метаданных

Далее следует исчерпывающий список метаданных в littlefs.


0x401 LFS_TYPE_CREATE

Создаёт новый файл с этим идентификатором. Обратите внимание, что файлы в блоке метаданных необязательно должны иметь тег создания. Всё, что делает создание, это перемещает любые файлы, использующие этот идентификатор. В этом смысле создание похоже на вставку в воображаемый массив файлов.

Теги создания и удаления позволяют littlefs хранить файлы в каталоге, упорядоченные по алфавиту по имени файла.


0x4ff LFS_TYPE_DELETE

Удаляет файл с этим идентификатором. Обратное созданию, этот тег перемещает любые соседние файлы этого идентификатора, подобно удалению из воображаемого массива файлов.


0x0xx LFS_TYPE_NAME

Связывает идентификатор с именем файла и типом файла.

Данные содержат имя файла, хранящееся в виде строки ASCII (в будущем может быть расширено до UTF8).

Поле чанка в этом теге указывает 8-битовый тип файла, который может быть одним из следующих.

В настоящее время тег имени должен предшествовать любым другим тегам, связанным с идентификатором, и не может быть переназначен без удаления файла.

Расположение тега имени:

        tag                          data
[--      32      --][---        variable length        ---]
[1| 3| 8 | 10 | 10 ][---          (size * 8)           ---]
 ^  ^  ^    ^    ^- размер                   ^- имя файла
 |  |  |    '------ идентификатор
 |  |  '----------- тип файла
 |  '-------------- тип 1 (0x0)
 '----------------- действительный бит

Поля имени:

  • тип файла (8 бит) — тип файла;

  • имя файла — имя файла хранится в виде строки ASCII.


0x001 LFS_TYPE_REG

Инициализирует идентификатор + имя как обычный файл.

Способ хранения каждого файла зависит от его структурного тега, который описан ниже.


0x002 LFS_TYPE_DIR

Инициализирует идентификатор + имя как каталог.

Каталоги в littlefs хранятся на диске в виде связанного списка пар метаданных, каждая пара содержит любое количество файлов в алфавитном порядке. Указатель на каталог хранится в структурном теге, который описан ниже.


0x0ff LFS_TYPE_SUPERBLOCK

Инициализирует идентификатор как запись суперблока.

Запись суперблока — это специальная запись, используемая для хранения конфигурации времени форматирования и идентификации файловой системы.

Название немного вводит в заблуждение. Хотя запись суперблока служит той же цели, что и суперблок, найденный в других файловых системах, в littlefs суперблоку не выделяется специальный блок. Вместо этого запись суперблока дублируется через связанный список пар метаданных, корни которых находятся на блоках 0 и 1. Последняя пара метаданных также служит корневым каталогом файловой системы.

 .--------.  .--------.  .--------.  .--------.  .--------.
.| супер  |->| супер  |->| супер  |->| супер  |->| файл B |
|| блок  | || блок  | || блок  | || блок  | || файл C |
||        | ||        | ||        | || файл A | || файл D |
|'--------' |'--------' |'--------' |'--------' |'--------'
'--------'  '--------'  '--------'  '--------'  '--------'

\----------------+----------------/ \----------+----------/
          суперблок пары               root directory

Файловая система начинается только с корневого каталога. Пары метаданных суперблока растут каждый раз, когда корневая пара сжимается, чтобы экспоненциально продлить срок службы устройства. Содержимое записи суперблока хранится в теге имени с типом суперблока и тегом встроенной структуры. Тег имени содержит магическую строку «littlefs», а тег встроенной структуры — информацию о версии и конфигурации.

Расположение тегов имени и встроенной структуры:

тег данные
[– 32 –] [– 32 – – 32 –]
^ ^ ^ - размер (8) ^ - магическая строка («littlefs»)
‘------------ тип (0x0ff)
‘----------------- действительный бит
тег данные
[– 32 –][– 32 – – 32 –
[1 - 11 -
^ ^ ^ ^ версия
^ блок-размер
^ блок-счётчик
^ - имя макс.
^ файл макс.
^ атрибут макс.
- размер (24)
‘------ id (0)
‘------------ тип (0x201)
‘----------------- действительный бит

Поля суперблока:

  1. Магическая строка (8 байт) — магическая строка, указывающая на наличие littlefs на устройстве. Должна быть строка «littlefs».
  2. Версия (32 бита) — версия littlefs во время форматирования. Версия кодируется 32-битным значением, где старшие 16 бит содержат основную версию, а младшие 16 бит — дополнительную версию. В этой спецификации описана версия 2.0 (0x00020000).
  3. Размер блока (32 бита) — размер логического размера блока, используемого файловой системой, в байтах.
  4. Счётчик блоков (32 бита) — количество блоков в файловой системе.
  5. Имя макс. (32 бита) — максимальный размер имён файлов в байтах.
  6. Файл макс. (32 бита) — максимальный размер файлов в байтах.
  7. Атрибут макс. (32 бита) — максимальный размер атрибутов файлов в байтах. Суперблок всегда должен быть первой записью (идентификатор 0) в паре метаданных, а также первой записью, записанной в блок. Это означает, что запись суперблока можно прочитать с устройства, используя только смещения.

LFS_TYPE_STRUCT 0x2xx Связывает идентификатор со структурой данных на диске. Точное расположение данных зависит от типа структуры данных, хранящегося в поле chunk, и может быть одним из следующих. Любой тип структуры заменяет все другие структуры, связанные с идентификатором. Например, добавление ctz-структуры заменяет встроенную структуру в том же файле.

LFS_TYPE_DIRSTRUCT 0x200 Придаёт идентификатору структуру данных каталога. Каталоги в littlefs хранятся на диске в виде связанного списка пар метаданных, каждая пара содержит любое количество файлов в алфавитном порядке.

Указатель на следующую пару метаданных в каталоге хранится в хвостовом теге, который описан ниже.

Расположение тега dir-struct:

тег данные
[– 32 –][– 32 – – 32 –]
[1 - 11 -
^- размер (8)
^- пара метаданных
^ - идентификатор
‘------------ тип (0x200)
‘----------------- действительный бит

Dir-struct поля:

  1. Пара метаданных (8 байт) — указатель на первую пару метаданных в каталоге. Размер каталога неизвестен без обхода каталога.

LFS_TYPE_INLINESTRUCT 0x201 Даёт идентификатору встроенные данные. Часть каталога (хвостовик жёсткий) или используется только для обхода файловой системы (хвостовик мягкий).

         .--------.
        .| dir A  |-.
        ||softtail| |
.--------|        |-'
|       |'--------'
|       '---|--|-'
|        .-'    '-------------.
|       v                      v
|  .--------.  .--------.  .--------.
'->| dir B  |->| dir B  |->| dir C  |
  ||hardtail| ||softtail| ||        |
  ||        | ||        | ||        |
  |'--------' |'--------' |'--------'
  '--------'  '--------'  '--------'

В настоящее время любой тип заменяет все предыдущие хвостовики в паре метаданных, но это может измениться, если будет добавлено дополнительное состояние пары метаданных.

Примечание о связанном списке пар метаданных: обычно этот связанный список содержит каждую пару метаданных в файловой системе. Однако есть некоторые операции, которые могут привести к рассинхронизации связанного списка в случае потери питания. В этом случае littlefs устанавливает флаг «sync» в глобальном состоянии. Как именно хранится этот флаг, описано ниже.

Когда установлен флаг синхронизации:

  1. Связанный список может содержать осиротевший каталог, который был удалён из файловой системы.
  2. Связанный список может содержать пару метаданных с повреждённым блоком, которая была заменена в файловой системе.

Если установлен флаг синхронизации, связанный список с резьбой должен быть проверен на наличие этих ошибок, прежде чем его можно будет использовать надёжно. Обратите внимание, что связанным списком с резьбой можно пренебречь, если littlefs смонтирован только для чтения.

Расположение тега хвостовика:

        tag                          data
[--      32      --][--      32      --|--      32      --]
[1| 3| 8 | 10 | 10 ][---              64               ---]
 ^  ^  ^   ^    ^- размер (8)            ^- пара метаданных
 |  |  |   '------ идентификатор
 |  |  '---------- тип хвостовика
 |  '------------- тип1 (0x6)
 '---------------- действительный бит

Поля хвостовика:

  1. Тип хвостовика (8-бит) — тип указателя хвостовика.

  2. Пара метаданных (8 байт) — указатель на следующую пару метаданных.


0x600 LFS_TYPE_SOFTTAIL

Предоставляет указатель хвостовика, который указывает на следующую пару метаданных в файловой системе.

В этом случае следующая пара метаданных не является частью нашего текущего каталога и должна использоваться только при обходе всей файловой системы.


0x601 LFS_TYPE_HARDTAIL

Предоставляет указатель хвостовика, который указывает на следующую пару метаданных в каталоге.

В этом случае следующая пара метаданных принадлежит текущему каталогу. Обратите внимание: поскольку каталоги в littlefs отсортированы в алфавитном порядке, следующая пара метаданных должна содержать только имена файлов, превышающие любое имя файла в текущей паре.


0x7xx LFS_TYPE_GSTATE

Предоставляет биты дельты для записей глобального состояния.

littlefs имеет концепцию «глобального состояния». Это небольшой набор состояний, которые можно обновить путём фиксации в любой паре метаданных в файловой системе.

Принцип работы заключается в том, что глобальное состояние хранится в виде набора дельт, распределённых по файловой системе таким образом, чтобы глобальное состояние можно было найти по сумме XOR этих дельт.

 .--------.  .--------.  .--------.  .--------.  .--------.
.|        |->| gdelta |->|        |->| gdelta |->| gdelta |
||        | || 0x23   | ||        | || 0xff   | || 0xce   |
||        | ||        | ||        | ||        | ||        |
|'--------' |'--------' |'--------' |'--------' |'--------'
'--------'  '----|---'  '--------'  '----|---'  '----|---'
                 v                       v           v
       0x00 --> xor ------------------> xor ------> xor --> gstate = 0x12

Обратите внимание, что хранение глобальных данных таким способом очень затратно с точки зрения использования памяти, поэтому любое глобальное состояние должно быть очень небольшим.

Размер и формат каждого фрагмента глобального состояния зависит от типа, который хранится в поле фрагмента. В настоящее время единственным глобальным состоянием является состояние перемещения, которое описано ниже.


0x7ff LFS_TYPE_MOVESTATE

Предоставляет биты дельты для глобального состояния перемещения.

Состояние перемещения в littlefs используется для хранения информации об операциях, которые могли бы привести к рассинхронизации файловой системы в случае потери питания. Операции, при которых это могло произойти, — это перемещение файлов между парами метаданных и любые

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/openharmony-third_party_littlefs.git
git@api.gitlife.ru:oschina-mirror/openharmony-third_party_littlefs.git
oschina-mirror
openharmony-third_party_littlefs
openharmony-third_party_littlefs
master