Как очистить кэш файловой системы?

Тема в разделе "WASM.WIN32", создана пользователем Zufyxe, 13 авг 2004.

  1. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    При открытии+чтении файла NT кэширует его содержимое так, что последующие запросы на чтение фактически получают содержимое кэша а не физического носителя. Вся эта кухня довольно подробно описана у Соломона/Русиновича. Проблема вот в чем: можно ли мгновенно очистить содержимое этого самого кэша, так чтобы следующий запрос на чтение заново поднимал файл с диска?
     
  2. ChS

    ChS New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2003
    Сообщения:
    20
    KmdKit\tools\Sync там пример :)
     
  3. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    Или NtFlushBuffersFile для файла.
     
  4. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    По поводу NtFlushBuffersFile:



    маленькая прога:



    call NtCreateFile ; получили handle FILE_READ_DATA+FILE_WRITE_DATA

    call NtReadFile ; прочитали 4кб

    call NtFlushBuffersFile ; типа почистили буферы

    call NtClose ; убили handle

    ; теперь берем SoftIce и лезим в FILE_OBJECT

    ; поле PRIVATE_CACHE_MAP = 0 вроде как файл не кэширован...

    ; однако SHARED_CACHE_MAP - существует и указывает на VACB где мы находим mapped наши прочитанные 4 кб

    ; ручками изменяем первые 2-4 байта.



    call NtCreateFile ; снова получаем handle FILE_READ_DATA

    call NtReadFile ; и мы имеем не исходный файл, а наши измененные 2-4 байта :dntknw:



    Вариантов - 2:



    1. NtFlushBuffersFile сливает содержимое кэша на диск, но сам кэш остается и используется далее.

    2. NtFlushBuffersFile инициирует отложенную запись (lazy-write) и сливает содержимое + чистит кэш не сразу, а как придется.
     
  5. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    1)

    Смотри флаги:



    FILE_WRITE_THROUGH

    FILE_NO_INTERMEDIATE_BUFFERING

    FILE_SYNCHRONOUS_IO_NONALERT

    И вообше:



    This service causes all buffered data to the file to be written.



    По-моему она синхронна и осылает IRP_MJ_FLUSH_BUFFERS, а у Four-F илвользуется FlushFileBuffers, которая вызаваетStatus = NtFlushBuffersFile(hFile,&IoStatusBlock);



    Требуются права: FILE_WRITE_DATA

    2)Ждем Four-F
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Sync и NtFlushBuffersFile просто немедленно сбрасывают последние изменения в файл. Но кеширование продолжается. Как вытолькнуть из кеша уже кешируемый файл я не знаю. Если из ядра надо, то можно посмотреть в сторону менеджера кэша. Например, есть CcPurgeCacheSection, которая, если я всё правильно понимаю, делает сабж. Но сам я Сс... функциями не работал, поэтому ничего умного не скажу. Если надо из юзера, то, наверное, только отменять кэширование при открытии файла.
     
  7. PavPS

    PavPS New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2004
    Сообщения:
    109
    Адрес:
    Russia
    А тогда у меня крыша едет:

    Чтоже теперь? Открыли файл прочитали 4 кб, потом какой-то процесс открыл этот файл, изменил 2-4 байта и закрыл. А мы опять читаем из этого файла (мы его ещё не закрывали) те же самые 4 кб, а они всё те же что-ли? Из этого кэша прочитанные? Да ведь нет же - тогдабы хаос какой-то был бы... Что за чёрт?
     
  8. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    PavPS

    Сделать файл не разделяемым, пусть остальные приложения подождут, или сообщают твоему, что файл им нужен.
     
  9. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    PavPS

    Касательно флагов:

    FILE_WRITE_THROUGH - требует немедленной записи на диск, т.е. отключает lazy-write для конкретного файла, кэш при этом сохраняется.

    FILE_NO_INTERMEDIATE_BUFFERING - отключает кэширование на уровне драйвера ФАЙЛОВОЙ СИСТЕМЫ, т.е. при чтении/записи логического блока (кластера). Это значит, что чтение может быть осуществлено только в размере кратном размеру кластера и только с позиции в файле выравненой на размер кластера. Соответствено file stream (как некоторый поток данных) кэшируется как всегда. :dntknw:

    FILE_SYNCHRONOUS_IO_NONALERT - это просто синхронное IO, на кэш не влияет.



    NtFlushBuffersFile - действительно отсылает IRP_MJ_FLUSH_BUFFERS.



    - наш процесс увидит все изменения файла, поскольку кэширование осуществляется на уровне FILE STREAM т.е. один файл окрытый разными процессами представлен только одним stream-ом в памяти, это ни что иное как те-же самые страницы mapped на разные процессы.



    pas



    это ничего не дает, на кэширование не влияет.
     
  10. Zufyxe

    Zufyxe New Member

    Публикаций:
    0
    Регистрация:
    13 авг 2004
    Сообщения:
    137
    Адрес:
    Russia
    Всё. Проверил. CcPurgeCacheSection - работает так как надо.

    Four-F

    Спасибо за идею!