본문 바로가기

Information Technology/OS

[운영체제] File System Implementations(2)

이 글은 개인의 학습을 목적으로 정리한 글입니다. 이점 참고하고 읽어주세요;)


Page cache: 페이지 단위(4KB)

 

Buffer cache: 파일 입출력 측면. 운영체제가 사용자의 요청을 받아서 디스크에서 가져온 정보를 사용자에게 바로 주지 않고 buffer cache에 저장한 뒤에 전달. 이후에 버퍼에 저장된 내용을 요청하면 다시 디스크까지 가지 않고 버퍼에서 데이터를 전달. 논리적 블록(디스크의 섹터, 예전에는 512Byte. 페이지 단위인 4KB에 비해 작음)

 

예전에는 버퍼 캐시와 페이지 캐시를 구분해서 사용했다면, 최근에는 Unified Buffer Cache를 많이 사용. 버퍼와 페이지 캐시를 통합. 버퍼 캐시의 단위도 작은 단위가 아닌 페이지와 동일(4KB)한 단위의 블록을 사용함. 페이지를 용도에 맞춰서 할당해줌. 

 

Memory-Mapped I/O(File): 파일 입출력을 read/write syscall을 통해 작업하지 않고, 프로세스의 주소 공간의 일부를 파일에 맵핑. 이렇게 하면 메모리 접근 연산을 통해 파일 입출력이 가능.


1) Unified Buffer Cache를 사용x

가. memory-maped: 명령어를 통해 memory mapped 선언. 처음엔 똑같이 데이터를 디스크에서 버퍼 캐시로 가져옴. 그다음 그 내용을 page cache에 복사. 사용자는 이제 자신의 메모리 영역에 읽고 쓰듯이 작업을 하면서 파일 입/출력 가능. 일단 메모리에 올라오면 운영체제의 write/read syscall처럼 운영체제의 도움 없이 스스로 읽기/쓰기 작업이 가능함. 하지만 어떤 방법을 사용하든 버퍼 캐시에 접근을 해야 함

 

2) Unified Buffer Cache를 사용

운영체제가 공간을 따로 나누지 않고 page cache에서 분할해서 사용하는 경우 -> 

  가) I/O 작업 -> syscall을 통해 운영체제에게 CPU 제어권이 넘어감. 

  나) memory-mapped: 초반 메모리 주소-파일 맵핑 작업 이후에는, 사용자 프로그램의 주소 영역에 페이지 캐시가 맵핑이 됨. 그러면 페이지 캐시이자 버퍼 캐시가 모두 파일에 맵핑되었기 때문에 운영체제의 도움 없이 파일 I/O 작업이 가능

 

실행파일 -> 프로세스가 됨 -> 프로세스별 주소 공간 생성 -> 필요한 부분들만 물리적 메모리에 올라감

*코드 부분 영역은 실행 파일에 존재하기 때문에 swapping에 의해 쫓겨날 때에도 Swap area에 저장할 필요가 없음(어차피 실행 파일에 있는 걸 가져오면 됨). 즉 가상 메모리에 존재하는 프로세스의 Code 영역은 파일 시스템의 실행 파일과 맵핑. 파일 IO에도 mmaped를 사용할 수 있지만, 실행 파일의 코드 부분을 맵핑하는 용도로도 사용.

프로그램이 실행되다가 파일 시스템에서 데이터를 가져오는데, I/O write/read가 아니라 memory mapped를 사용하고 싶으면 커널 영역에 mmap 요청(파일 시스템의 일부를 자신의 메모리 공간에 맵핑해달라는 요청). 그럼 운영체제가 데이터 파일의 일부를 프로세스의 가상 메모리 주소 공간에 맵핑. 이후에 프로세스는 해당 데이터에 접근할 때 OS의 도움 없이 그냥 데이터가 맵핑된 자신의 가상 메모리에 접근함으로써 write/read 작업이 가능(syscall 필요가 없으므로 더 빠름).

 

*주의할 점: 하나의 프로세스가 아닌 여러 프로세스가 동시에 특정 데이터를 memory-mapped 방식으로 사용하면, unified buffer cache 방식에서는 이미 다른 프로세스에 의해 memory-mapped 되어 물리적 메모리에 올라온 데이터가 여러 프로세스에 의해 사용되기 때문에 데이터의 일관성 문제가 발생할 수 있음.

read()의 경우에는 그냥 물리적 메모리의 버퍼(&페이지) 캐시에서 값을 복사해서 사용하기 때문에 문제가 없지만, write()에서 일관성 문제가 발생할 수 있음