NTFS

Drive subsystem, filesystem drivers
  • Лучше написать "I have modified kernel, driver or program source code, and want to test changes". А ещё неплохо бы на видном месте написать, что такое SVN. Я, например, в open source впервые.

    У меня windows установлена на fat32, для тестирования создаю ntfs раздел, колибри запускаю через mtldr. Результат работы виден во всех файловых менеджерах, но исчезает после перезагрузки, в том числе без загрузки windows. Загрузчик работает с файловой системой, а значит обнаруживает ошибки в корневом каталоге и может попытатся их исправить, в данном случае это легко. Лучше всего было бы смотреть в hexview, но как я понял, функция чтения раздела у вас уже отсутствует.
  • Pathoswithin wrote:Результат работы виден во всех файловых менеджерах, но исчезает после перезагрузки, в том числе без загрузки windows.
    Скорее всего, данные записались в дисковый кэш, но кэш не записался на диск. disk_sync вызываешь?
    Сделаем мир лучше!
  • disk_sync? Я даже не знаю, что это такое! У вас где-то описаны внутренние вызовы ядра? Я использую fs_write64_sys. Как я понял, старые вызовы использовали кэш, а новым то он зачем? Или давайте прямо - вы знаете чем я занимаюсь... Чего ещё я не знаю?
  • Pathoswithin wrote:У вас где-то описаны внутренние вызовы ядра?
    Увы, с этим плохо.

    fs_write64_sys пишет в дисковый кэш. Пока кэш не переполнится, записанные данные остаются только в памяти. disk_sync записывает все изменённые данные из кэша на диск. disk_sync по возможности объединяет операции записи - если изменены несколько подряд идущих секторов, они будут записаны одной операцией, это существенно ускоряет работу. Поэтому disk_sync лучше вызывать в конце операции. В коде FAT, например, в конце каждой функции записи есть вызов update_disk, которая, в частности, вызывает disk_sync.
    Pathoswithin wrote:Чего ещё я не знаю?
    Из неочевидного: несколько потоков могут одновременно вызвать функции файловой системы, в том числе для одного и того же раздела, и глобальных блокировок нет, файловая система должна сама заботиться о том, чтобы разные потоки друг другу не мешали. В свою очередь, функции fs_{read,write}* готовы к тому, что их будут вызывать параллельно из разных потоков. Сейчас все файловые системы держат для каждого раздела отдельный мьютекс, все функции файловой системы начинаются с mutex_lock на этом мьютексе и заканчиваются mutex_unlock - осталось от времени, когда глобальная блокировка была, далеко от идеала, но работает. Read-write глобальных переменных лучше избегать совсем, но если очень надо, для них нужно будет заводить отдельный мьютекс.
    Сделаем мир лучше!
  • У меня есть указатель на структуру NTFS PARTITION под мьютексом. Глобальных переменных нельзя, а структуру изменять можно? И разве не должен дисковый кэш записываться перед выключением системы?
  • Pathoswithin wrote:У меня есть указатель на структуру NTFS PARTITION под мьютексом. Глобальных переменных нельзя, а структуру изменять можно?
    Да, для этого мьютекс и берётся. Под PARTITION-специфичным мьютексом не может быть двух потоков, обращающихся к одному и тому же разделу, но вполне могут быть несколько потоков, обрабатывающих разные разделы или диски, - пока нет записи в глобальные read-write переменные, они друг другу не мешают.
    Pathoswithin wrote:И разве не должен дисковый кэш записываться перед выключением системы?
    Только перед выключением - нет, потому что а) пользователь может отключить флешки и внешние диски и без выключения системы и б) иногда бывают аварийные ситуации вроде внезапного отключения электричества. Запись кэша сразу после каждого вызова файловой системы - тоже неидеальный вариант, но чего-то более умного никто не написал.
    Сделаем мир лучше!
  • CleverMouse wrote:[...]
    а) пользователь может отключить флешки и внешние диски и без выключения системы; и
    б) иногда бывают аварийные ситуации вроде внезапного отключения электричества.
    Запись кэша сразу после каждого вызова файловой системы - тоже неидеальный вариант, но чего-то более умного никто не написал.
    А ни чего более умного и быть не может, процесс записи зависит от наличия электрического тока в медных жилах условного зверя:
    • хочешь выключить, записывай;
    • ИБП послал сообщение о выключении через 30 сек, записывай;
    • юзверь сообщил системе о безопасном извлечении USB, записывай и давай сообщение;
    • юзверь выдернул не сообщив системе об извлечении USB\SCSI\eSATA, его проблемы;
    • простой системы, запиши чтобы не нервничать;
    • приложение просит освободить кэш и записать, запиши сразу...
  • А обрабатывать исключения у вас можно? Например дописать буфер при ошибке доступа к памяти?
    kiv wrote:[*] юзверь сообщил системе о безопасном извлечении USB, записывай и давай сообщение;
    [*] юзверь выдернул не сообщив системе об извлечении USB\SCSI\eSATA, его проблемы;
    [*] простой системы, запиши чтобы не нервничать;
    Кстати, да. В windows тоже есть отложенная запись. В идеале кэш должен не терпеть до последнего, а скорее осуществлять сглаживающую функцию. То есть записывать сразу, но во время записи продолжать принимать запросы.
  • Pathoswithin
    А при каких условиях возникнет эта ошибка ?
  • Ну например мне нужно просмотреть битмап чтобы найти место для файла. У раздела на 2 Тб битмап будет 64Мб. Многовато чтобы изначально хранить в памяти. Просматривать нужно сравнивая каждый dword с -1, так ещё и счётчик буфера проверять. Можно конечно использовать repz scasd и убить двух зайцев, но он сначала сравнивает, а потом увеличивает di, и приходится его уменьшать, что тоже может быть существенно. Короче, спросил на всякий случай.
  • Значит надо смотреть по частям. Ядро рассматривает страничные ошибки в верхних 2Гб как фатальные.
  • А как вообще с расширением памяти? В windows при выделении страниц можно указывать желаемый виртуальный адрес, можно резервировать адреса. Мне для битмапа нужен целый кусок памяти. Хранить всё время - многовато, считывать каждый раз - долго. Нужна буферизация по требованию.
  • 64 Мб зарезервировать можно. Памятью придётся управлять вручную.
    alloc_kernel_space stdcall, size:dword
    резервируем диапазон адресов.
    alloc_pages stdcall, count:dword выделяем count страниц. Страницы физически непрерывны, количество желательно кратно восьми.
    commit_pages: выполняет маппинг.
    ; eax= page base + page flags
    ; ebx= linear address
    ; ecx= count

    release_pages чистит таблицы страниц и возвращает страницы в пул свободных.
    ; eax= linear memory address
    ; ecx= count
  • alloc_kernel_space - Размер в чём? Возвращает начальный адрес?
    alloc_pages - Количество по 4 кб? Насколько желательно по 8? Что возвращает?
    commit_pages - подробней про eax
  • Who is online

    Users browsing this forum: No registered users and 1 guest