🎉 berenickt 블로그에 온 걸 환영합니다. 🎉
CS
운영체제
07-파일 시스템

1. 파일과 디렉터리

여러분이 당연하게 사용해왔던 파일디렉터리모두 운영체제 내부 파일 시스템이 관리하는 존재입니다. 파일과 디렉터리는 보조기억장치에 있는 데이터 덩어리일 뿐인데, 운영체제는 이를 어떻게 파일과 디렉터리로 관리하는 것일까요? 이번 절에서는 파일 시스템을 본격적으로 학습하기에 앞서 파일과 디렉터리에 대해 학습해 보겠습니다.


1.1 파일

여러분이 일상적으로 컴퓨터를 이용할 때는 파일 단위로 이용합니다.

파일(file)이란

  • HDD나 SSD와 같은 보조기억장치에 저장된 관련 정보의 집합을 의미
  • 달리 표현하면, 파일은 의미있고 관련 있는 정보를 모은 논리적 단위를 의미

그렇다면 파일을 이루는 정보에는 어떤 것들이 있을까요? 모든 파일에는

  • 이름과 파일을 실행하기 위한 정보, 그리고 파일 관련 부가 정보가 있습니다.
  • 부가 정보속성(attribute) 또는 메타데이터(metadata)라고 부릅니다.

MySelf-Architec-Oper_15_1

윈도우 운영체제를 사용한다면, 파일 속성을 한 번쯤 접해 본 경험이 있을 것입니다.

  • 임의의 파일에서 마우스 오른쪽 버튼을 클릭한 후 [속성]을 선택해 보세요.
  • 위 그림과 같은 대화상자가 나타납니다.
  • 파일 형식, 위치, 크기 등 파일과 관련된 다양한 정보가 나타나지요?
  • 이러한 정보가 바로 파일 속성입니다.

1.2.1 파일 속성과 유형

운영체제마다 유지하는 파일 속성은 조금씩 차이가 있지만, 대표적인 속성의 종류는 다음과 같습니다. 운영체제, 그 중에서 파일 시스템은 파일별로 다음과 같은 속성을 유지하고 관리합니다.

속성 이름의미
유형운영체제가 인지하는 파일의 종류를 나타낸다.
크기파일의 현재 크기와 허용 가능한 최대 크기를 나타낸다.
보호어떤 사용자가 해당 파일을 읽고, 쓰고, 실행할 수 있는지를 나타낸다.
생성 날짜파일이 생성된 날짜를 나타낸다.
마지막 접근 날짜파일에 마지막으로 접근한 날짜를 나타낸다.
마지막 수정 날짜파일이 마지막으로 수정된 날짜를 나타낸다.
생성자파일을 생성한 사용자를 나타낸다.
소유자파일을 소유한 사용자를 나타낸다.
위치파일의 보조기억장치상의 현재 위치를 나타낸다.

1.2.2 파일 유형(확장자)

파일 속성 중 파일 유형운영체제가 인식하는 파일 종류를 나타냅니다. 같은 이름의 파일일지라도 텍스트 파일, 실행 파일, 음악 파일 등 유형이 다르면 실행 양상도 달라집니다. 그래서 파일을 실행할 운영체제에 파일 유형을 알려주어야 합니다.

파일 유형을 알리기 위해 가장 흔히 사용하는 방식은 파일 이름 뒤에 붙는 확장자(extension)를 이용하는 것입니다. 확장자는 파일 종류가 무엇인지 운영체제에 알려주는 힌트와도 같습니다.

e.g. myfile.oo라는 확장자를 통해, 운영체제에 목적 코드를 담고 있는 목적 파일임을 알려주는 셈이고, myfile.exeexe라는 확장자를 통해, 운영체제에 실행 파일임을 알려주는 셈입니다.

파일 유형대표적인 확장자
실행 파일없는 경우, exe, com, bin
목적 파일obj, o
소스 코드 파일c, cpp, cc, java, asm, py
워드 프로세서 파일xml, rtf, doc, docx
라이브러리 파일lib, a, so, dll
멀티미디어 파일mpeg, mov, mp3, mp4, avi
백업/보관 파일rar, zip, tar

1.2.3 파일 연산을 위한 시스템 호출

파일을 다루는 모든 작업은 운영체제에 의해 이뤄집니다. 어떤 응용 프로그램도 임의로 파일을 조작할 수 없으며, 파일을 다루려면 운영체제에 부탁해야 합니다. 이를 위해 운영체제는 다음과 같은 파일 연산을 위한 시스템 호출을 제공합니다.

  1. 파일 생성
  2. 파일 삭제
  3. 파일 열기
  4. 파일 닫기
  5. 파일 읽기
  6. 파일 쓰기 …

1.2 디렉터리, 폴더

파일들을 일목요연하게 관리하기 위해, 디렉터리(directory)를 이용할 수 있습니다. 윈도우 운영체제에서는 디렉터리폴더(folder)라고 부릅니다.

MySelf-Architec-Oper_15_2

옛날 운영체제에서는 하나의 디렉터리만 존재했습니다.

  • 모든 파일이 하나의 디렉터리 아래에 있었죠.
  • 이와 같은 디렉터리 구조를 1단계 디렉터리(single-level directory)라고 부릅니다.

MySelf-Architec-Oper_15_3

하지만 실제로 이렇게 사용하는 컴퓨터는 거의 없죠.

  • 컴퓨터 용량이 커지다 보니 저장할 수 있는 파일도 많아지고,
  • 1단계 디렉터리로는 많은 파일을 관리하기가 어렵기 때문에
  • 위 그림과 같이 여러 계층을 가진 트리 구조 디렉터리(tree-structured directory)가 생겨나게 되었습니다.
  • 트리 구조 디렉터리는 최상위 디렉터리가 있고, 그 아래에 여러 서브 디렉터리(자식 디렉터리)가 있을 수 있습니다.
  • 서브 디렉터리도 또 다른 서브 디렉터리를 가질 수 있지요.
  • 최상위 디렉터리는 흔히 루트 디렉터리(root directory)라고 부르고 슬래시(/)로 표현합니다.
  • cf. 윈도우 운영체제에서 최상위 디렉터리는 흔히 C:\로 표현합니다.

그러다 보니 자연스레 생긴 개념이 바로 경로(path)입니다. 경로는 디렉터리를 이용파일 위치, 나아가 파일 이름을 특정짓는 정보입니다.


1.2.1 절대 경로와 상대 경로

(1) 절대 경로

MySelf-Architec-Oper_15_3

많은 사람이 경험을 통해 알고 있듯, 같은 디렉터리에는 동일한 이름의 파일이 존재할 수 없지만, 서로 다른 디렉터리에는 동일한 이름의 파일이 존재할 수 있습니다

e.g. 위 그림을 다시 한 번 보면,

  • a.sh 라는 파일은 minchul 디렉터리에도 있고, etc 디렉터리에도 있습니다.
  • 이는 루트 디렉터리부터 파일까지 경로가 다르기 때문에, 동일한 이름임에도 공존할 수 있는 것입니다.
  • 그래서 모든 파일루트 디렉터리에서 자기 자신까지 이르는 고유한 경로를 가지고 있고,
  • 이러한 경로를 절대 경로(absolute path)라고 부릅니다.

e.g. 위 그림 속 왼쪽의 a.sh는 루트 디렉터리 아래, home 디렉터리 아래, minchul 디렉터리 아래에 있지요?

  • 따라서 a.sh의 절대 경로
    • **‘루트 디렉터리 아래, home 디렉터리 아래, minchul 디렉터리 아래에 있는 a.sh’**라고 표현

cf. 유닉스, 리눅스, macOS 등의 운영체제에서 슬래시 기호(/)

  • 루트 디렉터리를 표시할 뿐만 아니라, 디렉터리와 디렉터리 사이의 구분자로도 사용합니다.
  • 디렉터리와 디렉터리 사이의 구분자로 슬래시를 사용한다면,
  • a.sh의 절대 경로/home/minchul/a.sh로 표현할 수 있습니다.

cf. 윈도우에서는 디렉터리 구분자로 \(W, 원화표시)를 사용합니다.

  • 윈도우 운영체제에서 a.sh의 절대 경로C:\home\ minchul\a.sh로 표현됩니다.

(2) 상대 경로

MySelf-Architec-Oper_15_3

경로를 나타내는 또 다른 대중적인 방식으로 상대 경로(relative path)가 있습니다.

  • 절대 경로루트 디렉터리부터 시작하는 경로라면,
  • 상대 경로현재 디렉터리부터 시작하는 경로입니다.
  • e.g. 트리 구조 디렉터리 그림에서 현재 디렉터리 경로/home이라면,
    • d.jpg 파일의 상대 경로guest/d.jpg가 됩니다.

1.2.2 디렉터리 연산을 위한 시스템 호출

운영체제가 파일 연산을 위한 시스템 호출을 제공하는 것처럼 운영체제는 디렉터리 연산을 위한 시스템 호출도 제공합니다. 대표적인 종류는 다음과 같습니다.

  1. 디렉터리 생성
  2. 디렉터리 삭제
  3. 디렉터리 열기
  4. 디렉터리 닫기
  5. 디렉터리 읽기 등…

1.2.3 디렉터리 엔트리

여기까지 읽은 여러분은 아마 파일과 디렉터리는 엄연히 다른 별개의 존재라고 생각할 겁니다. 이쯤에서 중요한 이야기를 하나 하자면, 많은 운영체제에서는 디렉터리를 그저 ‘특별한 형태의 파일’로 간주합니다. 즉, 디렉터리도 파일입니다. 단지 포함된 정보가 조금 특별할 뿐이지요

  • 파일의 내부에는 해당 파일과 관련된 정보를 담고 있다면,
  • 디렉터리의 내부에는 해당 디렉터리에 담겨 있는 대상과 관련된 정보를 담고 있습니다.
    • 이 정보는 보통 테이블(표) 형태로 구성
    • 즉, 디렉터리보조기억장치에 테이블 형태의 정보로 저장됩니다.

MySelf-Architec-Oper_15_4

보조기억 장치에서 디렉토리는 위 그림과 같은 표의 형태로 저장됩니다.

  • 위 표의 각각의 행들을 디렉터리 엔트리라고 부릅니다.
  • cf. 각각의 엔트리(행)에 담기는 정보는
    • 파일 시스템마다 차이가 있으며,
    • 파일 시스템별 디렉터리 엔트리는 다음 절에서 학습할 예정입니다.
    • 여기서는 디렉터리 엔트리가 공통으로 포함하는 정보에 대해 학습합니다.
  • 각각의 엔트리(행)에 담기는 정보는 다음과 같습니다.
    • 디렉터리에 포함된 대상의 이름
    • 그 대상이 보조기억장치 내에 저장된 위치를 유추할 수 있는 정보
  • 다시 말해, 디렉터리 엔트리만 봐도 해당 디렉터리에 무엇이 담겨 있는지,
    • 그리고 그것들은 보조기억장치의 어디에 있는지를 직간접적으로 알 수 있습니다.

MySelf-Architec-Oper_15_5

파일 시스템에 따라 디렉터리 엔트리에 다음과 같이 파일 속성을 명시하는 경우도 있습니다.


e.g. 다음 그림과 같은 구조의 디렉터리와 파일이 있다고 가정하면,

MySelf-Architec-Oper_15_6

home 디렉터리에는 minchul 디렉터리guest 디렉터리가 있지요?

MySelf-Architec-Oper_15_7

따라서 home 디렉터리는 대략 위 그림과 같이 구성됩니다. 여기서 ..상위 디렉터리, .현재 디렉터리를 가리킵니다.


MySelf-Architec-Oper_15_8

디렉터리 엔트리를 통해 보조기억장치에 저장된 위치를 알 수 있기 때문에

  • home 디렉터리에서 minchul 디렉터리가 저장된 곳을 알 수 있고,
    • 따라서 그곳으로 이동할 수도 있습니다.
  • 마찬가지로 minchul 디렉터리 엔트리에는
    • 디렉터리에 속한 파일들의 이름(a.sh, b.c, c.tar)
    • 이들의 위치를 알 수 있는 정보 등이 포함되어 있기 때문에,
    • 이 파일들보조기억장치 내에 저장된 위치를 알 수 있고, 실행할 수 있는 것입니다.

1.3 상대 경로를 나타내는 또 다른 방법

대부분의 운영체제는 현재 작업 디렉터리마침표(.)로 나타내고, 현재 작업 디렉터리의 상위 디렉터리(부모 디렉터리)를 마침표 두 번(..)으로 나타냅니다. 그리고 흔히 이 기호를 이용해 상대 경로를 표현합니다.

MySelf-Architec-Oper_15_9


1.4 cd 명령어

e.g. 현재 작업 디렉터리가 /home인 경우 파일 b.c의 상대 경로./minchul/b.c로 나타낼 수 있습니다. 마찬가지로 현재 작업 디렉터리가 /bin인 경우 파일 e./e로 나타낼 수 있습니다

MySelf-Architec-Oper_15_10

e.g. 윈도우, 리눅스, 유닉스, macOS 등 대부분의 운영체제에서는 cd(change directory)명령을 통해, 현재 작업 디렉터리를 이동할 수 있습니다.

MySelf-Architec-Oper_15_11

e.g. 가령 윈도우 루트 디렉터리(C:) 아래에 test라는 디렉터리가 있다고 가정

  • 루트 디렉터리 아래에 있는 test 디렉터리로 현재 작업 디렉터리를 이동하려면 cd C:\test를 입력하면 됩니다.
  • 현재 작업 디렉터리가 C:\인 경우,
    • 상대 경로인 cd test 또는 cd .\test를 입력해도 test 디렉터리로 이동할 수 있습니다.

MySelf-Architec-Oper_15_12

이번에는 cd ..을 입력하면, 부모 디렉터리인 루트 디렉터리로 이동합니다,

💡 루트 디렉터리에서 cd ..

참고로 루트 디렉터리는 부모 디렉터리가 없기 때문에 루트 디렉터리의 ..자기 자신을 의미합니다. 그래서 루트 디렉터리에서 cd ..을 입력해도, 현재 작업 디렉터리는 변하지 않습니다.


2. 파일 시스템

MySelf-Architec-Oper_15_13

  • 파일 시스템파일과 디렉터리를 보조기억장치에 할당하고 접근하는 방법
  • 파일 시스템이 파일과 디렉터리를 보조기억장치에 어떻게 할당하고,
    • 접근하는지에 관한 이론적인 내용을 먼저 학습하고,
  • 대표적인 파일 시스템의 종류(FAT 파일 시스템, 유닉스 파일 시스템)에 대해 알아보겠습니다.

2.1 파티셔닝과 포매팅

MySelf-Architec-Oper_15_14

이제 막 공장에서 생산되어 한 번도 사용된 적이 없는 새 하드 디스크 또는 SSD가 있다고 가정해 봅시다.

  • 여러분은 이 보조기억장치에 곧바로 파일을 생성하거나 저장할 수 없습니다.
  • 왜냐하면 보조기억장치를 사용하려면,
    • 파티션을 나누는 작업(파티셔닝)포맷 작업(포매팅)거쳐야 하기 때문입니다.
  • 만약에 파티셔닝과 포매팅을 해주지 않았다면, 위 그림과 같은 그림이 뜰 것입니다.

2.1.1 파티셔닝(partitioning)

  • 파티셔닝 : 저장 장치의 논리적인 영역을 구획하는 작업을 의미

MySelf-Architec-Oper_15_15

e.g. 엄청나게 커다란 서랍이 있다고 생각해보세요. 이 커다란 서랍 안에 마구잡이로 물건들을 보관하면, 필요한 물건을 정돈하는 게 쉽지 않습니다.

MySelf-Architec-Oper_15_16

하지만 서랍 안에 위 그림과 같이 칸막이를 설치하여, 영역을 나누면 물건들을 정리하기가 조금 더 수월합니다.

  • 이렇게 칸막이로 영역을 나누는 작업이 바로 파티셔닝입니다.
  • HDD나 SSD처럼 용량이 큰 저장 장치를 하나 이상의 논리적인 단위로 구획하는 것이지요.
  • 그리고 이렇게 파티셔닝 작업을 통해 나누어진 영역 하나하나파티션(partition)이라고 합니다.

MySelf-Architec-Oper_15_17

여러분 컴퓨터의 파티션을 확인해 볼까요? 윈도우 작업표시줄에 있 는 검색창에 ‘하드 디스크 파티션 만들기 및 포맷’을 입력하면 위 그림과 같은 결과가 나옵니다.


MySelf-Architec-Oper_15_18

이곳에 들어가면 여러분 컴퓨터 내의 보조기억장치가 어떻게 파티셔닝되어 운영되는지를 한눈에 볼 수 있습니다.


2.1.2 포매팅(formatting)

  • 포맷하는 작업, 즉 포매팅은 저장 장치를 완전히 삭제하는 것으로 알고 있는 사람들이 많지만,
    • 사실 이는 완벽하게 정확한 표현이라고 보기는 어렵습니다.
  • 포매팅
    • 파일 시스템을 설정하여, 어떤 방식으로 파일을 저장하고 관리할 것인지를 결정하고,
    • 새로운 데이터를 쓸 준비를 하는 작업을 의미
    • 즉, 어떤 종류의 파일 시스템을 사용할지는 바로 이때 결정납니다.

💡 포매팅의 종류

포매팅의 종류에는 엄밀히 말하면 저수준 포매팅과 논리적 포매팅이 있습니다.

  • 저수준 포매팅 : 저장 장치를 생성할 당시 공장에서 수행되는 물리적인 포매팅이고,
  • 논리적 포매팅 : 파일 시스템을 생성하는 포매팅입니다.
    • 이 책에서 설명하는 포매팅은 리적 포매팅입니다.

MySelf-Architec-Oper_15_19

가령 USB 메모리를 포매팅할 때, 위 그림과 같은 화면을 볼 수 있습니다. 파일 시스템을 선택하는 항목이 보이지요? 포매팅할 때, 파일 시스템이 결정된다는 것을 알 수 있습니다.


MySelf-Architec-Oper_15_20

파일 시스템에는 여러 종류가 있고, 파티션마다 다른 파일 시스템을 설정할 수도 있습니다.

  • 포매팅까지 완료하여 파일 시스템을 설정했다면, 이제 여러분은 파일과 디렉터리를 생성할 수 있습니다.
  • 파티셔닝포매팅동시에 진행되는 경우가 많고,
    • 이미 포매팅까지 완료되어 판매되는 경우도 많기 때문에 개념에 익숙하지 않을 수 있지만,
    • 저장 장치를 관리하거나 운영체제를 설치하는 과정에서
    • 파티셔닝과 포매팅은 자주 접하게 될 키워드이니 기억하는 것이 좋습니다.

2.2 파일 할당 방법

하드 디스크의 포매팅까지 끝냈다고 가정해 봅시다. 이제 이 저장 장치에 여러분이 사용할 파일을 저장해 보겠습니다.

  • 운영체제파일디렉터리블록(block) 단위로 읽고 씁니다.
  • 즉, 하나의 파일이 보조기억장치에 저장될 때는, 하나 이상의 블록에 걸쳐 저장됩니다.
  • cf. 하드 디스크의 가장 작은 저장 단위는 섹터이지만,
    • 운영체제는 하나 이상의 섹터블록이라는 단위로 묶은 뒤, 블록 단위로 파일과 디렉터리를 관리합니다.
    • 파일 시스템이 모든 섹터를 관리하기에는 개수가 너무 많고 크기도 작기 때문입니다.

MySelf-Architec-Oper_15_21

e.g. 위 그림과 같이 하드 디스크 내에 여러 블록이 있다고 해봅시다.

  • 블록 안에 적힌 번호블록의 위치를 식별하는 주소입니다.
  • 이 블록여러분이 사용하는 파일을 할당해야 합니다.
    • 크기가 작은 파일적은 수의 블록에 걸쳐 저장될 것이고,
    • 크기가 큰 파일여러 블록에 걸쳐 저장됩니다.

이런 상황에서 파일을 보조기억장치에 할당하는 방법에는 크게 2가지가 있습니다.

  1. 연속 할당(contiguous allocation)
  2. 불연속 할당
    • 연결 할당(linked allocation)
    • 색인 할당(indexed allocation)

cf. 연속 할당과 불연속 할당 중 오늘날까지 사용되는 방식은 불연속 할당입니다


2.2.1 연속 할당

MySelf-Architec-Oper_15_22

  • 가장 단순한 방식으로 이름 그대로 보조기억장치 내 연속적인 블록에 파일을 할당하는 방식
  • e.g. 블록을 3개, 2개, 5개 차지하는 정도의 크기를 가진 파일 a, b, c가 있을 때,
    • 이 파일들은 위 그림과 같이 연속적으로 할당됩니다.

MySelf-Architec-Oper_15_23

연속으로 할당된 파일에 접근하기 위해서는

  • 파일의 첫 번째 블록 주소블록 단위의 길이만 알면 됩니다.
  • 그렇기에 연속 할당을 사용하는 파일 시스템에서는 위 그림과 같이,
    • 디렉터리 엔트리에 파일 이름첫 번째 블록 주소블록 단위의 길이를 명시합니다

MySelf-Architec-Oper_15_24

연속 할당 방식은

  • 파일을 그저 연속적으로 저장하는 방식이기에 구현이 단순하다는 장점이 있지만,
  • 외부 단편화를 야기한다는 치명적인 문제가 있습니다.
  • 위 그림을 보면, 하드 디스크의 블록들을 일렬로 쭉 나열한 후 파일들을 연속 할당되었습니다.

MySelf-Architec-Oper_15_25

여기서 파일 D와 F삭제되면,

  • 위 그림과 같이 할당할 수 있는 블록은 총 11개가 남지만,
  • 불행히도 크기가 블록 7개 이상을 사용하는 파일은 할당할 수 없습니다.
  • 이것이 연속 할당에서의 외부 단편화입니다.
  • 연속 할당의 문제를 해결할 수 있는 방식이 불연속 할당의 연결 할당입니다.

2.2.2 연결 할당 (불연속)

  • 각 블록 일부에 다음 블록의 주소를 저장하여, 각 블록이 다음 블록을 가리키는 형태로 할당하는 방식
  • 즉, 파일을 이루는 데이터를 연결 리스트로 관리합니다.
  • 불연속 할당의 일종이기에 파일이 여러 블록에 흩어져 저장되어도 무방합니다.
  • cf. **‘어떤 블록의 주소를 저장한다’**는 말은 **‘그 블록을 가리킨다’**는 말과 같습니다.
    • 어떤 블록의 주소를 알면, 해당 블록에 얼마든지 접근할 수 있기 때문입니다.
    • 이는 C언어의 포인터와 같은 개념입니다.

MySelf-Architec-Oper_15_26

위 그림을 보면, 4개의 블록으로 구성된 a라는 파일이 있고, 10번, 5번, 13번, 2번 블록저장되었다고 가정

  • 연결 할당 방식에서는 10번 블록 끝에 5번 블록 주소를,
  • 5번 블록 끝에 13번 블록 주소
  • 13번 블록 끝에 2번 블록 주소를 기록합니다.
  • 마지막 블록(2번 블록)에는 다음 블록이 없다는 특별한 표시자를 기록합니다.
    • 위 예시에서는 -1을 이용했습니다.

MySelf-Architec-Oper_15_27

즉, 10번 블록5번 블록을, 5번 블록13번 블록을, 13번 블록2번 블록을 가리키고 있는 셈입니다.

  • 연결 할당을 사용하는 파일 시스템에서는 디렉터리 엔트리에 연속 할당과 마찬가지로,
    • 파일 이름과 함께 첫 번째 블록 주소블록 단위의 길이를 명시합니다.
  • 디렉터리 엔트리만 봐도, 어떤 파일이 어디에 저장되어 있는지 알 수 있겠지요?
  • cf. 디렉터리 엔트리첫 번째 블록 주소마지막 블록 주소를 기록할 수도 있습니다.

(1) 단점

연결 할당외부 단편화 문제를 해결하지만 이 또한 단점이 있습니다.

  1. 반드시 첫 번째 블록부터 하나씩 차례대로 읽어야 합니다.
    • 다시말해, 파일 내 임의의 위치에 접근하는 속도, 즉 임의 접근(random access) 속도가 매우 느립니다.
    • e.g. 위 그림에서 파일 a의 중간부터 읽고 싶어도, 반드시 맨 처음(10번 블록)부터 시작해야 합니다.
      • 위 그림에서는 4개의 블록만을 사용하는 작은 파일을 예로 들었으나,
      • 실제로는 크기가 큰 파일들도 얼마든지 많습니다. 그러면 더 느리겠죠?
    • 즉, 파일의 i번째 블록접근하기 위해서는,
      • 반드시 첫 번째 블록부터 i번째 블록까지 일일이 순서대로 접근해야 함
      • 이는 성능 면에서 상당히 비효율적
  2. 하드웨어 고장이나 오류 발생 시 해당 블록 이후 블록은 접근할 수 없습니다.
    • 하나의 블록 안에 파일 데이터와 다음 블록 주소가 모두 포함되어 있다 보니,
      • 하드웨어 고장이나 오류로 인해 파일을 이루는 블록에
      • 하나라도 문제가 발생하면, 그 블록 이후의 블록에 접근할 수 없습니다.
    • HDD는 굉장히 정교하고 고장에 예민한 장치입니다.
      • HDD 헤드는 플래터 위에 대단히 미세한 간격으로 떨어져 있는 만큼,
      • 충격을 받으면 자칫 헤드가 플래터에 충돌하여 데이터를 손상시킬 수 있습니다.

그래서 오늘날에는 위 내용을 그대로 구현하기보다는 이를 조금 변형하여 사용합니다. 연결 할당을 변형한 대표적인 파일 시스템이 오늘날까지도 많이 사용하는 FAT 파일 시스템입니다. FAT가 무엇이며, 어떻게 위 문제를 해결하는지는 색인 할당을 살펴본 뒤에 바로 설명하겠습니다.


2.2.3 색인 할당 (불연속)

  • 파일의 모든 블록 주소를 색인 블록이라는 하나의 블록에 모아 관리하는 방식
  • 파일 내 임의의 위치에 접근하기 용이

MySelf-Architec-Oper_15_28

e.g. 파일 a의 색인 블록4번 블록이고, 파일 a의 데이터는 7번, 13번, 11번 블록에 저장되어 있다고 가정

  • 4번 블록 안에는 파일 a를 구성하는 블록들의 주소인 7, 13, 11이 적혀 있습니다.
  • 파일 a순차적으로 접근하고 싶다면, 색인 블록에 저장된 주소에 차례대로 접근하면 됩니다.

MySelf-Architec-Oper_15_29

색인 할당은 연결 할당과는 달리 파일 내 임의의 위치에 접근하기 쉽습니다.

  • 파일의 i번째 데이터 블록에 접근하고 싶다면,
    • 색인 블록의 i번째 항목이 가리키는 블록에 접근하면 되기 때문입니다.
  • 색인 블록 안에 파일을 구성하는 데이터 블록 주소가 있으므로,
    • 색인 블록만 알면 해당 파일 데이터에 접근할 수 있습니다.
  • 그렇기에 색인 할당을 사용하는 파일 시스템에서는
    • 디렉터리 엔트리파일 이름색인 블록 주소를 명시합니다.

색인 할당을 기반으로 만든 파일 시스템유닉스 파일 시스템입니다. 유닉스 파일 시스템에 대해서는 FAT 파일 시스템을 살펴본 뒤 설명하겠습니다.


2.3 파일 시스템 살펴보기

이제 실제 파일 시스템의 모습을 살펴봅시다. 다양한 파일 시스템이 있지만 여러 전공서에서 공통으로 소개하는 파일 시스템은 크게 2가지입니다.

  • USB 메모리, SD 카드 등의 저용량 저장 장치에서 사용되는 FAT 파일 시스템
  • 유닉스 계열 운영체제에서 사용되는 유닉스 파일 시스템

2.3.1 FAT 파일 시스템

  • 연결 할당의 단점을 보완연결 할당 기반 파일 시스템
  • 연결 할당 방식의 단점의 근본적인 원인블록 안에 다음 블록의 주소를 저장했기 때문

MySelf-Architec-Oper_15_30

위 그림은 앞에서 설명한 연결 할당을 단순화한 그림입니다. e.g. 파일 a4개의 블록으로 이루어져 있고, a를 구성하는 데이터4, 8, 3, 5번 블록에 걸쳐 저장되었다 가정하면,

  • 4번 블록8번 블록을,
  • 8번 블록3번 블록을,
  • 3번 블록5번 블록을 가리키고 있습니다.
  • 이런 방식임의 접근의 성능이 좋지 못하고,
  • 이 블록들 중 하나라도 문제가 발생하면, 그 이후의 블록에는 접근할 수 없습니다.

MySelf-Architec-Oper_15_31

하지만 각 블록에 포함된 다음 블록의 주소들을 한데 모아 테이블 형태로 관리하면,

  • 앞서 언급한 단점들을 상당 부분 해소할 수 있습니다.
  • 이러한 테이블을 파일 할당 테이블(FAT; File Allocation Table)이라고 부릅니다.

위 FAT을 보면,

  • 파일의 첫 번째 블록 주소(4번 블록)만 알면, 파일의 데이터가 담긴 모든 블록에 접근할 수 있겠지요?
  • 그래서 디렉터리 엔트리에는 파일 이름파일의 첫 번째 블록 주소가 명시됩니다.
  • cf. 더 이상 다음 블록이 없으면 특별한 표시자를 표기합니다
    • 위 그림에서는 -1로 표기했습니다.
    • 빈 공간은 아직 할당되지 않았음을 의미합니다.

이렇게 FAT를 이용하는 파일 시스템이 바로 FAT 파일 시스템입니다.

  • 옛날 마이크로소프트의 운영 체제인 MS-DOS에서 사용되었고,
  • 최근까지 USB 메모리, SD 카드와 같은 저용량 저장 장치용 파일 시스템으로 많이 이용되고 있습니다.
  • FAT 파일 시스템은 버전에 따라 FAT12, FAT16, FAT32가 있으며,
    • FAT 뒤에 오는 숫자는 블록을 표현하는 비트 수를 의미합니다.
  • cf. 참고로 윈도우에서는 블록이라는 용어 대신 클러스터라는 용어를 사용합니다.
    • 즉, FAT 뒤에 오는 숫자클러스터를 표현하기 위한 비트입니다.

MySelf-Architec-Oper_15_32

FAT 파일 시스템에서 FAT는 파티션의 앞부분에 만들어집니다. 위 그림은 FAT(FAT12) 파일 시스템을 사용하는 파티션을 간략화한 도식도입니다.

  • 하드 디스크의 한 파티션을 FAT 파일 시스템으로 포맷하면,
    • 해당 파티션이 위와 같이 구성된다고 이해하면 됩니다.
  • FAT 영역에 FAT가 저장되고,
    • 뒤이어 루트 디렉터리가 저장되는 영역이 있으며,
    • 그 뒤에 서브 디렉터리와 파일들을 위한 영역이 있습니다.

FAT는 하드 디스크 파티션의 시작 부분에 있지만, 실행하는 도중 FAT가 메모리에 캐시될 수 있습니다. FAT가 메모리에 적재된 채 실행되면 기존 연결 할당보다 다음 블록을 찾는 속도가 매우 빨라지고, 결과적으로 앞서 설명한 연결 할당 방식보다 임의 접근에도 유리해집니다. 즉, FAT가 메모리 에 적재된 채 실행되면 임의 접근의 성능이 개선됩니다.


이번에는 FAT 파일 시스템의 디렉터리 엔트리를 조금 더 자세히 살펴봅시다.

  • 앞서 FAT 파일 시스 템의 디렉터리 엔트리에는 파일 이름과 더불어 파일의 첫 번째 블록 주소가 명시된다고 했습니다.
  • 이외에도 FAT 파일 시스템의 디렉터리 엔트리에는 파일 속성과 관련한 다양한 정보들이 있습니다.

MySelf-Architec-Oper_15_33

다음 그림을 보면, FAT 파일 시스템에서의 디렉터리들은 위과 같은 형식으로 블록에 저장된다고 보면 됩니다.

💡 참고

속성(File Attribute) 항목은 해당 파일이 읽기 전용 파일인지, 숨김 파일인지, 시스템 파일인지, 일반 파일인지, 디렉터리인지 등을 식별하기 위한 항목입니다.

MySelf-Architec-Oper_15_34

자, 그렇다면 마지막으로 위와 같은 디렉터리 구조를 이루는 FAT 파일 시스템에서 /home/ minchul/a.sh 파일을 읽는 과정을 살펴보겠습니다.

MySelf-Architec-Oper_15_35

위 디렉터리 구조는 파티션 내에 위 그림과 같이 저장된다고 가정해 보겠습니다.

  • (cf. 이해를 돕기 위해 간략화한 그림입니다).
  • FAT 영역에 FAT가 있고,
  • 루트 디렉터리 영역에 루트 디렉터리가 있으며,
  • 데이터 영역에 기타 서브 디렉터리와 파일들이 있습니다.
  • 디렉터리는 하나의 블록에 저장된다고 가정하며,
    • FAT 상에서 더 이상의 블록이 없음을 표시하기 위한 표시자로 -1을 사용했습니다.

이제 /home/minchul/a.sh에 접근해 봅시다.

  • a.sh루트 디렉터리 아래, home 디렉터리 아래, minchul 디렉터리 아래에 있습니다.
  • 따라서 a.sh에 접근하려면, 루트 디렉터리부터 봐야 합니다.

MySelf-Architec-Oper_15_36

(1) 루트 디렉터리를 보면, home 디렉터리는 몇 번 블록에 있는지 살펴봅시다. home 디렉터리3번 블록에 있습니다.


MySelf-Architec-Oper_15_37

(2) 3번 블록을 읽어 home 디렉터리 내용을 살펴봅니다. 이번에는 minchul 디렉터리가 몇 번 블록에 있는지 살펴봅시다. minchul 디렉터리15번 블록에 있습니다.


MySelf-Architec-Oper_15_38

(3) 15번 블록을 읽어 minchul 디렉터리 내용을 살펴봅니다. 접근하려는 a.sh 파일의 첫 번째 블록 주소9번 블록이라는 것을 알 수 있습니다.


MySelf-Architec-Oper_15_39

(4) FAT를 보면 a.sh 파일9번, 8번, 11번, 13번 블록 순서로 저장되어 있다는 것을 알 수 있 습니다. 따라서 파일 시스템은 /home/minchul/a.sh을 읽기 위해, 9번, 8번, 11번, 13번 블록에 접근합니다.


2.3.2 유닉스 파일 시스템

  • 색인 할당 기반의 유닉스 파일 시스템
  • 색인 할당은 색인 블록을 기반으로 파일의 데이터 블록들을 찾는 방식
  • 유닉스 파일 시스템에서는 이 색인 블록i-node라고 부릅니다.
    • i-node에는 파일 속성 정보와 15개의 블록 주소가 저장될 수 있습니다.

MySelf-Architec-Oper_15_40

앞서 FAT 파일 시스템에서는 파일 속성 정보가 디렉터리 엔트리에 표현되었지요? 유닉스 파일 시스템에서 파일 속성 정보i-node에 표현됩니다.


MySelf-Architec-Oper_15_41

유닉스 파일 시스템에는 파일마다 이러한 i-node가 있고, i-node마다 번호가 부여되어 있습니다.

  • i-node들은 위와 같이 파티션 내 특정 영역에 모여 있습니다.
  • i-node 영역에 i-node들이 있고, 데이터 영역에 디렉터리와 파일들이 있습니다.

MySelf-Architec-Oper_15_42

그런데 여기서 1가지 문제가 있습니다. i-node의 크기는 유한합니다.

  • i-node 하나기본적으로 15개의 블록 주소를 저장할 수 있기 때문에
  • i-node 하나는 15개의 블록을 차지하는 파일까지 가리킬 수 있습니다.
  • 하지만 블록을 20개, 30개, 그 이상 차지하는 큰 파일도 있겠죠?
  • 이 경우 i-node 하나만으로는 파일의 데이터 블록을 모두 가리킬 수 없습니다.

(1) 문제 해결과정

유닉스 파일 시스템은 이러한 문제를 다음과 같이 해결합니다. 글을 먼저 읽고, 그림을 보면서 이해하길 권합니다.

MySelf-Architec-Oper_15_43

첫째, 블록 주소 중 12개에는 직접 블록 주소를 저장합니다.

  • i-node가 가리킬 수 있는 15개의 블록 주소
    • 처음 12개에는 파일 데이터가 저장된 블록 주소가 직접적으로 명시됩니다.
    • 파일 데이터가 저장된 블록직접 블록(direct block)이라고 합니다.
    • 즉, i-node의 12개 주소직접 블록 주소를 저장합니다.
  • 이것만으로 파일 데이터 블록을 모두 가리킬 수 있다면, 여기서 추가적인 작업이 필요하지 않습니다.

MySelf-Architec-Oper_15_44

둘째, ‘첫째’ 내용으로 충분하지 않다면, 13번째 주소에 단일 간접 블록 주소를 저장합니다.

  • 12개의 블록 주소로 파일의 모든 블록을 가리킬 수 없다면, i-node의 13번째 블록 주소를 이용합니다.
  • 13번째 블록 주소단일 간접 블록의 주소를 저장합니다.
  • 단일 간접 블록(single indirect block)이란?
    • 파일 데이터가 저장된 블록이 아닌 파일 데이터를 저장한 블록 주소가 저장된 블록을 의미합니다.
    • 이는 말보다 위 그림으로 이해하기 바랍니다.

MySelf-Architec-Oper_15_45

셋째, ‘둘째’ 내용으로 충분하지 않다면, 14번째 주소에 이중 간접 블록 주소를 저장합니다.

  • 13개의 블록 주소로 파일의 모든 블록을 가리킬 수 없다면, i-node의 14번째 블록 주소를 이용합니다.
  • 14번째 블록 주소이중 간접 블록 주소를 저장합니다.
  • 이중 간접 블록(double indirect block)이란?
    • 데이터 블록 주소를 저장하는 블록 주소가 저장된 블록을 의미합니다.
    • 즉, 단일 간접 블록들의 주소를 저장하는 블록이 이중 간접 블록입니다.

MySelf-Architec-Oper_15_46

넷째, ‘셋째’ 내용으로 충분하지 않다면, 15번째 주소에 삼중 간접 블록 주소를 저장합니다.

  • 14개의 블록 주소로 파일 블록을 가리킬 수 없다면, i-node의 15번째 블록 주소를 이용합니다.
  • 15번째 블록 주소삼중 간접 블록 주소를 저장합니다.
  • 삼중 간접 블록(triple indirect block)이란?
    • 이중 간접 블록 주소가 저장된 블록입니다.
    • 삼중 간접 블록까지 이용하면, 웬만한 크기의 파일은 모두 표현할 수 있습니다.

MySelf-Architec-Oper_15_47

이로써 i-node만 알면 파일 속성뿐만 아니라, 파일 크기가 크더라도 파일 데이터를 모두 가리킬 수 있습니다.

  • i-node파일의 모든 것을 담고 있다고 해도 과언이 아니지요.
  • 그래서 유닉스 파일 시스템의 디렉터리 엔트리도 위 그림과 같이 파일 이름i-node 번호로 구성됩니다.

MySelf-Architec-Oper_15_48

마지막으로 다음 그림과 같은 디렉터리 구조를 이루는 유닉스 파일 시스템에서 /home/minchul/a.sh 파일을 읽는 과정을 살펴보겠습니다.


MySelf-Architec-Oper_15_49

파티션 내에 위 그림과 같이 저장된다고 가정해 보겠습니다. (이해를 돕기 위해 간략화한 그림으로, 각 i-node에는 파일 속성은 제외하고 블록 주소만을 명시했습니다.)

  • 파일에 접근하기 위해 파일 시스템은 우선 루트 디렉터리 위치부터 찾습니다.
  • 루트 디렉터리 위치는 루트 디렉터리의 i-node를 보면 알 수 있는데,
  • 유닉스 파일 시스템루트 디렉터리의 i-node를 항상 기억하고 있습니다.
  • 위 그림에서는 2번 i-node루트 디렉터리의 i-node라고 가정했습니다.
  • 이제 /home/minchul/a.sh에 접근해봅시다.
    • 읽고자 하는 파일인 a.sh
    • 루트 디렉터리 아래, home 디렉터리 아래, minchul 디렉터리 아래에 있습니다.

MySelf-Architec-Oper_15_50

(1) 2번 i-node에 접근하여 루트 디렉터리의 위치를 파악합니다. 루트 디렉터리는 1번 블록에 있습니다.


MySelf-Architec-Oper_15_51

(2) 1번 블록을 읽으면 루트 디렉터리의 내용을 알 수 있습니다. 루트 디렉터리를 보세요. home 디렉터리의 i-node는 3번 i-node입니다.


MySelf-Architec-Oper_15_52

(3) 3번 i-node에 접근하여 home 디렉터리 위치를 파악합니다. home 디렉터리210번 블록에 있습니다.


MySelf-Architec-Oper_15_53

(4) 210번 블록을 읽으면 home 디렉터리 내용을 알 수 있습니다. home 디렉터리를 보면, minchul 디렉터리의 i-node8번입니다.


MySelf-Architec-Oper_15_54

(5) 8번 i-node에 접근하여 minchul 디렉터리의 위치를 파악합니다. minchul 디렉터리121번 블록에 있습니다.


MySelf-Architec-Oper_15_55

(6) 121번 블록을 읽으면, minchul 디렉터리의 내용을 알 수 있습니다. 파일 a.sh의 i-node 번호9번입니다.


MySelf-Architec-Oper_15_56

(7) 9번 i-node에 접근하여 파일 a.sh의 위치를 파악합니다. a.sh 파일98번, 12번, 13번 블록에 있습니다.

따라서 파일 시스템은 /home/minchul/a.sh를 읽기 위해 98번, 12번, 13번 블록에 접근하면 됩니다

이로써 파일 시스템의 이론적인 내용과 더불어 실제 파일 시스템 모습까지 살펴보았습니다. 파일 시스템을 아우르는 개념은 방대합니다. 파일 시스템만을 다루는 전공서도 많습니다. 그래서 이 책에서는 분량상 세상에 존재하는 다양한 파일 시스템 모두를 다루지는 않았고, 대표적인 파일 시스템 몇 개만을 다루었습니다.

이외에도 여러분이 알면 좋은 흥미로운 파일 시스템이 많습니다. 대표적으로 윈도우 운영체제에서 사용되는 NT 파일 시스템(NTFS), 리눅스 운영체제에서 사용되는 ext 파일 시스템 등이 있습니다.

지금까지 설명한 개념들을 제대로 이해했다면 이러한 파일 시스템을 이해하는 데에 큰 무리는 없을 것입니다. 이 책에서 설명한 파일 시스템 이외에 다른 파일 시스템에 대해서도 심화 학습하고 싶은 독자들은 아래 링크의 file_system 항목을 참고하기 바랍니다.


2.4 저널링 파일 시스템

컴퓨터 작업을 하던 도중 갑자기 전원이 나가거나,

  • 치명적인 오류로 인해 컴퓨터가 강제로 종료되어 버린 상황을 생각해 봅시다.
  • 파일 시스템을 변경하는 도중에 이러한 상황(시스템 크래시)이 발생하면 파일 시스템이 훼손될 수 있습니다.

저널링 파일 시스템이 있기 전에는 이런 상황이 발생하면,

  • 부팅 직후 파일 시스템을 검사하고 복구하는 프로그램을 실행시켰습니다.
  • 유닉스나 리눅스의 fsck나 윈도우의 scandisk가 이러한 프로그램에 속합니다.
  • 다만 이러한 프로그램들은 파일 시스템 내의 모든 블록에 대해 파일 시스템을 검사하기 때문에
  • 시간이 매우 오래 걸린다는 문제가 있었습니다.
  • 대용량 컴퓨터의 경우 몇 시간이 걸리기도 했지요.

그래서 등장한 것이 저널링 기법을 이용하는 저널링 파일 시스템입니다.

  • 저널링(journaling) 기법 : 작업 로그를 통해 시스템 크래시가 발생했을 때, 빠르게 복구하기 위한 방법

저널링 기법을 사용하는 파일 시스템에서 파일 시스템을 변경하는 작업은 다음과 같은 순서로 수행됩니다.

  1. 작업 직전 파티션의 로그 영역에 수행하는 작업(변경 사항)에 대한 로그를 남긴다.
  2. 로그를 남긴 후 작업을 수행한다.
  3. 작업이 끝났다면 로그를 삭제한다.

MySelf-Architec-Oper_15_57

이 경우 만약 작업을 하던 도중 시스템 크래시가 발생하여, 다시 부팅을 해야 한다면,

  • 파일 시스템 전 체를 검사할 필요없이 로그 영역에 남긴 로그만 검사해도 됩니다.
  • 즉, 저널링 파일 시스템은 시스템 크래시가 발생한 직후에
  • 로그 영역을 읽어 크래시가 발생한 당시 어떤 작업을 실행 중이었는지 알아낸 다음 해당 작업을 완료합니다.

마이크로소프트의 NT 파일 시스템, 리눅스의 ext3, ext4 파일 시스템을 포함하여, 현대 대부분의 파일 시스템은 이러한 저널링 기능을 지원합니다.


2.5 마운트

유닉스, 리눅스 등의 운영체제에서 **‘저장 장치를 마운트한다’**라는 표현을 자주 사용합니다.

  • 이는 한 저장 장치의 파일 시스템에서 다른 저장 장치의 파일 시스템에 접근할 수 있도록
  • 파일 시스템을 편입 시키는 작업을 의미합니다.
  • 이는 말보다는 예시로 이해하는 것이 좋습니다.

MySelf-Architec-Oper_15_58

e.g. 위 그림과 같은 디렉터리 구조를 가진 컴퓨터가 있다고 가정해 보겠습니다.

MySelf-Architec-Oper_15_59

그리고 위와 같은 디렉터리 구조를 가진 USB 메모리가 있다고 가정해보죠.


MySelf-Architec-Oper_15_60

USB 메모리의 파일 시스템을 컴퓨터의 /mnt 경로에 마운트하면,

  • /mnt 경로에 USB 메모리의 파일 시스템이 위 그림과 같이 연결됩니다.
  • 즉, /mnt 경로를 통해 USB 메모리에 접근할 수 있습니다.
  • /mnt/homework/os/a.cpp 경로를 통해, a.cpp 파일에 접근할 수 있고,
  • /mnt/pictures/Dog. jpg 경로를 통해, Dog.jpg 파일에 접근할 수 있지요.

유닉스, 리눅스와 같은 운영체제에서 다양한 저장 장치를 컴퓨터에 연결할 때, mount 명령어로 빈번하게 마운트합니다.


3. 마무리 및 이후

여기까지 모두 학습하신 여러분께 우선 감사와 축하의 말씀을 전합니다. 운영체제를 더 알고 싶은 독자를 위한 심화 학습 수단 두 가지를 소개하고 마치겠습니다.

개인적인 생각이지만, 운영체제는 분명 재미있고 즐거운 분야이지만, 동시에 파면 팔수록 방대하고 난해한 분야이기도 합니다. 세상에는 많은 운영체제가 있고, 그 많은 운영체제 중 하나를 제대로 아는 것도 벅찰 정도이지요. 시중에 있는 모든 운영체제를 한 번에 통달하기란 불가능에 가깝습니다.

그렇기 때문에 필자는 여러분들께 한 운영체제, 그중에서 리눅스(Linux) 운영체제의 자세한 동작을 분석해보길 권합니다. 리눅스를 추천하는 이유는 간단합니다. 리눅스는 그를 구성하는 모든 소스 코드가 공개되어 있는 오픈소스 소프트웨어이고, 수 많은 운영체제들이 리눅스를 기반으로 만들어졌기 때문입니다. 그래서 많은 개발자들이 리눅스를 사용하는 것이지요.

리눅스의 공식 페이지인 https://kernel.org에 접속해보면, 리눅스 커널을 구성하는 소스 코드뿐만 아니라 관련된 자세한 문서도 볼 수 있습니다. 이곳에서 프로세스 관리, 메모리 관리 등이 리눅스에 서 실제로 어떻게 구현되는지 확인해 보시기 바랍니다.

이 책을 통해 배운 내용을 복습할 수 있을 뿐만 아니라 리눅스만의 독특한 작동 방식도 확인할 수 있을 것입니다. 아직 프로그래밍 언어에 익숙하지 않아 리눅스 커널의 소스 코드를 분석하는 것이 어렵다면, 단순히 리눅스를 가상 머신 등에 설치하여 사용해 보는 것도 좋습니다. 이것이 필자가 제안하는 첫 번째 심화 학습 방법입니다

두 번째는 이 책을 통해 배운 내용을 프로그래밍 언어로 학습해 보는 것입니다. C/C++, Python, Java 등의 프로그래밍 언어를 통해 프로세스/스레드도 생성해 보고, 간단히 메모리도 다루어 보고, 파일 시스템과 상호작용도 해보길 권합니다. 개발자로서의 역량을 한층 더 올리는 계기를 제공할 것 입니다.