본문 바로가기
운영체제

File Systems

by sepang 2022. 6. 21.

  이번 학기에 마지막 챕터인 file system이다. 깊게 들어가지는 않고 개념적인 것들 위주로 다루게 될 것 같다.

File System Layers

fig 1

  file system은 user-level SW와 device 사이에 위치하는데 리눅스 기준으로 Ext4같은 file system이 있다. 여러가지 file system이 있는데 general하게 사용되는 것도 있고 분산 시스템등 특정 기능에 특화된 file system도 존재한다. 그리고 이러한 file system에 접근하기 위해서는 POSIX API같은 공통된 API를 이용해야 한다.

  그리고 file system들은 file을 관리하는 방법에는 차이가 있지만 data를 읽거나 쓰는 방법은 동일하다. POSIX API 밑에는 generic block interface가 있어서 block 단위의 read/write 방식이 공통되게 정의된다. 그리고 그 밑에는 저번 시간에 다뤘던 장치별로 특화된 driver가 있다.

  대부분의 file system이 HDD를 기반으로 만들어졌기 때문에 최근 많이 사용되고 있는 SSD의 경우에는 SSD를 마치 HDD를 사용하는 것처럼 추상화 해주는 펌웨어를 사용한다. 이런 것을 이용하기 때문에 기존에 사용하던 file system을 SSD에서도 사용할 수 있다.

 

Storage: A Logical View

fig 2

  지난 글에서 LBA를 이용하여 storage가 마치 하나의 array로 보여지게 한다고 했다. 그리고 데이터를 읽거나 쓸 때는 다음과 같은 operation이 수행된다.

  • Read(start sector #, # of sectors, buffer addresses)
  • Write(start sector #, # of sectors, buffer addresses)

 

Abstraction for Storage

  그리고 이러한 Storage를 추상화하는 방법은 우리가 이미 잘 알다시피 file과 directory(folder)이다. storage 안에 data를 기록할 때 file이라는 형태로 기록을 한다. 그리고 각 file들은 inode라는 식별번호를 가진다. 이것을 통해 file system은 파일들을 식별하고 관리한다. 이러한 inode에는 파일의 생성시기, 위치 등에 대한 메타데이터가 담겨있다.

  directory는 사용자에게 파일을 구조적으로 정돈된 형태로 보여주기 위해 존재한다. 그렇기 때문에 directory는 <내부에 있는 file 이름, inode 번호>를 리스트 형태로 담고 있다. 그리고 diectroy 안에 다른 directory를 담을 수 있기 때문에 계층적인 구조를 가질 수 있다.

 

File System Components

  파일 시스템은 다음을 구성된다.

  • file contents(data): 사용자 입장에서는 중요한 data이지만, file system 입장에서는 일련의 byte일 뿐이다. 그렇기 때문에 file system은 file에 어떤 data가 들어있는지는 관심이 없다.
  • file attributes(metadata or inode): 이것은 각각의 file마다 존재하는데 file 크기, block의 위치, 작성자나 접근 권한 등에 대한 정보를 담고 있다.
  • file name: root에서 시작해 특정 file을 가리키는 경로다.

fig 3

  fig 3을 통해 정리해보면 file name을 통해 file이 있는 directory를 찾은 다음, 이 파일의 inode number를 찾는다. 그리고 inode의 metadata를 통해 실제로 file에 있는 data를 읽어올 수 있다.

File System: A Mapping Problem

fig 4

  fig 4 하단의 작은 칸 하나를 sector라고 하자. 각 파일에 해당하는 metadata가 있고, file의 data는 특정 sector 단위로 나뉠 것이다. a.out은 4개, sky.jpg는 3개의 sector가 필요한데 HDD 내부에는 그림처럼 각 data들이 들어갈 수 있다. 이런 상황에서 <filename, data, metadata> 정보를 이용하여 <a set of block>를 얻어내 하나의 파일을 얻어올 수 있다.

 

File System Design Issue

  file system을 디자인 할 때에도 성능, 안정성, 확장성 등을 고려해야한다. 이를 위해 고려해야할 사항들이 다음과 같다.

  • meatadata 안에 어떤 정보들을 넣어야 하는지
  • file name으로부터 metadata를 어떻게 지정할 수 있는지(ex. path name -> metadata)
  • data blocks은 어떻게 찾아야 하는지
  • metadata와 data blocks은 어떻게 관리되어야 하는지
  • 시스템이 중간에 다운됐을 때 file system을 어떻게 복구할지

 

File Attributes

  POSIX의 inode에는 기본적으로 다음과 같은 file attributes가 담긴다.

fig 5

 

Pathname Translation

  user application이 파일에 접근할 때에는 'open("/a/b/c", ...)'처럼 path를 사용한다. 저 말은 'root directory(/)를 읽어서 이 안에 a directory를 찾은 뒤 a의 위치를 얻어 a를 연 다음 b를 찾고 ...'의 과정을 수행하면서 c의 inode를 찾아서 file system에 전달하면 file system이 권한 등을 파악한다.

  이처럼 directory 경로를 읽어나가는 과정은 많은 시간이 소요된다. 이처럼 시간이 많이 걸리는 일이 반복될 때에는 항상 caching을 한다. file system에서도 예를 들어 b directory에 자주 접근한다면 해당 경로는 cache에 담아놓고 다시 접근될 때에는 빠르게 접근할 수 있다.

 

Ensuring Persistence

  file이라는건 결국 쓰여져야 나중에 전원이 꺼지더라도 data를 다시 읽을 수 있다. 그렇기 때문에 persistence를 보장하는 것이 중요하다. 그럼에도 실제로 LDST같은 instruction이 수행될 때의 data는 스토리지가 아닌 메모리에 저장이 되고 이것을 스토리지에 저장하기 위해서는 write()같은 시스템콜을 이용해야 특정 파일에 메모리의 data를 쓰기 시작한다.

  하지만 disk의 속도는 매우 느리기 때문에 OS는 write()를 했을 때 data를 바로 disk에 쓰지 않고 OS가 관리하는 메모리인 page cache에 쓴다. 굳이 이렇게 하는 이유는 performance를 개선하기 위해서이다. 예를 들어 반복되는 read나 write가 있을 때 계속해서 스토리지에 위치한 file에 접근하는 것보다 메모리에 있는 data를 가져오거나 쓰다가 한번에 buffer에 있는 data를 처리하는 것이 더 효율적이기 때문이다. fsync()같은 시스템콜을 이용하면 바로 스토리지로 flush할 수 도 있다.

 

Hard Links & Symbolic Links

$ ln old.txt new.txt

  위와 같은 'ln'명령어는 hard link를 만드는 명령어인데 완전히 새로운 파일을 만드는 것이 아니라 new.txt라는 파일을 만드는데 old.txt와 같은 inode를 가리키게 하는 것이다. 당연히 inode는 몇개의 hard link가 연결되어 있는지에 대한 정보를 담고 있다. 그렇기 때문에 만약 두 파일 중 하나가 지워지면 hard link의 수를 하나 줄이고 만약 이것이 0이 된다면 파일을 완전히 지워준다. 그리고 서로 다른 file system에 있는 파일들 끼리는 hard link를 생성할 수는 없다.

$ ln -s old.txt new.txt

  'ln -s'는 symbolic link를 만드는 명령어이다. 윈도우의 '바로가기'를 생각하면 이해가 쉬울 것이다. 이것은 동일한 inode를 가리키는 파일을 생성하는 것이 아니라 new.txt가 old.txt를 가리키는 역할만 한다.

 

File System Mounting

fig 6

  HDD를 장착하거나, usb를 꽂으면 드라이브가 검색된다. 이처럼 file system을 시스템에 장착하는 것을 file system mounting이라고 한다. 윈도우에서는 C:\, D:\, E:\, ...처럼 전체 directory에서 새로운 directory가 붙게 되고 이것을 시스템에서 사용할 수 있게된다. 리눅스 환경에서는 빈 directory를 만들어서 그곳에 mount를 하는데 이것을 mounting point라고 한다. 그곳에 새로운 드라이브를 접근할 수 있게 해준다.

 

Consistency Semantics

   파일의 consistency를 어떻게 맞춰주는지 알아보자.

  • UNIX semantics: 권한이 있다면 동일한 파일에 여러개의 프로세스가 접근할 수 있다. 만약 file에 새로운 정보를 쓰면 다른 유저들에게 즉각적을 변경사항이 보여진다.
  • AFS session sementics: 파일에 write를 했을 때 변경사항이 즉각적으로 보이지 않고 open 했던 파일을 닫았을 때 변경사항이 다른 사용자에게 보인다.
  • Immutable-shared-files sementics: 파일이 creater에 의해서 공유되면 이후 수정이 불가하다.

'운영체제' 카테고리의 다른 글

HDD: Hard Disk Drives  (0) 2022.06.21
Memory Management 4: Page Replacement  (0) 2022.06.15
Memory Management 3: Page Tables and TLBs  (0) 2022.05.27
Memory Management 2 - Paging  (0) 2022.05.19
Memory Management 1  (0) 2022.05.16

댓글