· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Как очистить кэш файловой системы?

Посл.отвђт Сообщенiе


Дата: Авг 13, 2004 06:43:19

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


Дата: Авг 13, 2004 09:57:10

KmdKit\tools\Sync там пример :)


Дата: Авг 13, 2004 15:03:08

Или NtFlushBuffersFile для файла.


Дата: Авг 14, 2004 03:01:33

По поводу 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 байта :(

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

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


Дата: Авг 14, 2004 11:56:57 · Поправил: PavPS

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


Дата: Авг 14, 2004 17:41:59

Sync и NtFlushBuffersFile просто немедленно сбрасывают последние изменения в файл. Но кеширование продолжается. Как вытолькнуть из кеша уже кешируемый файл я не знаю. Если из ядра надо, то можно посмотреть в сторону менеджера кэша. Например, есть CcPurgeCacheSection, которая, если я всё правильно понимаю, делает сабж. Но сам я Сс... функциями не работал, поэтому ничего умного не скажу. Если надо из юзера, то, наверное, только отменять кэширование при открытии файла.


Дата: Авг 14, 2004 17:48:58

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


Дата: Авг 15, 2004 03:58:37

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


Дата: Авг 16, 2004 00:32:50

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

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

„Открыли файл прочитали 4 кб, потом какой-то процесс открыл этот файл, изменил 2-4 байта и закрыл. А мы опять читаем из этого файла (мы его ещё не закрывали) те же самые 4 кб, а они всё те же что-ли? Из этого кэша прочитанные?“ - наш процесс увидит все изменения файла, поскольку кэширование осуществляется на уровне FILE STREAM т.е. один файл окрытый разными процессами представлен только одним stream-ом в памяти, это ни что иное как те-же самые страницы mapped на разные процессы.

pas
„Сделать файл не разделяемым“
это ничего не дает, на кэширование не влияет.


Дата: Авг 17, 2004 04:25:10

Всё. Проверил. CcPurgeCacheSection - работает так как надо.
Four-F
Спасибо за идею!


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.090