-
Здравствуйте ! Давным давно я поднимала этот вопрос. Тогда ответа не нашли. Может сейчас у кого-нибудь будут идеи, как объяснить(понять) следующий факт:
Читаем файловую запись двумя способами: NtReadFile и NtFsControlFile(..., FSCTL_GET_NTFS_FILE_RECORD, ...). В первом случае получаем мусор, во втором корректные данные. (какой именно FileRecord прочитала NtFsControlFile - проверяется). Эффект довольно трудно, но воиспроизводим (я приводила диск в "непотребное" состояние :)
Когда я столкнулась с разницой между прямым чтением и чтении через API, подумла что вот она - причина и списала этот вопрос на всевозможные "кеширования" и "буферизации".
Но сейчас, похоже, это объяснение не проходит. Во всяком случае, эффект наблюдается (на тех одних и тех же файловых объектах) как после длительной работы, так и сразу после холодного рестарта.
Очень бы хотелось понять происходящее. Кто что думает: какие могут быть причины ?
-
> [0] Riply © (04.04.08 21:34) > Читаем файловую запись двумя способами: NtReadFile и NtFsControlFile
NtReadFile - имеется ввиду "прямое" чтение.
-
> Кто что думает: какие могут быть причины ?
Я думаю что причина в том что в программе ошибка :) Пришли образ где явление наблюдается.
-
> [2] guav © (05.04.08 00:11) > Я думаю что причина в том что в программе ошибка :)
Я понимаю, что ошибка может быть везде, но перепроверила сто раз. Вынесла все в отдельную процедуру. Передаю в нее номер рекода, читаю так и так и сравниваю результат. Что может быть проще ?
> Пришли образ где явление наблюдается. Образ чего прислать ?
Ты учитывай, что у меня Dual-up :)
-
Может это поможет ? Здесь выдержка атрибутов сканируемой директории (сожержит только файлы). Пробегаюсь по ее Lcn-ам. И при чтении Lcn`а 221544 вылетаю из цикла с ошибкой несовпадения MagicType у рекорда. Передаю этот Lcn в вынесенную процедуру и убеждаюсь, что читается по-разному. Если в основном блоке заменить ReadFile на ControlFile, то все работает.
\??\D:\DestDir_46\0 MultiSectorHeader NTFS_RECORD_HEADER cbType FILE UpdateSequenceArrayOffset 48 UpdateSequenceArraySize 3 _Usn64 108368966 SequenceNumber 1 LinkCount 1 AttributesOffset 56 Flags Dir BytesInUse 808 BytesAllocated 1024 BaseFileRecordSegment SegmentNumberLowPart 0 SegmentNumberHighPart 0 SequenceNumber 0 NextAttributeNumber 8 SelfRecord 88986
TypeCode AT_STANDARD_INFORMATION RecordLength 96 FormCode RESIDENT Name Flags STANDART Instance 0 ValueLength 72 ValueOffset 24 _Flags Not Indexed: 0 CreationTime 2008.04.03 22.05.50 ChangeTime 2008.04.03 22.06.29 LastWriteTime 2008.04.03 22.06.29 LastAccessTime 2008.04.05 00.28.20 FileAttributes $0 MaxVersionsNum 0 VersionNum 0 ClassId 0 OwnerId 0 SecurityId 260 QuotaCharge 0 Usn64 0
TypeCode AT_FILE_NAME RecordLength 96 FormCode RESIDENT Name Flags STANDART Instance 2 ValueLength 68 ValueOffset 24 _Flags Indexed: 1 ParentDirectory SegmentNumberLowPart 57290 SegmentNumberHighPart 0 SequenceNumber 1 CreationTime 2008.04.03 22.05.50 ChangeTime 2008.04.03 22.05.50 LastWriteTime 2008.04.03 22.05.50 LastAccessTime 2008.04.03 22.05.50 AllocatedSize 0 DataSize 0 FileAttributes $10000000I30 AlignmentOrReserved 0 FILE_NAME_WIN32_AND_DOS = 0
TypeCode AT_INDEX_ROOT RecordLength 88 FormCode RESIDENT Name $I30 Flags STANDART Instance 7 ValueLength 56 ValueOffset 32 _Flags Not Indexed: 0 cbType AT_FILE_NAME CollationRule 1 BytesPerIndexBlock 4096 ClustersPerIndexBlock 2 DirectoryIndex EntriesOffset 16 IndexBlockLength 40 AllocatedSize 40 Flags Large Enum Dir Entries
TypeCode AT_INDEX_ALLOCATION RecordLength 416 FormCode NONRESIDENT Name $I30 Flags STANDART Instance 3 LowestVcn 0 HighestVcn 231 MappingPairsOffset 72 _CompressionUnit 0 AllocatedLength 475136 FileSize 475136 ValidDataLength 475136 TotalAllocated 13511017930227748
TypeCode AT_BITMAP RecordLength 48 FormCode RESIDENT Name $I30 Flags STANDART Instance 4 ValueLength 16 ValueOffset 32 _Flags Not Indexed: 0
RETRIEVAL_POINTERS_BUFFER ExtentCount 111 Index 0 Lcn 228215 Count 2 Index 1 Lcn 228291 Count 2 Index 2 Lcn 228348 Count 2 Index 3 Lcn 228393 Count 2 Index 4 Lcn 228444 Count 2 Index 5 Lcn 228468 Count 4 Index 6 Lcn 228522 Count 2 Index 7 Lcn 228565 Count 2 Index 8 Lcn 228639 Count 2 Index 9 Lcn 228673 Count 2 Index 10 Lcn 228720 Count 2 Index 11 Lcn 228743 Count 2 Index 12 Lcn 228787 Count 2 Index 13 Lcn 228835 Count 2 Index 14 Lcn 228901 Count 2 Index 15 Lcn 228975 Count 2 Index 16 Lcn 229023 Count 2 Index 17 Lcn 229085 Count 2 Index 18 Lcn 229129 Count 2 Index 19 Lcn 229173 Count 2 Index 20 Lcn 229235 Count 2 Index 21 Lcn 229269 Count 2 Index 22 Lcn 229334 Count 2 Index 23 Lcn 229372 Count 2 Index 24 Lcn 229403 Count 2 Index 25 Lcn 229447 Count 2 Index 26 Lcn 229490 Count 2 Index 27 Lcn 229561 Count 2 Index 28 Lcn 229623 Count 2 Index 29 Lcn 222468 Count 2 Index 30 Lcn 222518 Count 2 Index 31 Lcn 222581 Count 2 Index 32 Lcn 222631 Count 2 Index 33 Lcn 222676 Count 2 Index 34 Lcn 222729 Count 4 Index 35 Lcn 222795 Count 2 Index 36 Lcn 222852 Count 2 Index 37 Lcn 222908 Count 2 Index 38 Lcn 222949 Count 2 Index 39 Lcn 222999 Count 2 Index 40 Lcn 223050 Count 2 Index 41 Lcn 223115 Count 2 Index 42 Lcn 223187 Count 2 Index 43 Lcn 223262 Count 2 Index 44 Lcn 223309 Count 2 Index 45 Lcn 223363 Count 2 Index 46 Lcn 223412 Count 2 Index 47 Lcn 223464 Count 2 Index 48 Lcn 223559 Count 2 Index 49 Lcn 223615 Count 2 Index 50 Lcn 223649 Count 2 Index 51 Lcn 223700 Count 4 Index 52 Lcn 223741 Count 2 Index 53 Lcn 223792 Count 2 Index 54 Lcn 223876 Count 2 Index 55 Lcn 223931 Count 2 Index 56 Lcn 223993 Count 2 Index 57 Lcn 224068 Count 2 Index 58 Lcn 224108 Count 2 Index 59 Lcn 224148 Count 2 Index 60 Lcn 224233 Count 2 Index 61 Lcn 224290 Count 2 Index 62 Lcn 224327 Count 2 Index 63 Lcn 224387 Count 2 Index 64 Lcn 224429 Count 2 Index 65 Lcn 224473 Count 2 Index 66 Lcn 224532 Count 2 Index 67 Lcn 224577 Count 2 Index 68 Lcn 224619 Count 6 Index 69 Lcn 224641 Count 2 Index 70 Lcn 224661 Count 2 Index 71 Lcn 221544 Count 2 Index 72 Lcn 221588 Count 2 Index 73 Lcn 221657 Count 2 Index 74 Lcn 221709 Count 2 Index 75 Lcn 221758 Count 2 Index 76 Lcn 221808 Count 2 Index 77 Lcn 221845 Count 2 Index 78 Lcn 221878 Count 2 Index 79 Lcn 221925 Count 2 Index 80 Lcn 221952 Count 2 Index 81 Lcn 222022 Count 2 Index 82 Lcn 222059 Count 2 Index 83 Lcn 222094 Count 2 Index 84 Lcn 222114 Count 2 Index 85 Lcn 222151 Count 4 Index 86 Lcn 222200 Count 2 Index 87 Lcn 222245 Count 2 Index 88 Lcn 222273 Count 2 Index 89 Lcn 222304 Count 2 Index 90 Lcn 222340 Count 2 Index 91 Lcn 222394 Count 2 Index 92 Lcn 222431 Count 1 Index 93 Lcn 221120 Count 1 Index 94 Lcn 221155 Count 2 Index 95 Lcn 221193 Count 2 Index 96 Lcn 221236 Count 2 Index 97 Lcn 221267 Count 2 Index 98 Lcn 221311 Count 2 Index 99 Lcn 221335 Count 2 Index 100 Lcn 221380 Count 2 Index 101 Lcn 221419 Count 2 Index 102 Lcn 221446 Count 2 Index 103 Lcn 221502 Count 2 Index 104 Lcn 220992 Count 2 Index 105 Lcn 221030 Count 2 Index 106 Lcn 221051 Count 2 Index 107 Lcn 221085 Count 2 Index 108 Lcn 221115 Count 2 Index 109 Lcn 220962 Count 2 Index 110 Lcn 220914 Count 2
-
> Riply © (05.04.08 00:24) [3]
> Ты учитывай, что у меня Dual-up :) >
Это что? Такая "шутка юмора"?
-
> [5] Германн © (05.04.08 02:16) > Это что? Такая "шутка юмора"?
Нет. Это просто ачепятка :)
-
> Пробегаюсь по ее Lcn-ам.
То есть, ты смотришь содержимое :$I30:$INDEX_ALLOCATION этой директории, и потом проходишь по всем файлреференсам оттуда ? Или это R.P. для её ::$Data ?
Давай не так. Приведи пример с одним файлом, у которого известен: 1. Результат чтения через FSCTL_GET_NTFS_FILE_RECORD 2. Результат прямого чтения (с указанием читаемого смещения) 3. Результат FSCTL_GET_RETRIEVAL_POINTERS для $Mft, именно результат FSCTL_GET_RETRIEVAL_POINTERS а не своей работы (открывать можно с правами 0, тогда откроется) 4. Параметры ФС: размер кластера, размер сектора, размер файлрекорда
После этого можно внимательно сопоставить RETRIEVAL_POINTERS для $Mft с читаемым кластером, думаю тут и будет ошибка.
-
> [7] guav © (05.04.08 11:31) > То есть, ты смотришь содержимое :$I30:$INDEX_ALLOCATION этой директории, > и потом проходишь по всем файлреференсам оттуда ?
Именно так.
> Или это R.P. для её ::$Data ?
Нет.
> Давай не так.
Давай :)
(Сканируется та же директория, только я ошиблась указывая "сбойный" LCN На самом деле он - 221120 )
Вот первые данные:
Сам диск:
FSCTL_GET_NTFS_VOLUME_DATA VolumeSerialNumber 7 967 016 108 593 429 977 NumberSectors 2 104 451 TotalClusters 526 112 FreeClusters 104 TotalReserved 0 BytesPerSector 512 BytesPerCluster 2048 BytesPerFileRecordSegment 1024 ClustersPerFileRecordSegment 0 MftValidDataLength 135 168 000 MftStartLcn 175 371 Mft2StartLcn 263 056 MftZoneStart 438 432 MftZoneEnd 438 560 ExtendedData 3.1
Часть атрибутов его MFT:
\??\D:\$MFT MultiSectorHeader NTFS_RECORD_HEADER cbType FILE UpdateSequenceArrayOffset 48 UpdateSequenceArraySize 3 _Usn64 100853279 SequenceNumber 1 LinkCount 1 AttributesOffset 56 Flags File BytesInUse 472 BytesAllocated 1024 BaseFileRecordSegment SegmentNumberLowPart 0 SegmentNumberHighPart 0 SequenceNumber 0 NextAttributeNumber 6 SelfRecord 0
TypeCode AT_STANDARD_INFORMATION RecordLength 96 FormCode RESIDENT Name Flags STANDART Instance 0 ValueLength 72 ValueOffset 24 _Flags Not Indexed: 0 CreationTime 2008.04.03 20.34.01 ChangeTime 2008.04.03 20.34.01 LastWriteTime 2008.04.03 20.34.01 LastAccessTime 2008.04.03 20.34.01 FileAttributes HS MaxVersionsNum 0 VersionNum 0 ClassId 0 OwnerId 0 SecurityId 256 QuotaCharge 0 Usn64 0
TypeCode AT_FILE_NAME RecordLength 104 FormCode RESIDENT Name Flags STANDART Instance 3 ValueLength 74 ValueOffset 24 _Flags Indexed: 1 ParentDirectory SegmentNumberLowPart 5 SegmentNumberHighPart 0 SequenceNumber 5 CreationTime 2008.04.03 20.34.01 ChangeTime 2008.04.03 20.34.01 LastWriteTime 2008.04.03 20.34.01 LastAccessTime 2008.04.03 20.34.01 AllocatedSize 16 384 DataSize 16 384 FileAttributes HS AlignmentOrReserved 0 FILE_NAME_WIN32_AND_DOS = $MFT
TypeCode AT_DATA RecordLength 112 FormCode NONRESIDENT Name Flags STANDART Instance 1 LowestVcn 0 HighestVcn 65999 MappingPairsOffset 64 _CompressionUnit 0 AllocatedLength 135168000 FileSize 135168000 ValidDataLength 135168000 TotalAllocated 3531575320579784755
TypeCode AT_BITMAP RecordLength 96 FormCode NONRESIDENT Name Flags STANDART Instance 5 LowestVcn 0 HighestVcn 9 MappingPairsOffset 64 _CompressionUnit 0 AllocatedLength 20480 FileSize 16504 ValidDataLength 16504 TotalAllocated 8575189053052944689
RETRIEVAL_POINTERS_BUFFER ExtentCount 8 Index 0 Lcn 175371 Count 45504 Index 1 Lcn 220883 Count 8 Index 2 Lcn 305974 Count 8697 Index 3 Lcn 453599 Count 8696 Index 4 Lcn 403347 Count 2639 Index 5 Lcn 406065 Count 8 Index 6 Lcn 406123 Count 440 Index 7 Lcn 406577 Count 8
Насчет самого объекта не поняла: тебя интересуют данные того на кого указывает "сбойный" LCN или данные того объекта, который выдает "сбойный" LCN ?
-
> [8] Riply © (05.04.08 15:02)
Опять форматирование "съехало" :) Кодом надо было выделять, наверное.
-
> [9] Riply © (05.04.08 15:06)
Смайлик не тот. Должен быть :(
-
Файлы нумеруются не через LCN, т.к. в одном кластере находятся несколько файлрекордов. Ссылка на файл - это то, что в MSDN называется MTF_SEGMENT_REFERENCE, или File Reference в документации линукса.
Вот есть у тебя File Reference, передаваемый в FSCTL_GET_NTFS_FILE_RECORD. Из него же ты получаешь смещение в MFT и соответственно смещение на диске. Приведи значение этого File Reference, значение смещения, по которому читаешь и результат что прочитывается в обоих случаях.
-
> [11] guav © (05.04.08 15:36) > Файлы нумеруются не через LCN > Ссылка на файл - это то, что в MSDN называется MTF_SEGMENT_REFERENCE, > или File Reference в документации линукса.
Sorry. Просто оговорилась.
> т.к. в одном кластере находятся несколько файлрекордов. Это не всегда так. Может быть что в одном файлрекорде несколько кластеров :) Я сейчас за компьютером, у которого есть диск (NTFS) с такими характеристиками : BytesPerSector 512 BytesPerCluster 512 BytesPerFileRecordSegment 1024 ClustersPerFileRecordSegment 2
> Приведи значение этого File Reference Хорошо. Только доберусь до компьютера, где Delphi установлена.
-
> Может быть что в одном файлрекорде несколько кластеров :)
Может. Но я про конкретный случай. В любом случае, 221120 на File Reference не похож, где тут последовательный номер ?
> TypeCode AT_DATA
> TotalAllocated 3531575320579784755
Кстати ни разу это ни TotalAllocated переводим в 0x это 3102AD0B00B1C033 00B1C0 = 45504 02AD0B = 175371 , т.е.
> Index 0 Lcn 175371 Count 45504
-
> [13] guav © (05.04.08 16:04) > Кстати ни разу это ни TotalAllocated
Совершенно верно. Значание TotalAllocated, при _CompressionUnit = 0 неопределено. Руки не доходят подправить функцию парсинга, чтобы она не выводила TotalAllocated при нулевом CompressionUnit
-
> [13] guav © (05.04.08 16:04) > В любом случае, 221120 на File Reference не похож, где тут последовательный номер ? Для получения "абсолютного смещения на диске" его надо умножить на BytesPerCluster
-
Выскажу я одно предположение, только чур не смеяться. Бывает несу чушь. Это от недосыпа :)
Трактовка Lcn`ов, возвращаемых FSCTL_GET_RETRIEVAL_POINTERS, и, соответственно, алгоритм их чтения могут зависеть от состояния MFT.
Например, если пользователь так загнал MFT, что та аж вся форматированная да еще и вынужденная хранить в себе данные, которые должны быть не резидентными. :)
-
> Значание TotalAllocated, при _CompressionUnit = 0 неопределено.
Я бы не так сказал, не неопределено, а его просто нет, структура на него меньше. Разница между "не определно" и "нет" может быть важна. > [15] Riply © (05.04.08 16:13)
> Для получения "абсолютного смещения на диске" его надо умножить > на BytesPerCluster
Т.е. это действиетльно LCN принадлежащий $Mft по твоему ? Ок. Берём R.P. $Mft из [8] и пытаемся найти его номер. Даже Dephi под рукой не надо, используем Calc:
lastLcn = fisrtLcn + count – 1
_221120_in = (fisrtLcn<=221120) AND (221120<=lastLcn)
firstLcn count lastLcn _221120_in
175371 45504 220874 ЛОЖЬ
220883 8 220890 ЛОЖЬ
305974 8697 314670 ЛОЖЬ
453599 8696 462294 ЛОЖЬ
403347 2639 405985 ЛОЖЬ
406065 8 406072 ЛОЖЬ
406123 440 406562 ЛОЖЬ
406577 8 406584 ЛОЖЬ Какой же тогда MFT номер у 221120 ? У кого в программе ошибка ?
-
[17] guav © (05.04.08 18:11) > > Значание TotalAllocated, при _CompressionUnit = 0 неопределено.
> Я бы не так сказал, не неопределено, а его просто нет, структура на него меньше. > Разница между "не определно" и "нет" может быть важна.
Спасибо, учту. То что "не определено" я стырила у линуксоидов. Скорее всего, не сумела правильно перевести.
> Т.е. это действиетльно LCN принадлежащий $Mft по твоему ?
Я уже не знаю что и думать :( В программе я поступаю так: высчитываю FileRefNumber := ((221120 - MftStartLcn) * BytesPerCluster) div BytesPerFileRecordSegment; Кстати 221120 попадает в диапазон [MftStartLcn < 221120 < MftStartLcn + MftValidDataLength div BytesPerCluster] Т.е. если забыть про фрагментацию MFT, то он ей принадлежит. Далее, по FileRef успешно считываю валидный FSCTL_GET_NTFS_FILE_RECORD из которого получаю список, примерно из 80 файлов, причем именно тех, которые и были "потеряны" . Ни одним больше, ни одним меньше.
> Какой же тогда MFT номер у 221120 ?
Получается, что FileRefNumber... Возможно нерезидентные данные, которые она вынуждена в себе хранить учитываются каким-то особым образом ?
-
> В программе я поступаю так: высчитываю > FileRefNumber := ((221120 - MftStartLcn) * BytesPerCluster) > div BytesPerFileRecordSegment;
Это что ? Где ты это взяла ? И более интересный вопрос - откуда взялось 221120 ?
> Кстати 221120 попадает в диапазон > [MftStartLcn < 221120 < MftStartLcn + MftValidDataLength > div BytesPerCluster]
И что ?
> Получается, что FileRefNumber...
Нет, не получается.
Не знаю как тебе ещё объяснить... Что по-твоему значат поля File Reference ?
|