운영체제 강의노트 - File Systems Implementation 1

조해빈·2023년 5월 29일
0

OS

목록 보기
8/9
post-thumbnail

LECTURE is here

KOCW 온라인에서 제공되는 이화여대 반효경 교수님의 OS 강의에 대한 정리 요약

  • 노션에 기록했듯 CSAPP과 함께 천천히 병행
  • 연관 게시글은 강의 진행 순서대로 정렬되어 있지 않고, 내 필요에 따라 강의의 주제를 선택해 듣는다.
  • 온라인 상의 타인들이 올려놓은 연관 자료 역시 함께 참고한다.

파일 접근 방법(Access Method)

파일 접근 방법은 시스템이 제공하는 파일 정보의 접근 방식을 뜻한다. 이는 매체에 따라 다르다. 테잎 등은 순차 접근밖에 안 되고 하드디스크나 플래시 메모리, cd 등은 직접 접근이 가능한 매체이다. 그러나 매체에 무관하게 어떻게 관리하느냐에 따라 달라지기도 한다. 디스크가 파일에 접근하는 방식은 순차접근과 직접 접근 두 가지 방식이 있다.

1️⃣ ) 순차 접근(sequential access):

카세트 테이프를 사용하는 것처럼 접근하는 방식이다. a-b-c 순으로 정보가 저장되어 있다고 하면, c만 접근하고 싶다고 해도 c에 접근하기 위해서는 반드시 a-b를 거쳐가야 한다.

2️⃣ ) 직접 접근(direct access, random access):

LP 레코드판과 같이 해당 위치에 다이렉트로 이동해 접근하는 방식을 뜻한다. 임의로 접근한다기보다 어디에 있든 해당 위치로 바로 접근하는 방식을 뜻한다.
예컨대 1-2-3-...-10의 순으로 파일이 나열되어 있다고 하면 파일 1에 접근했다가 곧바로 10으로 갈 수도 있고, 5에 있다가 10으로 갈 수도, 9에 있다가 10으로 갈 수도 있다. 하지만 세 가지 방식 모두 한 번에 이동하는 것이며 출발지가 임의이기 때문에 random access라고 생각하면 될 듯하다.

Allocation of File Data in Disk

파일이란 크기가 균일하지 않다. 이 임의의 파일을 동일한 크기의 단위로 나누어 저장하고 있다. 파일 시스템이라던지 디스크의 외부에서는 이 단위를 "논리적 블록"이라 부르고, 디스크 내에서는 이 단위를 "섹터(sector)"라 부른다. (이는 어쩌면 메모리 관리 기법 중 페이징 기법과 유사해 보인다.)

✅ 섹터와 블록의 차이?

섹터는 디스크의 최소 저장 단위로, 크기는 512바이트이다. 블록 역시 동일한 크기이다.

섹터는 물리 디스크에서 가리키는 물리적인 최소 저장 단위이다.
블록은 파일 시스템 상에서 논리적인 최소 저장 단위라고 보면 될 듯 하다.

간단한 하드디스크(HHD) 구조 소개

섹터(Sector)

  • 하드 디스크의 플래터 위에 데이터를 기록할 수 있는 최소 단위 == 가장 작은 저장 단위!.
    섹터는 즉, 자체적으로 주소를 가지고 있는 최소 스토리지의 단위이다.
    최근에는 하나의 트랙에 다수의 섹터들이 들어가 있으며 플래터에 수천 개의 트랙들이 있을 수 있다.
  • 일반적으로 섹터 크기는 512바이트에서 4킬로바이트(4096바이트) 사이. 대표적으로 섹터는 512byte의 유저 데이터를 가지고 있지만, 몇몇 디스크들은 더 큰 섹터 사이즈로 초기화 되어 있기도 하다.
  • 블록(Block) 단위에서 섹터는 블록과 1:1로 본다.
  • 추가적으로 섹터는 유저 데이터뿐만 아니라 다른 정보도 가지고 있는데, 이는 섹터 번호, 헤드 번호 또는 플래터 번호 그리고 트랙 번호 등의 메타데이터들이다. ➡️ 이런 정보들은 컨트롤러가 정확한 데이터의 위치를 찾아내는데 도움을 주지만, 공간을 좀 더 소모한다. (예를 들면, 500GB의 디스크가 실제로는 약 465.7GB의 유저 데이터를 보유할 수 있으며 나머지 약 34.3GB는 메타데이터로 사용 된다.)

클러스터(Clustter)

  • 데이터를 할당하는 최소 단위.
  • 클러스터는 일반적으로 여러 섹터의 집합이며, 클러스터 크기는 파일 시스템에 따라 다를 수 있다.

트랙(Track)

  • 트랙은 섹터(Sector) 라는 작은 단위들로 나눠져 있다. 섹터가 쭉 나열되어 있는 것이 곧 트랙이다.
  • 트랙은 숫자가 붙여져 있으며 플래터 바깥면부터 0으로 시작 된다.
  • TPI (Traks per Inch)로 플래터에 트랙이 얼마나 빽빽하게 채워져 있는지 알 수 있다.

실린더(Cylinder)

  • 섹터(Sector)와 트랙(Track)은 물리적으로 실존하는 존재이지만 실린더(Cylinder)는 "논리적인 단위"이다.
  • 실린더는 각 드라이브 플래터 표면에 동일한 인덱스(?)의 트랙들의 집합으로, '각 Platter의 n번 Track의 집합'을 실린더(Cylinder)라 할 수 있는 것이다. 그림을 참고하면 이해할 수 있을 것.
  • 헤드는 트랙 번호가 아닌 이 실린더 번호를 참조하게 된다.

플레터(Platter)

  • 하드 디스크 드라이브(Hard Disk Drive, HDD)의 회전하는 디스크 원판.
  • 앞뒷면 모두 마그네틱 소재로 표면이 코팅되어 있고, 자성을 이용하여 디스크에 부호화하게 된다.
  • 즉, 하나 또는 다수의 평평한 디스크들을 플래터라고 하며, 데이터는 이곳 플래터에 바이너리 코드 (0s 그리고 1s)로 기록된다.
  • 플래터의 수가 디스크 용량을 결정짓게 된다.

저장 용량 계산하기 (예시)
섹터 저장 용량 : 512bytes
트랙당 섹터 수 : 63개
실린더의 트랙 수 ( == Platter 갯수) : 16개
Cylinder 갯수 ( == Track 갯수) : 4092개

하드디스크 총 용량 = 512 63 4092 * 16 = 2,111,864,832 bytes

연속 할당(Contiguous Allocation)

앞서 살펴봤듯 디스크에 파일을 저장할 때는 보통 동일한 크기의 섹터 단위로 나누어 저장한다.

"디렉터리"는 일종의 파일이며, 파일들의 메타데이터를 내용으로 가지는 파일이다. 해당 파일에는 파일의 이름과 위치 정보 등이 저장되어 있어, 우리는 이를 기반으로 시작 위치와 길이를 가지고 디스크에 연속적으로 적재할 수 있다.

즉, 디스크 상에 연속해서 저장하는 기법이다. 하나의 파일을 저장할 때 인접한 섹터들에게 통째로 저장하는 방법이며 모두 인접한 인덱스를 가지게 된다.

장점

  • 빠른 입출력: 한 번의 seek/rotation으로 많은 바이트를 전송할 수 있다.
    하드디스크같은 매체는 대부분의 접근 시간이 헤드가 이동하는 시간이다. 얼마나 읽어야하는지, 즉 파일의 용량은 사실상 상관 없고, 밖->안쪽 트랙으로 이동하는 시간이 접근 시간에 있어 핵심이다. 한 번 이동 즉 seek해서 한꺼번에 많은 용량의 파일을 받아오면 더 이상의 seek가 필요 없을 것이다.
    • 이미 run 중이던 프로세스의 swaping area용: 파일 시스템 즉, 파일을 저장하는 것이 아니라, 프로세스가 끝나면 지워질 비영속성 데이터들에 대해서 대용량의 크기를 빠르게 디스크로 swap out, 메모리로 swap in 해야 하기 때문에 속도 효율성 > 공간 효율성의 경우 연속 할당(Contiguous Allocation)이 적합하다.
    • realtime file용: deadline이 있고, 빠른 입출력이 필요한 경우 연속 할당(Contiguous Allocation)이 적합하다.
  • 직접 접근(direct access) 가능 ⭕️: 시작 위치에 일정 숫자를 더하면 중간 위치 블럭을 미리 볼 수 있다.

단점

  • 외부 조각 문제(외부 단편화): 모든 파일의 크기가 균일하지 않은데 연속적으로 파일을 적재해야 하기 때문에, 비어 있는 공간이 블럭 2개인데 블럭 3개로 구성된 파일은 들어갈 수 없어 비어 있는 공간을 활용할 수 없다.
  • File grow가 어렵다: 파일은 중간중간 수정하며 크기가 커질 수 있는데, 이에 대한 제약이 있다는 것이다.
    • 이를 대비해서 파일 생성 시 얼마나 큰 hole을 배당할 것인가? 미리 빈 공간을 확보해놓을 수 있다.
    • 커질 것을 대비해서 grow 가능 vs 그러나 낭비(내부 조각 문제(내부 단편화)) 발생 가능성

연결 할당(Linked Allocation)

파일의 데이터를 디스크에 연속적으로 배치하지 않고 빈 위치 아무 곳에나 배치하는 기법이다.

디렉터리 파일에는 시작 위치와 종료 위치만 가지고 있고, 모든 중간 위치는 실제 위치에 기록되어 있다. 마지막 섹터에 가면 끝났다는 표시 즉 -1이 표기되어 있다.

장점

  • 외부 단편화가 발생하지 않는다. 즉, 할당되지 못하고 노는 섹터가 생길 확률이 낮아진다.

단점

  • 직접 접근 (direct access) 불가 ❌: 중간 위치를 보려면 앞에 부분을 모두 거쳐 내용을 봐야 비로소 중간 위치를 볼 수 있다. 즉, 순차 접근(sequential access)만 가능해 한 파일에 대한 건너뛰고 읽기가 불가하다.

    • 디스크라는 매체는 애초에 직접 접근이 가능한 매체지만, 파일 관리 방법을 linked allocation으로 하면 직접 접근을 할 수 없고 순차 접근만 할 수 있게 된다. 고로 seek 하는데 시간이 많이 걸린다.
  • Reliability 문제: 한 섹터가 고장 나 포인터가 유실되면(bad sector가 나면), 뒷부분의 포인터들을 완전히 다 유실하는 문제가 발생할 수 있다.

  • Pointer를 위한 공간이 block의 일부가 되어 공간 효율성을 떨어뜨린다.

    • 디스크의 섹터는 512 byte, 컴퓨터에서 디스크에 접근할 때는 디스크 저장 단위 512 byte의 배수로 구성되어야 한다.
      이때 다음 위치를 가리키는 포인터는 4 byte를 소요 → 실제 데이터 저장 공간은 (512 - 4 =)508 byte가 된다.
      이렇게 되면 한 섹터에 저장될 내용이 포인터에 대한 저장 때문에 두 섹터에 저장되어야 하는 비효율이 발생한다.

    • 🚩 약간의 변형! ---> File-allocation table(FAT)(파일 할당 테이블) 시스템
      : 포인터를 별도의 위치에 보관해서 reliability와 공간 효율성 및 직접 접근(direct access)도 가능하게 하는 방법이다. MS-DOS, OS/2, Windows 등에서 사용하고 있다. 색인 할당과 닮았지만 다르다. 더 아래에서 설명할 것이다.

색인 할당(Indexed Allocation)

직접 접근이 가능하게 하기 위해! 디렉터리 파일에 위치 정보를 바로 저장하는 것이 아니라 위치 정보에 대한 메타데이터를 "인덱스 블럭"에 저장하는 방법이다. Unix/Linux 등에서 사용한다.

인덱스 블럭에는 파일의 내용 대신 어디 어디에 저장되어 있는지 위치 정보를 한 블록(block) 하나에 쭉 열거한 것이다.

장점

  • 외부 단편화가 발생하지 않는다.
  • 직접 접근(direct access) 가능 ⭕️

단점

  • 작은 크기의 파일일 경우엔 공간 낭비이다. 아무리 작은 파일이더라도 index, 실제 데이터 저장으로 2개의 블럭이 필요하기 때문이다. 실제로, 많은 파일들의 크기가 작다.
  • 너무 큰 파일의 경우 하나의 블럭으로 인덱스를 저장하기 부족하다.
    • 🚩 해결방안) linked scheme의 사용: 인덱스 블럭이 파일의 크기를 다 커버하지 못할 때엔, 맨 마지막에는 내용이 아니라 또 다른 인덱스 블럭을 가리키게 한다.
    • 🚩 해결방안) multi-level index의 사용: 애초에 하나의 인덱스 블럭이 직접 파일의 위치를 가리키게 하는 게 아니라 또 다른 인덱스를 가리키게 한다.

주요 파일시스템들

위에서 살펴본 이론들은 기본적인 내용으로, 실제 파일 시스템에서는 어떤 할당 방법을 어떻게 변형해서 쓰는지 알아본다.

UNIX 파일시스템의 구조

UNIX 파일 시스템의 구조는 부트 블록(Boot Block), 슈퍼 블록(Super Block), I-node(Index node) 블록, 데이터 블록으로 구성된다.

부트 블록(Boot Block)

부팅에 필요한 정보 (bootstrap loader)를 담고 있다.
어떤 파일시스템이건 제일 먼저 부트 블록이 앞에 나오게 되있다. 약속이다.
항상 0번 블럭에 저장한다. 메모리에 올리면 OS 커널 위치를 찾아 메모리에 올려 정상적인 부팅이 이루어지게 한다.

슈퍼 블록(Super Block)

파일 시스템에 관한 총체적인(어디가 빈 블럭이고 어디가 사용 중인 블럭인지, 어디까지가 i-node 리스트이고 어디서부터가 실제 데이터인지) 정보를 담고 있다.

I-node List

우린 일전에 한 파일에 대한 메타데이터가 그 파일을 가진 디렉터리 파일에 저장되어 있다고 배웠다.

하지만 실제 구현에서는, 특히 UNIX의 파일 시스템에선 디렉터리 파일은 메타데이터를 지극히 일부만 가지고 있다. 실제 파일의 메타데이터들은 별도의 위치에 빼서 보관한다. 그 위치가 "I-node(Index node) 리스트"이다.

아이노드 리스트는 아이노드들이 하나씩 저장될 수 있는 위치가 있고, 파일 하나당 하나의 I-node(Index node)가 할당된다. 딱 하나, 파일 이름을 제외한 파일의 모든 메타데이터를 저장한다. 이는 파일의 소유주, 접근 권한, 타임 스탬프(마지막으로 수정된 시각), 위치 정보 등이다.

데이터 블록(Data block)

파일의 실제 내용을 보관하는 블록이다. 파일 이름이 저장되어 있다.
이 중 디렉토리 파일은 자신의 디렉토리에 속한 파일들의 이름 + 해당 I-node 번호를 가지고 있다.

🧷

이 시스템은 위에서 알아본 색인 할당을 변형하여 차용하는 시스템이다.

i-node는 미리 할당된 고정 사이즈이다. 위치 정보를 나타낼 수 있는 가질 수 있는 포인터 갯수도 고정(유한)이지만, 굉장히 큰 파일도 표현할 수 있다.

위 그림의 하단을 보자.

direct blocks는 파일이 존재하는 인덱스를 저장하는 인덱스 블록이다. 파일의 크기가 크지 않다면 이 블록을 이용하여 파일을 접근할 수 있다.

direct blocks으로 커버할 수 있는 크기보다 저장 용량이 큰 파일은 single indirect를 통해서 하나의 level을 두어서 저장하는 방식을 취하고, 그보다 더 큰 파일은 double indirect, 더 큰 파일은 triple indirect 방식을 취한다.

FAT 파일시스템

FAT은 마이크로소프트 사가 MS-dos를 만들었을 때 처음 고안한 파일시스템이다.

부트 블록(Boot Block)

동문.

FAT

위치 정보만을 따로 빼서 FAT에 저장하고 있다.

루트 디렉토리(Root Directory)

루트 디렉토리의 각 항목은 파일 또는 디렉토리를 나타내며 이름, 속성, 크기 및 위치 정보와 같은 해당 파일 또는 디렉토리에 특정한 메타데이터를 저장한다.

  • 파일의 경우 메타데이터에는 파일 이름, 속성, 크기, 저장 장치에서 파일의 데이터 블록 위치와 같은 세부 정보가 포함.
  • 디렉토리의 경우 메타데이터에는 디렉토리 이름 및 속성과 같은 정보가 포함.

Data 블록(Data Block)

파일의 실제 내용을 보관하는 블록이다. 동문.

메타데이터를 모두 디렉토리 파일이 가지고 있다. 파일 이름은 물론 접근 권한, 소유주, 파일의 첫 번째 블록 위치 등을 가진다.

🧷
❗️ 연결 할당의 단점(임의 접근 불가, 신뢰성 문제, 공간 효율성 문제)을 전부 극복한다.

비슷해보이나 연결 할당과 다른 점이 있다면,

연결 할당에서는 첫 블록이 끝날 때 파일이 큰 경우 두번째 블록의 위치를 저장하고 있다고 했다.
FAT 파일시스템은 메모리에 FAT이라는 별도의 작은 배열에 저장하는 것이다.

이 FAT이란 배열의 크기는 디스크가 관리하는 데이터 블록의 갯수만큼이다. 이 배열은 각각 숫자를 하나씩 담는데, 그 블록의 다음 블록이 어디인질 담는 것이다. 한 파일에 대한 마지막 블록이라면 EOF가 표기되어 있다.

기존의 연결 할당 기법에서는 직접 접근이 안 되고 디스크 헤드가 직접 이동해야 했는데, 이 방법에선 FAT를 잠시 순회하면 직접 접근이 되는 것이다. 중간 포인터가 유실되어도 FAT을 통해 유실 지점 이후의 내용에 접근이 가능하기도 하다.

Free-Space Management

Directory Implementation

VFS and NFS

1. Virtual File System(VFS)

여러 종류의 파일 시스템 존재. 접근 시 시스템콜을 하는데, 시스템 종류별로 다른 시스템콜 인터페이스를 사용한다면 혼란스러울 것이다. -> 보통은 어떤 파일시스템이 사용되든지 상관없이 윗 계층에 VFS라는 인터페이스를 둔다.
서로 다양한 file system에 대해 동일한 시스템콜 인터페이스를 통해 접근할 수 있게 해주는 OS의 layer

2. Network File System(NFS)

분산 시스템에서는 네트워크를 통해 파일이 공유, NFS는 분산 환경에서의 대표적인 파일 공유 방법
자신의 로컬컴퓨터가 아닌 원격의 다른컴퓨터에 접근 시 지원
NFS client, NFS server 모두 필요

Page Cache and Buffer Cache

6.1. Page Cache
Virtual memory 의 관점
반쪽짜리 정보
6.2. Memory-Mapped I/O
원래는 파일 접근 시 open후 read/write 등 사용
메모리에 매핑하고 read/write등 시스템콜 대신, 메모리에 읽고 쓴다. 실제로는 파일에 데이터를 읽고쓰는 효과가 나도록
6.3. Buffer Cache
파일 시스템 관점
LRU, LFU등 사용 가능
6.4. Unified Buffer Cache
합쳐서 관리하는 운영체제들 있음.
버퍼 캐시도 페이지단위로 관리한다. 운영체제에서 물리적인 메모리를 관리하는 루틴에 페이지 캐시와 버퍼 캐시를 같이 관리한다.페이지 보통 4kb, 블록 512b -> 최근에는 두개가 합쳐지면서 버퍼캐시에도 페이지크기(4kb)로 블록들을 관리
swap area의 블록들은 빠르게 데이터를 내리고 올려야한다. -> 여러 개의 블록을 모아서 4kb단위로 올리거나 내리는게 기본. 더 크게 여러개의 페이지를 올리고 내리기도 한다.

profile
UE5 공부하는 블로그로 거처를 옮겼습니다!

0개의 댓글