이번엔 운영체제가 파일과 디렉터리를 어떻게 관리해주는 지 알아보자.
그 전에, 파일 시스템이란 파일과 디렉터리를 관리하는 운영체제 내부에 있는 시스템이다.
파일과 디렉터리는 보조기억장치의 데이터 덩어리로 볼 수 있다.
파일은 보조기억장치에 저장된 의미있고, 관련된 정보의 집합이다.
파일에는 파일을 실행하기 위한 정보와 속성, 메타 데이터 등의 부가 정보로 이루어져있다.
파일의 속성은 아래와 같다.
유형은 운영체제가 인식하는 파일의 종류이다. 확장자로 특정지을 수 있다.
파일을 다루기 위해서는 반드시 운영체제를 거쳐야 한다. 파일 생성, 삭제, 열고 닫기, 읽기, 쓰기 등 다양한 시스템 호출이 존재한다.
윈도우에서는 폴더라고도 부른다. 하나의 디렉터리만 사용하던 1단계 디렉터리에서, 여러 개의 디렉터리가 계층적으로 구성된 트리 구조 디렉터리를 사용한다.
최상위 디렉터리를 루트 디렉터리 또는 '/' 라고 표현하며, 그 아래의 디렉터리를 서브 디렉터리라고 한다.
경로는 디렉터리를 이용해 파일이나 디렉터리의 위치와 이름까지 특정할 수 있는 정보를 말한다. 절대 경로와 상대 경로로 이루어져있다.
절대 경로는 루트 디렉토리부터 시작하는 경로, 상대 경로는 현재 디렉터리부터 시작하는 경로이다. 예를 들어 위의 g.jpg의 절대 경로는 /home/guest/d.jpg이고, 상대 경로는 guest/g.jpg이다.
운영체제가 디렉터리를 다루는 다양한 시스템 호출 역시 존재함!
사실 많은 운영체제에서는 디렉터리를 그저 특별한 형태의 파일로 간주한다.
파일의 내부에 파일과 관련된 정보들이 담겨있다면, 디렉터리 내부에는 해당 디렉터리에 담겨 있는 대상과 관련된 정보들이 테이블의 형태로 담겨있다.
디렉터리 테이블에 공통적으로 들어가는 것은 디렉터리에 포함된 대상의 이름과 그 대상이 보조기억장치 내에 저장된 위치가 담긴다.
이제 파일 시스템이 파일과 디렉터리를 보조기억장치에 할당하고 접근하는 방법에 대해 알아보자.
그 이전에 꼭 알아야 할 두가지 용어가 있다.
이제 막 공장에서 생산되어 한 번도 사용한 적 없는 새 하드디스크 혹은 ssd가 있다고 가정하자. 여기에 곧바로 파일을 생성하거나 저장하는 것은 불가능하다. 그 전에 파티셔닝과 포매팅이 필요하다.
파티셔닝은 저장 장치의 논리적인 영역을 구획하는 작업이다.
포매팅은 파일 시스템을 설정하는 작업이다.
어떤 방식으로 파일을 저장하고 관리할 지 결정하고, 새로운 데이터를 쓸 준비를 하는 작업이다.
포매팅까지 끝난 하드 디스크에는 파일을 저장할 수 있다. 운영체제는 파일과 디렉터리를 블록 단위로 읽고 쓴다. 즉 하나의 파일이 보조기억장치에 저장될 때에는 여러 블록에 걸쳐 저장된다.
하드디스크 안에 여러개의 블록이 있는데, 어느 블록에 어떻게 할당하게 될까?
파일 할당에는 위와 같은 방식으로 나뉘어 진다.
연속 할당은 이름 그대로 보조기억장치 내 연속적인 블록에 파일을 할당하는 방법이다.
연속 할당에서, 파일에 접근하기 위해서는 첫 번째 블록의 주소와 단위 길이를 알아야 한다. 디렉터리 엔트리에 담기는 정보는 파일이름과 첫 번째 블록 주소, 블록 단위 길이가 있다.
구현이 단순하지만 외부 단편화를 야기할 수 있다.
위와 같은 상황에서, 파일 D,F가 삭제되면 다음과 같은 모습이 된다.
이러한 상황에서 잔여 블록은 11개이지만, 블록을 7개 이상 사용하는 파일은 할당할 수 없다.
외부 단편화를 해결하기 위해 파일을 여러 블록에 흩어져 저장되게 하는 방식인 불연속 할당에 대해 알아보자.
반드시 첫 번째 블록부터 하나씩 읽어 들어야 한다.
오류 발생 시 해당 블록 이후 블록은 접근이 어렵다.
실제로 사용되는 파일 시스템의 방식과 동작 원리를 알아보자.
연결 할당 기반의 파일 시스템으로, 연결 할당의 단점을 보완한 방식이다.
연결 할당 방식에서 문제가 발생했던 근본적인 원인은 모든 블록에 다음 번지 블록의 주소를 기록했기 때문이다.
이 그림은 연결 할당 방식을 단순화한 그림이다.
예를 들어 파일이 4개의 블록으로 이루어져 있다고 하자. 4번 블록이 8번 블록의 주소를 저장하고 있고, 8번은 3번 블록의 주소를 저장하고 있다. 만약 이 중 하나의 블록에만 문제가 생겨도 다음 블록에 접근할 수 없게 된다.
만약 각 블록에 포함된 다음 블록의 주소를 한데 모아 테이블 형태로 빼놓으면 훨씬 더 효율적일 것이다.
이러한 방법을 FAT(File Allocation Table) 파일 시스템이라고 한다.
이 방식은 메모리에 캐시될 수 있기 때문에, 임의 접근 속도 또한 개선될 수 있다.
디렉터리 엔트리에는 다음과 같은 정보가 담긴다. 여기서는 파일의 속성까지 명시된다.
아래의 예시를 통해 FAT 파일 시스템의 방식을 알아보자.
a.sh를 읽기 위해 3번, 15번, 9번 블록을 확인하여 위치를 찾은 뒤
9,8,11,13번 블록으로 접근하게 된다.
색인 할당 기반의 파일 시스템이다.
색인 블록을 i-node(index node)라고 하며, 파일의 속성 정보와 15개의 블록 주소를 저장할 수 있다.
그런데 만약 15개가 넘는 크기의 파일을 저장해야 한다면 어떻게 해야할까?
블록 주소 중 12개에는 직접 블록 주소를 저장한다.즉 데이터의 주소를 직접 저장한다.
이로 충분하지 않다면, 13번째 주소에는 단일 간접 블록 주소를 저장한다.
다시말해 데이터의 주소를 저장한 블록의 주소를 저장한다.
2번으로도 충분하지 않다면, 14번째 주소에는 이중 간접 블록의 주소를 저장한다. 단일 간접 블록의 주소를 저장하는 블록의 주소를 저장한다.
유닉스 파일 시스템에서는 i-node가 핵심이다!
디렉터리 엔트리에는 i-node의 번호와 파일 이름이 담기게 된다.
여기서 a.sh파일을 읽어보자. 여기서도 먼저 루트 디렉터리에 접근한다. (루트 디렉터리에 접근하는 첫번째 노드는 시스템 내에서 알고 있다.)
i-node 2에 접근하여 루트 디렉터리는 1번 블록에 저장되어있다는 사실을 알 수 있다.
1번 블록에서는, home 디렉터리의 i-node는 i-node 3이라는 사실을 통해 i-node 3으로 가서 210번 블록에 저장되어 있다는 것을 알 수 있다.
해당 방법으로 i-node 1, i-node 3, i- node 8, i-node 9를 이용하여 1번, 210번, 121번 블록으로 접근하고, i-node 9에서는 a.sh를 읽어들이기 위해 99번,12번,13번 블록을 읽으면 된다는 사실을 알 수 있게 된다.
여기까지
운영체제 정리 끝~