> man operating_systems
Дисковая структура ReiserFS
на Понедельник, 31 Октябрь 2005, 12:48
добавил: Пешеходов А. П. aka fresco список авторов печатать элемент контента создать pdf-файл  элемент контента
категория Статьи
комментарии: 0
просмотров: 5187

Статья рассматривает дисковую структуру ReiserFS 3.6.

Ранее статья была опубликована на <a href=http://fresco.front.ru>fresco.front.ru</a>.

Публикация и распространениематериала без согласия автора запрещены.

Примечания

Статья составлена по документу Florian Buchholz “ The structure of the Reiser file system”, по комментариям в исходных текстах ReiserFS, а также по консультациям с Владимиром Савельевым.

При написании статьи использованы исходники драйвера ReiserFS ядра Linux-2.6.13.3.

Введение

Reiser File System была создана Гансом Рейзером с целью увеличения производительноти (по сравнению с ext2), создания эффективной схемы управления дисковым пространством и обеспечения улучшенной (относительно существующих файлоывх систем) обработки больших каталогов. ReiserFS использует сбалансированны деревья для хранения файлов и директорий, а также обеспечивает журналирование.

Этот документ описывает дисковую структуру ReiserFS версии 3.6. Здесь не рассматриваются алгоритмы балансировки filesystem tree, выполнения журналирования, операций управления файлами, каталогами и пр.

Блоки

Раздел ReiserFS представляет собой набор блоков фиксированного размера. Блоки нумеруются последовательно начиная с нулевого. Максимально доступное количество блоков на одном разделе – 2^32.

Раздел начинается с 64-х килобайт неиспользуемогопространства, оставленного под загрузчики, дисковые метки и прочие служебные надобности. Далее следует суперблок. Суперблок содержит важную информацию о разделе, например размер блока и местоположение корневого узла и journal node. Номер блока, содержащего суперблок, варьируется в зависимости от размера блока файловой системы, однако он всегда начинается с 65536-го байта раздела. Размер блока reiserfs в Linux по умолчанию равен 4 kb. Таким образом, суперблок содержится в 16-м блоке. Суперблок – один на весь раздел.

Сразу за суперблоком следует блок, содержащий битовую карту свободнго места. Количество блоков, отслеживаемых картой, напрямую зависит от размера блока. Большой раздел может иметь несколько bitmap-блоков.

За первым bitmap-блоком должен быть журнал, однако суперблок содержит более точную (для нестандартных случаев) информацию о его местоположении.

Суперблок

См. include/linux/reiserfs_fs.h

/* Параметры журнала */
struct journal_params {
 __le32 jp_journal_1st_block; /* Первый блок журнала на этом разделе */
 __le32 jp_journal_dev; /* Номер устройства, содрежащего журнал */
 __le32 jp_journal_size; /* Размер журнала */
 __le32 jp_journal_trans_max; /* Максимальное количество блоков в транзакции */
 __le32 jp_journal_magic; /* Случайный magic-номер (присваивается при создании ФС */
 __le32 jp_journal_max_batch; /* Максимальное количество блоков в транзакции */
 __le32 jp_journal_max_commit_age; /* Максимальный возраст (в секундах) асинхронного 
        пакета (commit) */
 __le32 jp_journal_max_trans_age; /* Максимальный возраст (в секундах) транзакции */
};
 
/* Формат суперблока для reiserfs v 3.5.x, где x >=10 */
struct reiserfs_super_block_v1 {
 __le32 s_block_count; /* Количество блоков */
 __le32 s_free_blocks; /* Количество свободных блоков */
 __le32 s_root_block; /* Номер блока, содержащего корневой узел дерева файловой 
        системы */
 struct journal_params s_journal; /* Параметры журнала (см. выше) */
 __le16 s_blocksize; /* Размер блока (в байтах) */
 __le16 s_oid_maxsize; /* Максимальный размер массива Object ID (подробнее см. 
        комментарии к reiserfs_get_unused_objectid() в fs/reiserfs/objectid.c */
 __le16 s_oid_cursize; /* Текущий размер массива Object ID */
 __le16 s_umount_state; /* Unmount статус 
 1 – если ФС была размонтирована
 2 – если нет */
 char s_magic[10]; /* Reiserfs magic string
 "ReIsErFs", "ReIsEr2Fs" или "ReIsEr3Fs" */
 __le16 s_fs_state; /* Это поле используется fsck для отметок о том, какая фаза 
        восстановления завершена */
 __le32 s_hash_function_code; /* Определяет, какая хэш-функция будет использоваться
        для сортировки имен в каталогах*/
 __le16 s_tree_height; /* Высота дерева */
 __le16 s_bmap_nr; /* Количество bitmap-блоков, необходимых для отслеживания
        каждого блока в файловой системе */
 __le16 s_version; /* Версия reiserfs (актуальна только на ФС с нестандартым
        журналом) */
 __le16 s_reserved_for_journal; /* Размер (в блоках) журнала на основном
        устройстве, который мы должны сохранить после создания ФС с нестандартым
        журналом */
};

/* Дисковый суперблок */
struct reiserfs_super_block {
 struct reiserfs_super_block_v1 s_v1; /* См. выше */

 
 __le32 s_inode_generation; /* Поколение inode – счетчик, увеличивается при
        каждом удалении */
 __le32 s_flags; /* В настоящее время используется только подсистемой
        inode-attributes, если она разрешена */
 unsigned char s_uuid[16]; /* Уникальный идентификатор ФС */
 unsigned char s_label[16]; /* Метка тома (volume lable) */
 char s_unused[88]; /* используется mkreiserfs и reiserfs_convert_objectid_map_v1() */
 };


Поле s_inode_generation используется для работы reiserfs на NFS-сервере. NFS-клиент получает от сервера handle, содержащий ID файла и generation counter. Допустим, что далее файл на сервере удаляется, а через некоторое время создается новый, получающий тот же ID (reiserfs, как большинство других файловых систем, присваивает новым файлам освободившиеся идентификаторы удаленных). Клиент, не зная этого, делает новый запрос с handle удаленного файла. Если бы не s_inode_generation, сервер не смог бы понять, что handle, переданный клиентом, относится к несуществующему уже файлу, т.к. он ищет inode файла в кэше inodes по ID, и он нашел бы новый файл. Однако s_inodes_generation при новом файле отличается от того, что был при старом, то сервер может понять, что ему передан устаревший NFS-handle.

Для синхронизации процессов, ожидающих балансировки дерева, reiserfs имеет не хранимый на диске счетчик fs_generation, используемый для того, что бы определить, изменилась файловая система с момента последнего чтения счетчика. Балансировка – сложный и длительный процесс, подготовка к которому часто требует чтение с диска нескольких блоков. Т.к. reiserfs не имеет locking-механизма, ни что не мешает другому процессу изменить дерево, пока наш процесс ждет завершения ввода-вывода. В таком случае может оказаться, что все данные, подготовленные первым процессом, уже не актуальны, и надо сделать все заново. fs_generation увеличевается при каждом изменении в дереве. Процесс, начинающий подготовку к балансировке, запоминает fs_generation, а перед началом самой балансировки сравнивает этой значение с новым. Если fs_generation изменился – подготовка выполняется заново.

индекс статьи
страница 1 - текущая : страница без заголовка
страница 2 : страница без заголовка
страница 3 : страница без заголовка
страница 4 : страница без заголовка


© OSRC.info, 2004-2010.
Авторские права на любые материалы, авторы которых явно указаны, принадлежат их авторам. По вопросам публикации таких материалов обращайтесь к авторам.
Авторские права на любые другие материалы принадлежат OSRC.info.
Сайт является помещением библиотеки. Копирование, сохранение на жестком диске или иной способ сохранения произведений осуществляются пользователями на свой риск.
При использовании материалов сайта ссылка на OSRC.info обязательна.