디스크에 있는 파일 메타데이터
를 메모리로 불러오는 시스템 콜이다. (파일 read/write전에 해줘야 함)
파일을 열고 fd(파일 디스크립터)를 반환한다.
왜 read/write와 별도로 open()을 수행할까?
디렉토리를 찾는데 시간이 오래 걸리기 때문에 한번 open한 파일에 다시 디렉토리 접근하는 것을 막기 위함
(http://www.kocw.net/home/search/kemView.do?kemId=1046323)
root
→ a
→ b
순으로 차례대로 디렉토리에 접근해 메타데이터 정보를 가져온다. b
의 메타데이터를 Open File Table
에 올려두면 read/write 시스템 콜이 호출될 때 메타데이터를 통해 파일로 접근이 가능해진다.
Open File Table
: 오픈된 파일 메타데이터를 저장한다. 디스크의 파일 메타데이터와는 다르게 현재 해당 파일을 오픈한 프로세스의 개수와 프로세스별 파일 오프셋등을 저장하기도 한다.(파일 오프셋 : 프로세스가 현재 파일의 어느 위치에 접근중인지) 모든 프로세스가 글로벌하게 접근할 수 있다.fd (File Descriptor)
: Open File Table에 있는 메타데이터 위치를 가리킨다. 프로세스마다 자신의 PCB에서 저장하고 있다. (PCB는 프로세스가 오픈하고 있는 모든 파일들에 대한 정보를 저장한다.)
Open File Table
에 위치한 메타데이터를 찾아간다. 파일별로 접근 권한을 관리한다.
권한의 종류는 read/write/execute가 존재한다.
read와 execute의 차이
read 권한:
- 파일 내용을 읽을 수 있다.
- 디렉터리 내용을 열람할 수 있다. (하위 디렉터리/파일 목록 확인 가능)
execute(x) 권한:
- 실행 파일(바이너리, 스크립트 등)을 실행할 수 있다.
- 디렉터리로 이동(cd)할 수 있다.
- 디렉터리 내용을 열람할 수는 있지만, r 권한이 없으면 파일 내용을 읽을 수 없다.
즉, r 권한은 파일 내용을 읽는 것을 허용하고, x 권한은 실행 파일을 실행하거나 디렉터리로 이동하는 것을 허용.
ACM, ACL등을 통해 파일별 유저의 권한을 저장한다.
ACM은 행렬, ACL은 파일별로 유저를 연결리스트로 관리(Capability는 유저별 접근 가능한 파일을 연결리스트로 관리)
모든 유저에 대해 일일이 저장하는 것은 그만큼 공간 낭비.
모든 유저를 owner, group, public 세 그룹으로 구분하고 그룹별로 권한을 줄 수도 있다.
각 그룹에 대한 권한을 3bit로 표한하여(rwx) 총 9bit로 파일에 대한 권한을 설정 가능하다.
파일별로 패스워드를 등록이 가능하다.
물리적인 디스크는 논리적인 디스크 단위로 나누어져있다.
각 디스크에는 파일시스템이 생길 수 있는데, 특정 경로를 root경로로 두는 식으로 파일 시스템들을 구성할 수 있다. 이를 마운팅이라고 함.
처음부터 끝까지 차례대로 접근.
카세트 테이프 처럼 순서대로 읽고, 뒤로 돌아가고 싶으면 되감아야함.
원하는 부분에 바로 접근할 수 있음.
A->B->C로 되어있을 때, A만보고 C로 바로 건너 뛰는 것이 가능함.
디스크에 파일을 저장할 때는 동일한 크기의 sector단위로 저장한다.
저장하는 방식은 여러 방법이 있다.
장점
단점
파일의 각 부분들을 포인터로 연결해서 저장한다.
| FAT(File-Allication-Table) : LinkedAllocation의 단점인 Reliability와 포인터 공간 차지 문제를 해결한 파일 시스템)
파일이 커서 한 파일에 인덱스를 전부 저장할 수 없는 경우 Linked Scheme
방식 또는 Multi Level Index
방식을 사용할 수 있다.
Linked Scheme
: 인덱스 파일의 마지막 인덱스가 다음 인덱스 파일을 가리킴
Multi Level Index
: 2단계 페이징처럼 첫 번째 인덱스 파일을 실제 인덱스가 저장된 파일들을 가리키는 용도로 사용.
(어떤 파일 시스템이든 항상 0번 블럭에 부트 블럭이 존재한다.)
Unix는 Indexed Allocation을 사용하고 있어서 Inode에 인덱스들을 저장함. (direct blocks, single indirect, double indirect, triple indirect : 작은 파일들은 direct blocks만 사용)
Boot block
: 부팅에 필요한 코드 모음(부트스트랩 로더라고 부름)Super block
: 파일 시스템에 대한 전체적인 정보를 관리. (Inode들이 저장되는 위치, 현재 어느 영역의 Inode가 사용되고 있는지 등을 저장)Inode List
: 파일 이름을 제외한 파일의 모든 메타데이터 저장. 파일하나당 Inode가 하나씩 할당됨. (파일 이름은 아래 Data block의 Directory 파일에서 저장)Data block
: 파일의 실제 내용 저장 (Directory파일은 파일 이름과 Inode주소를 가지고 있음)마이크로소프트에서 만듦
LinkedAllocation 방식을 사용함. FAT에서 주소를 연결리스트로 관리중.
FAT
: 파일 위치 정보를 저장.(위치 정보만 FAT에 저장하고 나머지 메타데이터는 Directory가 가짐. Directory에서 첫 번째 위치를 가리키는 FAT주소도 가지고 있음) FAT의 크기는 Data block에서 사용중인 블럭 개수와 동일.(당연함. 블럭 위치정보라서)앞서 나왔던 Linked Allocation의 단점을 전부 해결했다고 봄
- 단점
- 직접 접근이 불가능하다. 포인터를 쭉~ 따라가면서 접근해야함.
- 앞에 sector가 잘못되면 뒤에 sector도 못찾아간다.(Reliability)
- 포인터만큼의 공간을 차지한다.(약 4byte?)
할당이 안된 빈 블럭들을 어떻게 관리할까?
블럭 개수 만큼 비트맵을 만들어서 비트로 상태 관리
빈 블럭들을 연결리스트로 저장
Indexed Allocation과 유사한 방법.
free block의 마지막 포인터가 다음 free block을 가리키는 모양새
빈 블럭들의 위치와, 해당 위치에서 몇 개의 블럭이 연속적으로 비어져 있는지를 저장.
(1, 3) -> 1번 위치에서 3개의 블럭이 비어져있다.
VFS(Virtual File System)
: 하나의 컴퓨터에서 여러 개의 파일시스템을 사용할 수 있다. 동일한 시스템콜로 다양한 파일시스템에 접근할 수 있게 해주는 layer.
NFS(Network File System)
: 로컬에 저장된 파일 시스템을 사용할 수도 있지만 원격으로 다른 서버에 있는 파일 시스템을 사용할 수도 있음. 분산 시스템에서 네트워크를 통해 파일을 공유하는 방법. (예시 사진에선 RPC를 사용해서 접근)
Page Cache
:
- Memory-Mapped I/O : 버퍼를 프로세스의 가상 메모리 영역과 매핑해서 사용. 완전 매핑이므로 레이스 컨디션 발생 가능. 반면에 파일 시스템에서 사용하는 read()/write()를 사용한 I/O는 버퍼의 내용을 메모리로 복사해서 사용하기 때문에 프로세스간 레이스 컨디션 발생하지 않음.
보통 프로세스의 code영역을 memory-mapped해서 사용한다고 한다.(read-only이라 수정할 일이 없기 때문)
Buffer Cache
:
Unified Buffer Cache
: 버퍼 캐시가 페이지 캐시에 통합됨. 버퍼 캐시도 페이지 단위로 관리. (512byte -> 4KB)
Unified Buffer Cache
여부에 따른 비교Unifed Buffer Cache를 사용하지 않을 때는 page cache에 저장한 내용을 한 번 더 buffer cache에 저장해야 한다는 단점이 존재.