[OS] File System

Operating Systems 2013. 5. 17. 03:13

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


OS 폴더에 포스팅하는게 얼마만인지.. 사실 할 필요는 있었다. OS 블로그가 파일 시스템에 대한 이야기가 없다는 것이 말이 되는가? 그래서 포스팅하려고 한다. 요즘 포스팅에 재미가 들려서 계속 이것 저것하게 된다.


우선 파일에 대해서 이야기하기 전에 파일이 저장되는 물리적인 장치에 대해서 먼저 이야기해보자. 그렇다. 디스크가 바로 파일이 저장되는 물리적인 장소이다. 그 디스크는 어떻게 이루어져있을까? Sector, Track, Cylinder, Platter, Surface 이 다섯개가 디스크를 이루고 있고 그 이외에 Head, Arm, Positioner, Spindle 등이 디스크의 작동을 돕는다.

아래의 그림과 같이 되어있다.



각각을 설명하자면 이렇다.

우선 하나의 디스크는 회전축을 갖는다. 이 회전축을 Spindle이라고 한다. 이 Spindle에 이상한 원판이 몇 개 끼어져서 돌아가는데 그 각각을 Platter이라고 한다. 그 트랙 위에 데이터가 저장이 되는 것인데, 앞 뒤면(Surface) 모두 따로 따로 저장이 가능하다. 따라서 하나의 Platter는 두 개의 Surface를 갖는다는 당연한 말을 하고 있네;; 위의 그림에서 오른쪽에 Platter 0, Platter 1, Platter 2가 있다. 각각이 왼쪽의 그림처럼 여러 개의 Track으로 이루어져있다. 나무를 보면 나이태가 있는데, 그 나이태가 바로 Track이라고 보면 된다. 이 나이태를 세로로 나누어 보자. 아래와 같이 말이다.


Track을 세로로 나누어서 나온 여러 개의 작은 조각들을 Sector라고 한다. 파일은 섹터 단위로 저장이 된다. 여기서 잠깐. 트랙 안쪽의 섹터와 바깥쪽의 섹터 크기가 다른데, 어느 쪽에 더 많은 데이터를 저장할 수 있을까? 옛날의 디스크에서는 넓이가 더 넓은 바깥쪽의 섹터와 더 좁은 안쪽의 섹터에 저장할 수 있는 양이 같았다고 한다. 하지만 지금은 바깥쪽에 더 많은 데이터를 저장할 수 있다고 한다. (저장 용량 효율을 높이기 위함) 하나의 디스크에 여러 개의 Platter가 있다. 그 각각의 Platter가 같은 개수의 Track을 가지고 있을 것인데, (가령 Track 0 ~ Track k-1)

각각의 Platter의 같은 Track 번호를 갖는 Track들을 모아둔 것이 바로 Cylinder이다. 즉, Track의 집합체인 샘이다.


이와 같은 요소를 사용하기 위해서 우리는 Head, Arm, Positioner, Spindle 등이 필요하다. 


보면 대충 어떤 역할을 하는지 짐작이 갈 것이라고 믿는다. 간단하게 말하면 같은 속도로 돌아가는 디스크 위에서 Head가 위/아래로 움직이면서 데이터를 읽어 들이는 것이다. 


자, 이제는 물리적인 디스크에서의 주소를 이야기해보자. 한 때 가상 메모리에 대해서 엄청나게 고민했을 무렵, 이런 저런 가설?들을 머리 속에서 마구 세우고 있었을 때, 이런 생각도 해봤었다. 혹시 Logical Address라는 것이 하드디스크 내에 있는 주소를 의미하는 것이 아닐까? 맞는 말이기도 하고 틀린 말이기도 하다는 것을 지금은 알지만 Virtual Address의 개념을 모르고 있었을 때의 내 개념을 가정하고 말하면 완전 틀린 말이었겠지. 아무튼 실제 물리적인 하드디스크에서의 주소는 어떤 식으로 되어있는지 공부해보자.


실제 물리적인 주소는 어떻게 되어있을까? 앞서 말했듯이, 데이터는 섹터 단위로 디스크에 저장된다. 그렇다면 그 섹터를 알 수 있는 주소 형태면 되겠다. 하나의 섹터를 구별하기 위해서 필요한 요소는 실린더 번호, Surface 번호, 섹터 번호 세 가지가 되겠다. 어떤 실린더의 몇 번째 면? 그 중에서도 어떤 섹터? 이렇게만 구별하면 정확히 하나의 섹터가 구분될 수 있겠지.


그래서 실제로 컴퓨터에서는 다음과 같이 두 가지 방법의 형태 중 하나를 선택한다고 한다.



그러나 이것은 실제 디스크 주소일 뿐, 실제 OS는 디스크 주소를 위와 같이 인식하지 않는다. 가상 메모리 개념처럼 어떤 logical disk address를 어떤 방법을 써서 실제 disk 주소로 변형을 시킨다. 어떻게 변형하는지는 나도 모른다. 우선 여기에서는 OS가 가상 디스크 주소를 어떤 방법으로 변형시켜서 접근한다는 것만 알자.


이제 조금 더 파일 시스템에 가깝게 가서 이야기를 해보자. 우선 파일은 무엇인가? 

위키피디아를 참고하면 다음과 같다.(http://en.wikipedia.org/wiki/Computer_file)


computer file is a resource for storing information, which is available to a computer program and is usually based on some kind of durable storage. A file is durable in the sense that it remains available for programs to use after the current program has finished. Computer files can be considered as the modern counterpart of paper documents which traditionally are kept in offices' and libraries' files, and this is the source of the term. A group of files used by the same program can be packed into one archive file


즉, 파일이라는 것은 정보를 저장하기 위한 컴퓨터가 사용할 수 있는 자원같은 것이다. 이러한 파일들은 여러 가지 형태의 타입으로 존재한다. 우리가 흔히 말하는 그림 파일, 실행 파일, 텍스트 파일들이 그것이다. OS에서 파일을 논할 때 중요한 것은 해당 파일의 내용이 아니다. 바로 파일에 대한 정보들인 metadata들이다. 파일에 대한 정보라.. 무엇인지 아래 예시를 통해 보자.


Metadata of a file

1. Name

2. Identifier

3. Type

4. Location

5. Size

6. Protection

7. User identification

8. Time, date

...


이와 같은 정보들이 바로 metadata이다. 이제 metadata가 어떤 정보를 의미하는지는 모두가 이해했으리라고 생각한다. 다 중요하지만 여기서 특히나 중요한 정보가 location과 protection이다. 


Protection의 경우 multi user 환경의 OS에서 특히 중요하다. multi user 환경의 OS에서는 파일마다 권한을 가지고 있다. 나만 볼 파일을 누군가가 봐서 수정하거나 하면 좋겠나? 아니지. 이 protection에 대한 이야기는 뒤에서 조금 더 자세하게 다룰 예정이다. 


Location의 경우 파일을 Access하기 위해서 쓰인다. OS는 파일을 어떻게 접근할까? 기본적으로 OS는 하나의 파일을 읽을 때 우선 그 파일의 metadata를 메모리로 가져와서 location정보를 읽어서 파일의 위치를 찾아온다. 음... 무슨 말인지 모르겠으니 하나 하나 차근차근 보자. 


예를 들어 우리가 하나의 C프로그램에서 파일을 하나 오픈하려고 하면 보통 open()함수를 사용한다. 가령, test.txt라는 파일을 읽기 위해 C코드를 작성한다고 하자. 그러면 실제로 read명령어를 사용하기 전에 아래와 같이 open() 함수를 사용해야 한다.


f1 = open("/anything/abc/test.txt", O_RDONLY);


test.txt파일에 대해서 읽기만 수행하겠다는 뜻이다. 이 open()함수의 실제 역할이 사실은 하나의 파일의 metadata를 메모리로 로딩하는 역할이다. 왜 metadata를 메모리로 로딩해둘까? 여러가지 이유가 있겠지만 효율을 높이기 위한 이유가 있다. 만일 파일을 open() 함수를 사용하지 않고 그냥 read 혹은 write 한다면 매번 read할 때마다 directory search를 해야한다. 매번 read할 때마다 root 디렉토리에서 anything을 찾아서 그 밑에 있는 abc를 찾아서 그 밑에 있는 test.txt에 접근해야 한다. 얼마나 비효율적인가. 따라서 read 혹은 write하기 전에 먼저 open()함수를 통해서 한번만 디렉토리 탐색을 한다. 그리고 그 파일의 metadata를 메모리에 로딩해두면 나중에 read 혹은 write할 때 메모리에 로딩되어있는 metadata의 loacation 정보만 보면 그 파일의 위치를 찾을 수 있다는 뜻이 된다. 기본적으로 CPU가 하드디스크를 접근하는 속도와 메모리를 접근하는 속도는 엄청난 차이가 있다는 것은 모두가 알고 있을 것이다. 대략 10배 정도 차이나는 것으로 알고 있다. 


open()함수 본래의 역할을 알았으니 조금 더 자세하게 open()함수의 수행과정과 그 결과를 알아보자. f1 = open("/anything/abc/test.txt", O_RDONLY); 함수의 수행과정은 아래와 같다.


1. 파일 이름을 얻는다. (/anything/abc/test.txt)

2. 디렉토리 탐색 (해당 파일이 실제 존재하는 것인지 검사한다.)

3. 실제로 존재할 경우, 해당 파일의 metadata를 메모리에 로딩


지금까지는 위에서 다 설명했던 내용이다. 그 다음 과정에는 open-file table이라는 새로운 개념이 들어간다. open-file table은 open()함수에 의해 open된 파일의 list 형태로 나타낸 테이블이다. 즉 이 테이블에는 open된 파일이 모두 들어와 있다고 보면 된다.


4. metadata가 있는 주소의 위치를 가리키는 포인터를 open-file table에 저장한다.

5. 해당 open-file table 내의 index의 주소를 return 한다. (f1이 그 주소값을 갖게 될 것이다.)


그림으로 설명해보자. (역시 어려운 것은 그림으로 설명하면 쉬워진다.)



open-file table은 결국 파일의 metadata가 저장되어 있는 주소값을 가지고 있는 것이고 그 각각의 index에 대한 주소가 바로 open()함수의 return 값이 되는 것이다.


이제 파일을 어떻게 access하는지 대략적으로 감을 잡았으리라고 본다. 그러면 이제는 조금 더 구체적으로 과정을 이야기 해보자. 방금전에 open-file table에 대해서 이야기를 했다. 그런데 이 open-file table은 사실 두 가지 형태로 존재한다. per-process open-file table 그리고 system-wide open-file table이다.


per-process open-file table은 프로세스마다 가지고 있는 open-file table이다. 

system-wide open-file table은 시스템의 모든 open된 파일들에 대한 open-file table이다. 


Unix의 예를 가지고 이야기 해보자. 가령 unix에서 C 코드를 다음과 같이 작성했다고 하자.


fd1 = open("/etc/passwd", "O_RDONLY");

fd2 = open("/anything/abc/test.txt", "O_RDWR");

fd3 = open("/etc/passwd", "O_WRONLY");



위의 그림에서와 같이 UNIX 시스템에서는 per-process open-file table과 system-wide open-file table이 모두 존재한다. per-process open-file table이 system-wide open-file table를 가리키고 system-wide open-file table이 inode table을 가리키는데, inode table은 각 파일의 metadata를 가지고 있다. 이렇게 해서 아무튼 하나의 프로세스에서 사용될 fd1, fd2, fd3 값은 per-process open-file table index의 주소값이 된다.


※ Unix system에서 per-process open-file table은 file descriptor table이라고 하고 system-wide table은 file table이라고 한다. inode는 index node의 약자이다.


이번 포스팅에서는 파일 시스템에 대한 이야기보다는 OS가 파일을 접근하는 방법에 대해서 주로 알아보았다. 다음 포스팅에서는 파일 시스템에 대해서 이야기해볼 것이고 마운팅에 대한 개념을 설명해보려한다.

'Operating Systems' 카테고리의 다른 글

[OS] File System (Protection)  (1) 2013.05.18
[OS] File System  (0) 2013.05.18
[OS] Deadlock Detection  (2) 2013.02.03
[OS] Deadlock Avoidance (Banker's Algorithm)  (5) 2013.02.03
[OS] Deadlock Prevention and Deadlock Avoidance  (0) 2013.02.03
Posted by 빛나유
,