지난 시간
파일시스템 구현에 대해서 봅시다.
하드디스크에 접근하는 방법 2가지
- 순차 접근 : 테이프
- 임의 접근 : 하드디스크, 플래시 메모리, CD
chapter 11. File System Implementations
Allocation of File Data in Disk
- Contiguous Allocation
- Linked Allocation
- Indexed Allocation
Contiguous Allocation
파일에 블록이 3개로 구성될 때 들어갈 수 없는 공간 (외부 조각) 발생
늘어날 것을 예상해서 미리 공간을 늘리면 (내부 조각) 발생
swap area
- 프로세스 주소 공간 중에 일부를 물리적인 메모리에서 쫓아내고 나중에 다시 올려 놓음
- 속도 효율성 좋다 (빠른 I/O)
Linked Allocation
Indexed Allocation
이론적 내용
실제 사용하는 방법
UNIX 파일 시스템 구조
super block
- 어디가 빈 블록인지
- 어떤 블록이 사용되는지
- inode list가 어디서 부터 있는지 등등
Inode list (index node)
디렉토리 파일
파일이 작으면
- single indirect
파일이 크면
- double indirect
파일이 엄청 크면
- triple indirect
FAT File System
- 디렉토리가 모든 파일 정보 가지고 있음
- 다음 번 블록이 뭔지 FAT에 담고 있음
- FAT 크기 = Data block 크기
- FAT 파일 시스템 유실되면 안되니까 여러개 copy 해둔다
Linked Allocation 문제 보완
Free-space Management
Linked Free Space List on Disk
Counting
- 빈 블록 + 그 뒤에 이어지는 빈 블록 개수 표현
Directory Implementation
VFS and NFS
Page cache and Buffer Cache
Page cache
- Virtual memory의 paging system에서 사용하는 page frame을 caching의 관점에서 설명하는 용어
- Memory-Mapped I/O를 쓰는 경우 file의 I/O에서도 page cache 사용
- 프로세스의 주소 공간을 구성하는 페이지가 swap area에 내려가 있는가
페이지 캐시에 올라가 있는가
Memory-Mapped I/O
- File의 일부를 virtual memory에 mapping시킴
- 메모리에 이미 올라와있으므로 시스템 콜이 필요없음
- 메모리 상에 데이터를 읽고 쓰는 것처럼 파일에 읽고 쓸 수 있다.
- 매핑시킨 영역에 대한 메모리 접근 연산은 파일의 입출력을 수행하게 함
Buffer cache
- 파일 시스템을 통한 I/O 연산은 메모리의 특정 영역인 버퍼 캐시를 사용
- file system
- File 사용의 locality 활용
- 한 번 읽어 온 블록에 대한 후속 요청 시, 버퍼 캐시에서 즉시 전달
- 모든 프로세스가 공용으로 사용
- Replacement algorithm 필요 (LRU, LFU) -> 무조건 시스템 콜을 통해 일어나므로 운영체제가 LRU를 활용할 수 있다.
- 파일 데이터가 파일 시스템에 저장되어 있나 버퍼 캐시에 올라와 있나
통합 버퍼 캐시
- 최근의 OS에서는 기존의 버퍼 캐시가 페이지 캐시에 통합됨.
- 버퍼 캐시를 페이지 단위로 관리
통합 버퍼 캐시를 사용하지 않을 때와 사용할 때의 차이
Unified Buffer cache를 이용하지 않는 File I/O
memory-mapped I/O를 쓰는 경우에 page cache와 커널 영역의 buffer cache를 두 번 거쳐야 한다.
- read, write system call을 쓸 때는 그 내용이 buffer cache에 있든 없든 항상 운영체제에게 요청해서 받아와야 한다.
- mmap을 쓰게 되면 page cache에 올라온 내용은 운영체제의 도움을 받지 않고 사용자 프로세스가 직접 메모리접근을 통해 I/O를 한다(인터페이스의 차이)
mmap을 사용하는 이유
- mmap을 사용하면 이미 메모리에 올라온 내용에 대해서는 kernel의 도움을 받지 않고 (운영체제를 호출하지 않고) 자신이 직접 자신의 메모리에 접근하듯이 읽고 쓸 수 있다.
Unified Buffer cache를 이용하는 File I/O
buffer cache가 곧 page cache이므로 page cache(=buffer cache) 에 한번 접근하는 것만으로 I/O 처리가 가능하다.
Memory-mapped I/O를 쓸 때 처음 해당 페이지에 mapping된 파일을 읽으려고 하면 page fault가 발생한다. 그 때 시스템 콜을 통해 file system의 block을 해당 페이지에 올려놓는다. 그렇기 때문에 memory-mapped I/O를 쓰더라도 I/O 작업은 불가피하다.
- read, write system call을 하는 경우
- 해당 내용이 buffer cache에 올라와 있든 아니든 상관없이 운영체제에게 CPU 제어권이 넘어간다.
- CPU는 이미 올라와 있는 data는 사용자 프로그램에 copy해주고 메모리에 없다면 disk에서 읽어와서 사용자프로그램에 copy해서 전달한다.
- mmap인 경우
- 자신의 주소영역중에 일부를 file에 mapping하는 단계를 거치고 나면 사용자 프로그램의 주소영역에 page cache가 mapping된다.
- 이전처럼 buffer cache의 내용을 copy하는 것이 아니라 그냥 page cache 자체가 사용자 프로세스의 논리적 주소영역에 mapping되어 사용된다(page cache에 직접 읽고 쓴다).
프로그램의 실행
-
프로그램이 실행되면 실행 파일이 프로세스가 되며, 프로세스만의 독자적인 주소 공간이 만들어 진다.
-
이 공간은 코드, 데이터, 스택으로 구분되며 당장 사용될 부분은 물리적 메모리에 올라가고, 당장 사용되지 않는 부분은 스왑 영역으로 내려간다.
-
이때 코드 부분은 이미 파일 시스템에 있기 때문에 스왑 영역에 내리지 않고, 필요 없으면 물리적 메모리에서 지운다. 나중에 필요하면 파일 시스템에서 가져오면 된다.
-
code 부분 -> read-only라서 파일 시스템에 저장되어 있음, swap area에 내려가지 않는다
-
메모리에 프로세스를 올리는 loader가 쓰는 memory-mapped I/O의 일종이다. 프로세스의 주소공간 중 code 영역을 실행파일에 mapping시키는 것이다.
1. Memory Mapped I/O 수행
Memory-mapped I/O를 통해 데이터 파일을 사용하는 과정
- 프로세스가 일반 데이터 파일을 I/O하고 싶을 수 있다.
- mmap() 시스템 콜을 통해 해당 파일을 자신의 주소공간에 매핑
- 실제 메모리 상의 페이지에도 파일에 매핑된 페이지가 존재
- 이 페이지를 조회하고자 하면 아직 매핑만 된 상태이고 파일이 올라오지 않았으므로 page fault가 발생
- swap area에서 page를 불러오는 것이 아니라 file system에 가서 파일의 내용을 메모리에 올린다.
- 운영 체제는 데이터 파일의 일부를 프로세스 주소 공간에 매핑을 한다.
- 만약 데이터 파일이 매핑된 영역을 접근했을 때, 실제 물리적인 메모리에 페이지가 올라와 있지 않다면 페이지 부재가 발생한다.
- 그렇지 않으면 가상 메모리의 매핑된 영역은 물리적 메모리의 페이지 프레임과 일치가 되므로 프로세스가 데이터 파일에 대해 I/O를 하고 싶을 때 운영 체제의 도움 없이 독자적으로 I/O를 수행할 수 있다.
- 물리적 메모리에 올라간 데이터 파일과 매핑된 페이지 프레임을 쫓아내야 할 때는 스왑 영역으로 내리는 것이 아니라 수정된 사항을 파일 시스템에 적용하고 물리적 메모리에서 지운다.
- 현재 프로세스 B가 데이터 파일에 대해 Memory Mapped I/O를 수행하여 물리적 메모리에 페이지 프레임을 올려 두었는데, 프로세스 A도 이 페이지 프레임을 공유하여 사용할 수 있다.
2. read() 수행
- 프로세스가 일반 데이터 파일을 I/O를 하는 방법으로 read() 시스템 콜을 호출
- 운영체제가 현재 buffer cache(page cache)에 올라와있지 않은 데이터 파일을 buffer cache(page cache)에 등록한다. 그리고 사용자 프로세스 주소공간에 복사하여 사용할 수 있도록 해준다.
- 운영체제는 버퍼 캐시에 있던 내용을 복사하여 프로세스의 주소 공간에 할당한다.
3. Memory Mapped I/O vs read()
Memory Mapped I/O
- 가상 메모리에 올라 온 영역이 곧 파일이므로 시스템 콜 없이 I/O 작업을 할 수 있다.
- 페이지 캐시에 있는 내용을 복사할 필요가 없다.
- 여러 프로세스가 mmap() 을 사용하여 같은 영역을 공유하여 사용하면 일관성 문제가 발생할 수 있다.
read()
- 매번 운영 체제의 중재를 받는다.
- 페이지 캐시에 있는 내용을 복사해야 한다.
- 여러 프로세스가 read() 를 사용해도 일관성 문제가 발생하지 않는다.