파일 시스템은 크게 두 가지로 나눌 수 있다. 프로세스가 파일에 접근하는 방식인 In-memory structure, 전원이 없을 때 휘발되지 않고 데이터가 저장되는 On-disk structure 이다.

In-Memory Structure

파일을 open 할 때와 read 할 때의 동작을 나타낸다. open 은 단순하게 하나의 파일을 어떤 방식으로 읽을 지를 나타내는 것이며, read 는 open 된 파일에서 실제 데이터를 읽어오는 것이다.

따라서 open 시 디렉토리에서 file-control block 까지만 찾는다.

read 시에는 per-process open-file table과 system-wide open-file table 을 거쳐 실제 data 에 접근하게 된다.

이때 system-wide open-file table 은 커널에 존재하는 파일 테이블이며, per-process open-file table은 각 프로세스 별 존재하는 파일 테이블이다. 각 인덱스는 시스템의 파일 테이블을 가르킨다.

image

기본적으로 각 프로세스에서 file-table 을 가지고 실제 커널에 존재하는 file-table 을 매핑시킨다. 이때 자세히보면 각 프로세스의 file-table 은 4번째부터 매핑되는 것을 볼 수 있다. 이는 모든 프로세스는 파일 3개를 오픈한 상태로 가지기 때문이다. 그래서 0,1,2는 항상 고정되어있다.

  • 0번 : standard input
  • 1번 : standard output
  • 2번 : standard error 3번부터 실제로 프로세스가 사용하는 파일이 들어가기 시작한다.

오른쪽의 in-memory partition table 은 성능을 높이기 위해 다른 메모리에 존재하는 데이터 스트럭쳐이다. Directory cache(dir) 와 Buffer cache(file) 를 합쳐서 Buffer cache 라 부르며, 자주쓰는 파일을 메인 메모리에 가져다 놓고 쓰는 것이다.

image

On-disk Structure

전원이 없을 때 디스크 파일 시스템에 데이터가 저장되는 스트럭처이다.

파티션 1에는 시스템이 처음 시작되었을 때 부팅을 위한 정보들이 추가적으로 들어있다. 내부구조를 자세히 살펴보자.

  • Boot loader : 운영체제가 시동되기 전에 미리 실행되면서 커널이 올바르게 시동되기 위해 필요한 모든 작업을 마무리하고 운영체제를 실행시킨다.
  • super block : 타입과 블럭의 수 등 file system metadata 가 들어있다.
  • bitmaps : free space management를 위한 data structure 이다. 디스크 블락의 사용 여부를 비트로 나타낸다.
  • i-node : FCB 라 하며 file matadata 이다.

이후에는 모두 파일 시스템에 존재하는 파일(=file+dir)이다. 제일 첫번째 데이터는 Root 디렉토리이다.

파일 시스템은 Disk Block으로 관리한다. 4GB 짜리 하드디스크를 사면 디스크블락은 4KB 이므로 1M 개의 블락을 관리하며 하나는 Root 디렉토리라고 할 수 있다.

image

Free Space management

앞서 bitmaps가 free space management를 위한 data structure 라고 설명했다. 여기서 free space management 란 말 그대로 비어있는 디스크 블락을 관리하는 방법이다.

bit map으로 모든 디스크 블락을 사용 여부를 1/0으로 표시한다.

block size = 2^12 bytes (4kb) disk size = 2^30bytes (1GB)

라고 할 때,

disk block 수는 2^18. 이며 하나 당 한 비트가 필요하므로 2^15 byte가 필요하다 (=32K bytes)

여기서 비어있는 디스크를 표시하는 것 뿐만 아니라 이제 데이터를 저장하기 위해 실제 디스크 블락을 할당해주어야한다.

Linked list

가장 처음의 디스크 블락 하나를 할당해주고 데이터와 함께 다음 디스크 블락의 위치를 저장해 디스크 블락을 할당하는 방법이다. 자료구조의 Linked list 와 같은 구조이다. 만약에 중간에 하나의 디스크 블락이 고장나면 그 뒤는 모두 읽을 수 없다.

image

Location of metadata (FCB)

파일이 하나 생기면 metadata, 속성 들을 저장하고 있는 블럭이 하나 함께 생성된다. 이를 File Control Block 이라 한다.

  • Directory data : directory에 어떤 파일들이 존재하는 지 나타내는 데이터이다.

이 때 실제 파일 데이터를 저장하는 세 가지 방법이 있다.

  1. In the directory entry 디렉토리 데이터에 파일 이름과 FCB 모두 저장하는 방법
  2. In the separate data structure 디렉토리 데이터에는 파일 이름과 FCB가 저장된 위치 정보만 저장하는 방법. 포인터를 따라가면 실제 FCB 를 읽을 수 있다.
  3. A hybrid approach FCB의 위치정보를 저장하되 일부 중요한 정보들은 디렉토리 데이터에 직접 저장한다.

image

Allocation Methods

이름과 오너, 변경날짜 등 파일 관련 모든 정보는 FCB에 저장한다. 이때 제일 중요한 것은 FCB가 가르키는 파일의 실제 데이터가 어디에 저장되어 있는가이다. 파일의 크기가 커서 디스크 블락이 많이 필요하면 여러 디스크 블락들이 어디에 어떻게 저장되어있는 지 관리해야한다.

Contiguous Allocation

파일을 모두 연속적으로 배치하는 방법이다. 시작위치와 길이만 알면 파일의 위치를 모두 알 수 있기에 저장하기 심플하다. 단점은 기존 파일에 데이터가 추가되어 디스크 블락이 더 필요할 때 다른 파일에 막혀 문제가 발생한다. 따라서 파일의 크기가 변하는 것에 적합하지 않다. 만약 사용한다면 수정이 없는 읽기 전용 파일에 사용할 수 있다.

image

Linked Allocation

시작 위치만 저장하면 블락에 다음 위치를 표시하는 포인터가 존재해 따라간다. Linked List와 동일하며 파일 크기 변화가 쉽다. 따라서 각 디스크 블락에 다음 번 디스크 블락을 알려주는 포인터를 할당해야한다. 파일을 읽기 위해서는 처음부터 끝까지 차근차근 따라가야하기 때문에 원하는 위치를 읽는 Random access가 불가능하다.

문제는 중간에 하나가 손실되면 뒤쪽이 모두 날라가기 때문에 신뢰성 문제가 발생한다.

image

이를 해결하기 위해 각 파일들이 실제 가지는 디스크 블락들을 모두 관리하는 FAT (File-Allocation Table)을 만들어 관리할 수 있다. 하지만 하드디스크 용량이 커지면서 모든 디스크 블락을 관리하기가 어려워지며, FAT가 날라가면 디스크 전체가 날라가기 때문에 신뢰도 문제를 해결했다고 할 수 없다.

image

Indexed Allocation

첫 번째 디스크 블락에 인덱스를 모두 저장하는 방법이다. FAT는 모든 파일이 날라갈 가능성이 있지만, 이 방법은 하나의 파일만 날라가니 신뢰도 측면에서 우수하다.

첫 디스크 블락에 디스크 블락이 순서대로 저장되어있기에 Random access 도 가능하다.

image

만약 저장해야할 디스크 블락의 수가 너무 많아서 용량이 부족해지면 어떻게 저장을 해야할까?

이 문제를 해결하기 위해 등장한 것이 index 이다.

실제 파일에 다이렉트 블락 12개(4kb * 12)가 존재한다. 만약 12개의 블락보다 더 많은 데이터를 저장해야한다면 sigle indirect 를 사용한다.

하나의 블럭 single indirect 도 같은 4kb 의 크기를 가지고 있다. 디스크를 가르키는 포인터로 4 바이트를 사용한다면 하나의 디스크 블락에서는 총 1k 개의 포인터를 가질 수 있다. 그리고 각 1k 의 디스크 블럭은 4kb 의 크기를 가지고 있기 때문에 하나의 single indirect 는 (1k * 4kb) 를 저장할 수 있다.

double indirect 는 같은 방식으로 (1k * 4kb * 4kb) 를 저장할 수 있다.

image

UNIX File System (UFS)

아래 그림은 실제로 유닉스에서 파일에 접근할 때의 과정을 나타낸 그림이다. root 라는 디렉토리의 파일 컨트롤 블락은 실제 i-node(0)에 저장되어있기 때문에 항상 바로 접근할 수 있다

i-node(0)에는 이름은 root, 타입은 디렉토리, directory data 가 어디에 저장되어있는 지 나타나있다. 위에서는 10000번지에 존재한다.

10000번지 디스크 블락에는 root 디렉토리에 존재하는 파일이름과 각 i-node가 존재하는 디스크 블락 번호 테이블이 존재한다.

100 번을 읽으면 bin 디렉토리에 접근할 수 있으며 다시 directory data에 접근한다.

11000번지에 접근하면 bin 디렉토리의 내용들이 존재하며 a.out 파일을 읽기 위해 i-node(500)으로 이동한다.

이제 실제 내부에 파일 데이터를 확인할 수 있으며, 12개의 다이렉트 파일과 1개의 싱글 인다이렉트 파일이 존재한다. 650을 읽으면 다시 인덱스가 존재하고 안에 disk block들이 존재한다.

만약 a.out파일을 또 읽으면 같은 과정을 거치기에는 복잡하기 때문에 캐싱을 사용한다.

image

Performance, Efficiency

디스크 블락의 크기가 커지면 disk rate이 높아진다. 한번 움직여서 많이 읽어야(= 디스크 블락의 크기가 커야) 성능이 높아진다.

  • Space utilization : 메모장에 1byte를 저장하더라도 하나의 디스크 블락에 저장하기에 디스크 블락이 크면 남는 공간이 많다. 즉 internal fragmentation이 일어난다.

image

Read Ahead

100번을 읽으면 101번도 읽을 확률이 높으니 미리 읽어 성능을 높일 수 있다.

Buffer Cache

자주 사용되는 데이터는 또 사용될 확률이 높으니 캐싱해 놓으면 일련의 과정을 생략할 수 있다.

Caching Writes

Write 할 때마다 하드디스크에 바로 저장하는 것이 아니라 모아서 저장하는 버퍼와 같은 개념이다. 메인메모리에만 데이터가 바뀌어있는데 메모리가 날라가면 저장이 안되므로 신뢰성 문제가 발생할 수 있다.

Reliability

비 정상적인 것을 복구할 수 있는가에 대한 문제이다.

Log Structured File System (Journal File System)

Caching Write에서 어떤 함수가 호출되었는지 journal 에 요약해서 기록하고 하드디스크에 저장되면 삭제한다. 이를 통해 신뢰성 문제를 극복할 수 있다.

업데이트:

댓글남기기