Любая | Ссылка (file reference) на базовую файловую запись (base FILE record) или ноль, если данная файловая запись является базовой | |||
28h | 2 | Любая | Идентификатор следующего атрибута (next attribute ID) | |
2Ah | 2 | Windows XP | Используется для выравнивания | |
2Ch | 4 | Windows XP | Индекс данной файловой записи (number of this MFT record) | |
2 | Любая | Номер последовательности обновления (update sequence number) | ||
2S -2 | Любая | Массив последовательности обновления (update sequence array) |
Последовательность обновления
Будучи очень важными компонентами файловой системы, $MFT
, INDEX
и $LogFile
нуждаются в механизме контроля целостности своего содержимого. Традиционно для этого используются коды обнаружения и коррекции ошибок (ECC/EDC codes). Однако на тот момент, когда проектировалась NTFS, процессоры были не настолько быстрыми, как теперь, и расчет корректирующих кодов занимал значительное время, существенно снижающее производительность файловой системы. Именно поэтому от использования корректирующих кодов пришлось отказаться. Вместо них разработчики NTFS применили так называемые
В конец каждого из секторов, слагающих файловую запись (INDEX Record
, RCRD Record
или RSTR Record
), записывается специальный 16-байтный
Основное назначение последовательностей обновления — защита от 'обрыва записи'. Если в процессе записи сектора на диск исчезнет питающее напряжение, может случиться так, что часть файловой записи будет записана успешно, а другая часть — сохранит прежнее содержимое (файловая запись, как мы помним, обычно состоит из двух секторов). После восстановления питания драйвер файловой системы не может уверенно определить, была ли файловая запись записана целиком. Вот тут-то последовательности обновления и выручают! При каждой перезаписи сектора последовательность обновления увеличивается на единицу. Потому, если произошел обрыв записи, значение последовательности обновления, находящейся в заголовке файловой записи, не совпадет с последовательностью обновления, расположенной в конце сектора.
Оригинальное содержимое, расположенное 'под' последовательностью обновления, хранится в специальном INDEX Record
, RCRD Record
или RSTR Record
). Если они не совпадут, значит, соответствующая структура данных повреждена. Использовать такие структуры следует очень осторожно (на первых порах лучше не использовать вообще).
По смещению 006h
от начала сектора находится 16-разрядное поле, хранящее совокупный размер номера последовательности обновления вместе с массивом последовательности обновления (sizeof (update sequence number) + sizeof(update sequence array)
), выраженный в словах (не в байтах!). Так как размер номера последовательности обновления всегда равен одному слову, то размер массива последовательности обновления, выраженный в байтах, должен вычисляться следующим образом: (update sequence number & update sequence array - 1)*2
. Таким образом, смещение массива оригинального содержимого равно: (offset to update sequence number) + 2
. В Windows NT и Windows 2000 номер последовательности обновления всегда располагается по смещению 2Ah
от начала заголовка файловой записи или индексного заголовка, а поле update sequence array
— по смещению 2Ch
. В Windows XP и более новых операционных системах эти значения располагаются по смещениям 2Dh
и 2Fh
соответственно.
Первое слово массива последовательности обновления соответствует последнему слову первого сектора файловой записи или индексной записи. Второе — последнему слову второго сектора и т.д. Для восстановления сектора в исходный вид необходимо вернуть все элементы массива последовательности обновления на их законные места (естественно, модифицируется не сам сектор, а его копия в памяти).
Чтобы проиллюстрировать сказанное выше, рассмотрим пример, приведенный в листинге 6.2.
Листинг 6.2. Оригинальная файловая запись до восстановления
--> начало первого сектора FILE Record
00000000: 46 49 4C 45-2A 00 03 00-7C 77 1A 04-02 00 00 00 FILE*...| w......