O_DIRECT | O_ASYNC로 파일을 열고 fsync 또는 fdatasync를 사용하지 않고 동일한 디스크 섹터에 두 개의 동시 쓰기를 수행하면 Linux 디스크 하위 시스템이나 하드웨어 디스크 컨트롤러가 해당 디스크의 최종 데이터 섹터는 두 번째 쓰기가 될 것인가?디스크 컨트롤러가 쓰기 장벽이없는 경우 같은 섹터에 대한 동시 쓰기를 어떻게 처리합니까?
사실 O_DIRECT가 OS 버퍼 캐시를 우회하는 동안 데이터는 궁극적으로 하위 레벨 IO 대기열 (디스크 스케줄러 대기열, 디스크 드라이버 대기열, 하드웨어 컨트롤러의 캐시/대기열 등)에서 종료됩니다. IO 알고리즘을 엘리베이터 알고리즘까지 추적했습니다. 예를 들어
요청의 다음 순서는 디스크 스케줄러 큐
write sector 1 from buffer 1
write sector 2 from buffer 2
write sector 1 from buffer 3 [Its not buffer 1!!]
엘리베이터 코드가 각각 버퍼 1, 2에서 sector1,2을 병합 할 수있는 "다시 병합"을 할 것이라고에서 생을 마감합니다. 그런 다음 디스크 2 개의 디스크 IO를 발행하십시오. 하지만 디스크 섹터 1에 대한 최종 데이터가 버퍼 1 또는 버퍼 3 (드라이버/컨트롤러의 다시 쓰기 의미에 대해 잘 모르는 경우)에 있는지 확실하지 않습니다.
시나리오 2 :
write sector 1 from buffer 1
write sector 500 from buffer 2
write sector 1 from buffer 3
방법이 시나리오를 처리 할 것인가? 더 기본적인 질문은 O_DIRECT 모드에서 AIO를 사용하여 쓰기를 수행 할 때 명시적인 쓰기 장벽이없는 경우 디스크 시퀀스 스케줄러의 대기열에 이러한 일련의 요청이 끝날 수 있습니까?
"예"인 경우 "동일한 섹터에 여러 번 쓰면 최종 기록이 최종 기록이됩니다"와 같은 주문 보증이 있습니까?
또는 비 결정적인 순서 [디스크 컨트롤러/검색 시간을 최적화하기 위해 장벽 내에서 쓰기를 재개하는 캐시] 왼쪽에
wrt bios, 커널은 버퍼 캐쉬 페이지 (응용 프로그램 소유가 아닌) 인 경우 버퍼를 수집하고 잠급니다. 또한 IOMMU가 DMA를 사용하여 완료 될 때까지 페이지를 NO ACCESS로 설정하도록 CPU에 (의미 상으로) 요청할 것이라고 생각합니다. 그렇지 않으면 정상적인 mmaped 쓰기의 경우 전체적으로 많은 레이스가 발생합니다. – Tautology
mmaped가 아닌 쓰기의 경우, 커널 공간에 대한 버퍼 복사 (dma 버퍼), AFAIK – Tautology