한빛미디어의 '리눅스 커널의 이해'를 읽고 내용을 정리하는 글입니다. **


- 가상 파일 시스템의 역할

 '가상 파일 시스템(VFS, Virtual File System)'은 표준 유닉스 파일 시스템이 제공하는 모든 시스템 콜을 처리하는 커널 소프트웨어 계층이다. VFS의 장점은 여러 종류의 파일 시스템에 대해 공통 인터페이스를 제공한다는 것이다. 예를 들어, cp 명령을 통해 MS-DOS 디스켓의 파일을 일반 Ext2(2차 확장 파일 시스템) 디렉토리에 복사한다고 해도 cp 프로그램은 복사 대상과 복사 목적지의 파일 시스템 유형을 알 필요가 없다. 대신 cp는 일반 시스템 콜(open, read, write 등)을 통해 VFS와 상호 작용한다.

VFS가 지원하는 파일 시스템은 크게 다음과 같이 세 부류로 나눌 수 있다.

1. 디스크 기반 파일 시스템

로컬 디스크 파티션의 기억 장소 또는 디스크를 흉내내는 몇 가지 다른 장치(USB 등)를 관리한다. VFS가 지원하는 잘 알려진 디스크 기반 파일 시스템은 다음과 같다.

- 널리 사용되는 Ext2, 최신 Ext3, 또한 ReiserFS같은 리눅스의 독자적인 파일 시스템

- SYSV(시스템 V, Coherent, XENIX)와 UFS(BSD, Solaris, NEXTSTEP), MINIX 파일 시스템, 베리타스 VxFS(SCO 유닉스웨어) 등 다른 유닉스를 위한 파일 시스템

- MS-DOS, VFAT, NTFS 같은 마이크로소프트 파일 시스템

- ISO9660 CD-ROM 파일 시스템, UDF DVD 파일 시스템

- IBM OS/2(HPFS), 애플 매킨토시(HFS), 아미가 패스트 파일 시스템(AFFS), 아콘 디스크 파일 시스템(ADFS) 등 기타 전용 파일 시스템

- IBM의 JFS, SGI의 XFS 등 리눅스 이외의 시스템에서 유래한 추가적인 저널링 파일 시스템


2. 네트워크 파일 시스템

 네트워크로 연결된 다른 컴퓨터의 파일에 쉽게 접근하게 해준다. VFS가 지원하는 잘 알려진 네트워크 파일 시스템으로는 NFS, Coda, AFS, CIFS, SMB, NCP 등이 있다. (책에는 없었지만 GlusterFS도 있다)


3. 특수 파일 시스템(가상 파일 시스템이라고도 함)

 이 파일 시스템은 자신의 컴퓨터나 다른 컴퓨터의 실제 디스크 공간을 관리하지 않는다. /proc이 대표적인 특수 파일 시스템이다.


- 공통 파일 모델 

 VFS의 핵심 개념은 지원하는 모든 파일 시스템을 표현할 수 있는 '공통 파일 모델(Common File Model)'을 도입하는 것이다. 이 모델은 전통적인 유닉스 파일 시스템이 제공하는 파일 모델을 충실히 따른다. 

 공통 파일 모델에서는 각 디렉토리를 파일의 목록과 다른 디렉토리들을 포함하는 파일처럼 생각한다. 하지만 몇몇 비 유닉스 계열의 디스크 기반 파일 시스템은 디렉토리 트리에서 각 파일의 위치를 저장한 파일 할당 테이블(FAT)을 사용한다. 이런 파일 시스템에서는 디렉토리를 파일로 간주하지 않는다. FAT 파일 시스템을 리눅스에서 구현하기 위해서는 VFS의 공통 파일 모델을 따르도록 하기 위해 실행 중에 디렉토리에 대응하는 파일을 생성할 수 있어야 한다. 이 파일은 커널 메모리 객체로만 존재한다.

 본래 리눅스 커널은 read()나 ioctl() 작업을 처리하는 특정 함수를 직접 구현할 수 없고, 대신 각 작업에 대해 포인터를 사용해야 한다. 포인터는 접근할 특정 파일 시스템을 위한 적절한 함수를 가리키게 한다. 파일은 커널 메모리에서 file 자료 구조로 표현되는데, 이 자료 구조에는 f_op라는 필드가 있어서 각 파일 시스템을 처리하는 함수에 대한 포인터를 포함한다. 함수 중에는 파일을 읽는 함수도 있으며, read()함수를 실행했을 때 커널 내부에서 sys_read()는 이 함수에 대한 포인터를 찾아서 호출한다. 따라서 다음과 같이 간접적으로 호출하게 되는 것이다.

file->f_op->read(...);

 이와 비슷하게 write()연산은 출력 파일에 대응하는 적당한 쓰기 함수를 실행하도록 한다. 간단히 말해서 커널은 각 열린 파일에 대해 file 변수에 알맞은 함수 포인터를 할당하고, f_op 필드가 가리키는 각 파일 시스템별 호출을 실행해야 한다.


공통 파일 모델은 다음과 같은 객체 유형으로 이루어진다.

- 슈퍼 블록 객체

 마운트 된 파일 시스템에 대한 정보를 저장한다. 디스크 기반 파일 시스템의 경우, 이 객체는 일반적으로 디스크에 저장한 파일 시스템 제어 블록(File System Control Block)에 대응한다.


- 아이노드 객체

 특정 파일에 대한 일반 정보를 저장한다. 디스크 기반 파일 시스템의 경우, 이 객체는 일반적으로 디스크에 저장한 파일 제어 블록(File Control Block)에 대응한다.


- 디엔트리 객체

 디렉토리 항목(즉 특정 파일 이름)과 이에 대응하는 파일의 연결에 대한 정보를 제공한다.


 프로세스 3개가 같은 파일 하나에 접근하며, 이 중 두 프로세스는 동일한 하드 링크를 사용하여 접근한다고 하면 세 프로세스 모두 각각의 파일 객체를 소유하지만 디엔트리 객체는 하드 링크 하나당 하나만 필요하기 때문에 두 프로세스는 같은 디엔트리 객체에 접근하게 된다. VFS는 모든 파일 시스템에 대한 공통 인터페이스를 제공하는 일 외에도 가장 최근에 사용한 디엔트리 객체를 디엔트리 캐시(Dentry Cache)라는 디스크 캐시에 저장함으로 파일 경로명을 경로의 마지막 구성 요소인 파일 아이노드로 변환하는 속도를 높인다.


( 실제 파일 블록당 아이노드 객체는 하나씩 존재함. 디엔트리 객체는 하드링크 하나당 하나씩 존재하며 같은 파일을 가리키는 하드링크는 같은 아이노드 객체를 참조하여 실제 파일에 접근함. )

(디엔트리 객체는 ext 구조에서는 디스크에 저장된다고 하는데 다른 파일 시스템에서는 커널 메모리 영역에 저장된다고 함. 하드 링크는 같은 파일 시스템에 대해서만 만들 수 있다는게 이것때문인 것 같은데, 만약에 NTFS 파일 시스템에서 같은 NTFS 파일 시스템에 하드 링크를 만들 경우 어떻게 저장되는지는 좀 더 찾아봐야 할 듯 하다.)

블로그 이미지

__미니__

E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?

댓글을 달아 주세요