Embedded : : Linux/: : Linux

리눅스(유닉스)의 파일 시스템

Jay.P Morgan 2023. 11. 9. 23:59

  리눅스(유닉스)의  파일 시스템

살펴보고자 하는 파일시스템은 전통적인 유닉스의 파일시스템으로 리눅스에서도 이 파일시스템을 선택적으로 사용할 수 있다. 유닉스 시스템의 디스크를 논리적인 구조로 나타내면 아래 그림 과 같이 부트 블록, 수퍼 블록, inode 리스트 그리고 데이터 블록들로 나눌 수 있다.

※ 유닉스 시스템 디스크의 논리적인 구조

  - 부트 블록 : 운영체제를 주기억장치에 올리는 역할을 하는 프로그램이 들어 있는 영역으로, 윈도우의 부트 레코드와 유사하다.

  - 수퍼 블록 : 디스크에 대한 다양한 정보를 저장하고 있는 곳으로, 전체 블록의 수, 블록의 크기, 사용 중인 블록의 수, 사용할 수 있는 블록의 번호, inode 리스트의 크기, 사용할 수 있는 inode의 번호 등의 정보를 저장한다.
  - inode 리스트 : inode들을 모아놓은 곳인데, 한 블록에 여러 개의 inode를 저장하고 있다. inode에 대해서는 바로 뒤에서 살펴볼 것이다.
  - 데이터 블록 : 일반적인 파일과 디렉토리 그리고 간접 블록을 저장하는 영역이다. 간접 블록에 대해서는 뒤에서 살펴볼 것이다.

그러면 inode(Index Node)에 대해 살펴보자. inode는 다음과 같이 파일에 대한 다양한 정보를 저장하는 곳으로 파일마다 하나씩 부여된다.

※ inode의 구성

  위 그림에서 ‘파일 위치’ 부분은 10개의 직접 블록 포인터와 단일 간접 블록 포인터, 이중 간접 블록 포인터, 삼중 간접 블록 포인터로 구성되는데, 직접 블록 포인터에는 파일이 저장된 블록 번호가 직접 저장된다. 그리고 간접 블록 포인터에는 블록 번호들을 모아 놓은 블록의 번호들을 저장하는데, 상세한 내용은 동작 예에서 설명한다.


  윈도우에서 파일에 대한 정보를 디렉토리에 저장하는 것과는 차이가 있는데, 예를 통해 이 과정을 살펴보자. 편의상 한 블록의 크기는 1,000바이트라 가정한다.

  유닉스로 포맷하면 루트 디렉토리는 첫 번째 데이터 블록(블록 100이라 가정)에 생성되는데, 루트 디렉토리에 대한 정보는 inode2에 저장된다. inode 2의 100은 루트 디렉토리가 저장된 블록 번호를 의미한다.

  그리고 블록 100의 내용을 보면 ‘.’과 ‘2’, ..’과 ‘2’가 저장된 것을 볼 수 있는데, ‘.’은 현재 디렉토리를 의미하고, ‘..’은 부모 디렉토리를 의미한다. 그리고 숫자 ‘2’는 inode 번호를 나타내는데, 용도는 차츰 알게 될 것이다. 아래 그림의 하단에 있는 inode들은 이를 확대한 것이다.

※ 유닉스로 포맷한 디스크의 초기 구조

 

 

  유닉스에서 파일을 디렉토리에 저장하는 과정

 

1) 루트 디렉토리 아래에 src 디렉토리를 생성한다. 데이터 블록 101에 src 디렉토리를 생성하고 src에 대한 정보를 inode 3에 저장한다. 그리고 루트 디렉토리에 디렉토리 이름인 src inode 번호인 3을 저장하고, src 디렉토리에는 ‘.’과 ‘3’, ..’과 ‘2’를 저장한다. 유닉스 시스템의 디렉토리는 해당 디렉토리에 저장된 모든 파일 이름과 각 파일에 대한 inode 번호를 저장한다.

※ 유닉스에서 파일 정보를 디렉토리에 저장하는 과정 1)

 

2) src 디렉토리에 1,500바이트 크기의 test.c 파일을 생성한다. test.c 파일은 두 개의 블록을 필요로 하므로 블록 102와 103에 생성되고, test.c 파일에 대한 정보는 inode 4에 저장한다. inode 4의 102와 103은 파일이 저장된 블록 번호다. 그리고 src 디렉토리에 파일 이름인 test.c inode 번호 4를 저장한다.

※ 유닉스에서 파일 정보를 디렉토리에 저장하는 과정 2)

 

3) 루트 디렉토리에 1,100바이트 크기의 c.txt 파일을 생성한다. 디스크 동작 단위는 블록이므로 두 블록 104와 105 모두를 차지해서 저장하고, c.txt에 대한 정보는 inode 5에 저장한다. 그리고 루트 디렉토리에 파일 이름인 c.txt inode 번호인 5를 저장한다.

※ 유닉스에서 파일 정보를 디렉토리에 저장하는 과정 3)

 

4) test.c 파일을 수정해서 크기가 2,500바이트로 커졌다고 하자. 수정된 파일을 저장하기 위해서는 블록 102, 103 외에도 1개의 블록이 더 필요하므로 블록 106에 나머지 부분을 저장한다. 그리고 inode 4에 블록 번호 106을 추가적으로 저장한다.

※ 유닉스에서 파일 정보를 디렉토리에 저장하는 과정 4)

 

5) src 디렉토리에 12,500바이트 크기의 book.c 파일을 생성한다. 블록 107부터 블록 119의 13개 블록에 book.c 파일을 저장하고, book.c 파일에 대한 정보를 inode 6에 저장한다. 그리고 src 디렉토리에 book.c inode 번호인 6을 저장한다. 파일 위치인 블록 번호 107부터 119를 inode에 저장해야 하는데, 좀 복잡해진다. inode를 보면 블록 번호를 직접 넣을 수 있는 직접 블록 포인터는 10개기 때문에 117, 118, 119는 다른 형태로 저장해야 한다.

※ 유닉스에서 파일 정보를 디렉토리에 저장하는 과정 5)

 

⑥ 이때 간접 블록 포인터를 활용한다. 블록 120에 나머지 블록 번호인 117, 118, 119를 저장하고 inode 6의 단일 간접 블록 포인터에 120을 저장한다. 결국 book.c 파일이 저장된 위치는 직접 블록 포인터에 저장된 ‘107, 108, ···, 116’과 단일 간접 블록 포인터가 가리키는 블록 120에 저장된 ‘117, 118, 119’이다.

※ inode의 파일 위치를 저장하는 부분

 

 

  간접 블록 포인터

  간접 블록 포인터란?

  정해진 블록 크기를 넘는 파일인 경우를 대비한 것

 

       단일 간접 블록 포인터 :  파일 저장 블록 번호들을 모아 놓은 블록을 나타냄

       이중 간접 블록 포인터 :  다른 간접 블록들의 블록 번호들을 모아 놓은 블록을 나타냄

       삼중 간접 블록 포인터 :  이중 간접 블록들의 블록 번호들을 모아 놓은 블록을 나타냄

※ 음영으로 표시된 블록이 파일을 저장하고 있는 부분

 

다음은 바로 앞 그림 구조의 src 디렉토리에서 test.c 파일을 읽는 순서다.

  1) 루트 디렉토리에 대한 정보를 저장하고 있는 inode 2에서 루트 디렉토리가 블록 100에 저장된 것을 확인하고 블록 100으로 간다.
  2) 블록 100에 위치한 루트 디렉토리에서 src의 정보가 inode 3에 저장된 것을 알고, inode 3으로 간다.

      만약 루트 디렉토리에 src에 대한 내용이 없으면 더 이상 진행하지 않고 종료한다.
  3) inode 3에서 src 디렉토리가 블록 101에 저장된 것을 확인하고 블록 101로 간다.
  4) src 디렉토리에서 test.c의 정보가 inode 4에 저장된 것을 알고 inode 4로 간다.
  5) inode 4에서 test.c가 블록 102, 103, 106에 저장되어 있음을 알고, 이들 블록에 저장된 내용을 읽는다.

 

 

 

네이버 지식백과