파일 시스템
xv6 파일 시스템은 데이터 파일과 디렉토리를 제공합니다. 데이터 파일은 해석되지 않은 바이트 배열을 포함하고 있으며, 디렉토리는 데이터 파일과 다른 디렉토리에 대한 이름이 지정된 참조를 포함합니다. 디렉토리들은 루트라고 불리는 특별한 디렉토리를 시작으로 트리를 형성합니다. /a/b/c와 같은 경로는 루트 디렉토리 /에서 a라는 디렉토리 내에 있는 b라는 디렉토리 내에 있는 c라는 파일 또는 디렉토리를 가리킵니다. /로 시작하지 않는 경로는 호출하는 프로세스의 현재 디렉토리를 기준으로 평가되며, 이는 chdir 시스템 호출을 사용하여 변경할 수 있습니다. 아래 코드 조각들은 같은 파일을 엽니다(모든 관련 디렉토리가 존재한다고 가정합니다):
chdir("/a");
chdir("b");
open("c", O_RDONLY);
open("/a/b/c", O_RDONLY);
첫 번째 조각은 프로세스의 현재 디렉토리를 /a/b로 변경하고, 두 번째 조각은 프로세스의 현재 디렉토리를 참조하거나 변경하지 않습니다. 새 파일과 디렉토리를 생성하기 위한 시스템 호출이 있습니다. mkdir은 새 디렉토리를 생성하고, O_CREATE 플래그를 사용한 open 시스템 호출은 새로운 데이터 파일을 생성하며, mknod은 새 디바이스 파일을 생성합니다.
디바이스 파일은 컴퓨터 시스템의 입출력 장치 또는 기타 하드웨어 리소스를 나타내는 파일입니다. 이러한 파일을 통해 사용자 및 응용 프로그램은 시스템의 하드웨어에 접근하고 제어할 수 있습니다.
mkdir("/dir");
fd = open("/dir/file", O_CREATE|O_WRONLY);
close(fd);
mknod("/console", 1, 1);
mknod은 디바이스를 참조하는 특수 파일을 생성합니다. 디바이스 파일과 연결된 것은 주 장치 번호와 부 장치 번호입니다 (mknod에 전달되는 두 인수). 이는 커널 디바이스를 고유하게 식별합니다.
나중에 프로세스가 디바이스 파일을 열면, 커널은 파일 시스템에 대한 시스템 호출이 아닌 커널 디바이스 구현으로 읽기 및 쓰기 시스템 호출을 전환합니다.
파일의 이름은 파일 자체와 구별됩니다. 동일한 기본 파일은 여러 개의 이름을 가질 수 있으며, 이러한 이름을 링크라고 합니다. 각 링크는 디렉토리의 항목으로 구성되며, 항목에는 파일 이름과 inode에 대한 참조가 포함됩니다. Inode에는 파일의 메타데이터가 포함되어 있으며, 파일의 종류 (파일, 디렉토리 또는 디바이스), 길이, 디스크 상의 파일 내용의 위치 및 파일의 링크 수를 포함합니다. fstat 시스템 호출은 파일 디스크립터가 가리키는 inode에서 정보를 검색합니다. 이는 stat.h (kernel/stat.h)에 정의된 struct stat을 채웁니다.
#define T_DIR 1
#define T_FILE 2
#define T_DEVICE 3
struct stat {
int dev; // File system's disk device
uint ino; // Inode number
short type; // Type of file
short nlink; // Number of links to file
uint64 size; // Size of file in bytes
};
link 시스템 호출은 기존 파일과 동일한 inode를 가리키는 다른 파일 시스템 이름을 생성합니다. 이 코드 조각은 "a"와 "b"라는 새로운 파일을 모두 생성합니다.
inode는 파일 시스템에서 파일을 식별하고 메타데이터를 저장하는 방식입니다. 각 파일은 파일 시스템 내의 고유한 inode를 가지며, 이 inode에는 파일의 종류, 소유자, 권한, 크기, 생성 시간 등의 정보가 포함됩니다.
open("a", O_CREATE | O_WRONLY);
link("a", "b");
a에서 읽거나 쓰는 것은 b에서 읽거나 쓰는 것과 같습니다. 각 inode는 고유한 inode 번호로 식별됩니다. 위의 코드 시퀀스 이후에는 fstat의 결과를 검사하여 a와 b가 동일한 내용을 참조한다는 것을 확인할 수 있습니다. 둘 다 동일한 inode 번호(ino)를 반환하며, nlink 카운트가 2로 설정됩니다.
unlink 시스템 호출은 파일 시스템에서 이름을 제거합니다. 파일의 링크 수가 0이 되고 더 이상 파일 디스크립터가 해당 파일을 참조하지 않을 때에만 파일의 inode와 해당 내용을 보유하는 디스크 공간이 해제됩니다.
따라서 마지막 코드 시퀀스에
unlink("a");
를 추가하면 inode 및 파일 내용이 b로 여전히 접근 가능합니다. 또한,
fd = open("/tmp/xyz", O_CREATE|O_RDWR);
unlink("/tmp/xyz");
를 함께 사용하는 것은 fd를 닫거나 프로세스가 종료될 때 정리되는 이름이 없는 임시 inode를 만드는 관용적인 방법입니다.
유닉스는 mkdir, ln, rm과 같은 파일 유틸리티를 쉘에서 호출할 수 있는 사용자 수준의 프로그램으로 제공합니다. 이런 설계를 통해 누구나 새로운 사용자 수준 프로그램을 추가하여 명령줄 인터페이스를 확장할 수 있습니다. 이런 계획은 현재에 와서는 당연해 보이지만, 유닉스가 설계된 시기에 다른 시스템들은 종종 이러한 명령을 쉘에 내장시켰고 (또한 쉘을 커널에 내장시켰습니다).
그 중 하나는 cd인데요, 이것은 쉘에 내장되어 있습니다. cd는 쉘 자체의 현재 작업 디렉터리를 변경해야 합니다. cd를 일반적인 명령어로 실행한다면 쉘은 자식 프로세스를 포크하고, 그 자식 프로세스가 cd를 실행하고, cd가 자식의 작업 디렉터리를 변경할 것입니다. 부모(즉, 쉘)의 작업 디렉터리는 변경되지 않습니다.
uninterpreted : 해석되지 않은
diverts : 전환하다
distinct : 별개의
inspecting : 검사
idiomatic : 관용적인
temporary : 임시적인
'xv6-book' 카테고리의 다른 글
xv6-book (Ch1-과제) (1) | 2024.02.09 |
---|---|
xv6-book (1.5 Real world) (2) | 2024.02.06 |
xv6-book (1.3 Pipes) (0) | 2024.02.04 |
xv6-book (1.2 I/O and File descriptors) (0) | 2024.02.04 |
xv6-book (Ch1.1-Processes and memory) (0) | 2024.01.30 |