Unix 파일 시스템에서 디렉토리는 어떻게 구현됩니까?

Unix 파일 시스템에서 디렉토리는 어떻게 구현됩니까?

내 질문은 디렉토리가 어떻게 구현됩니까? 테이블, 배열 또는 유사한 데이터 구조와 같은 변수와 같은 데이터 구조를 신뢰할 수 있습니다. UNIX는 오픈 소스이므로 프로그램이 새 디렉토리를 생성할 때 수행하는 작업을 소스 코드에서 볼 수 있습니다. 이 주제에 대해 어디서 보거나 자세히 설명할 수 있는지 알려주실 수 있나요? 디렉토리는 내가 이해할 수 있는 "파일"이며 디렉토리는 실제로 파일입니까? 파일이 실제로 "파일에" 저장되어 있는지는 확실하지 않지만 "파일"이라는 단어를 사용하여 거의 모든 것을 의미할 수 있으며 확실히 파일이 아닌 것이 무엇인지 잘 모르겠습니다. 변수 "a" 파일. 예를 들어, 링크는 물론 파일이 아니고 링크는 디렉터리와 비슷하지만 이는 디렉터리 파일입니까? 위반입니다.

답변1

디렉토리의 내부 구조는 사용되는 파일 시스템에 따라 다릅니다. 무슨 일이 일어나고 있는지 정확히 알고 싶다면 파일 시스템 구현을 살펴보세요.

기본적으로 대부분의 파일 시스템에서 디렉토리는연관 배열파일 이름(키)과 inode 번호(값) 사이. 이 같은:

1167010 .
1158721 ..
1167626 subdir
 132651 barfile
 132650 bazfile

목록은 (보통) 4KB 블록 체인 내에서 (다소) 효율적인 방식으로 인코딩됩니다. 일반 파일의 내용도 유사하게 저장됩니다. 디렉터리의 경우 이러한 블록에 사용된 실제 크기를 아는 것은 의미가 없습니다. 이것이 보고된 디렉터리 크기가 du4KB의 배수인 이유입니다.

Inode는 블록을 함께 결합하여 일반적인 의미에서 "파일"인 엔터티를 형성합니다. 이는 일종의 주소인 숫자로 식별되며, 각 숫자는 일반적으로 단일 특수 블록으로 저장됩니다.

이 모든 관리는 커널 모드에서 이루어집니다. 소프트웨어에서는 int mkdir(const char *pathname, mode_t mode);시스템 호출을 발생시키는 이름의 함수를 사용하여 디렉토리를 생성하기만 하면 되며, 다른 모든 작업은 백그라운드에서 수행됩니다.

링크 구조 정보:

하드 링크는 파일이 아니며 단지 새로운 디렉토리 항목일 뿐입니다(예:이름 – 아이노드 번호Association)은 기존 inode 엔터티²를 나타냅니다. 이는 동일한 인덱스 노드가 다른 경로 이름에서 액세스될 수 있음을 의미합니다. 특히, 메타데이터(권한, 소유권, 타임스탬프...)는 inode에 저장되므로 이러한 메타데이터는 고유하며 파일에 액세스하기 위해 선택한 경로 이름과 무관합니다.

심볼릭 링크대상과 다른 파일입니다. 이는 자체 인덱스 노드가 있음을 의미합니다. 이전에는 일반 파일처럼 처리되었습니다. 대상 경로는 데이터 블록에 저장되었습니다. 하지만 지금은 효율성상의 이유로 최근확대파일 시스템에서 60바이트보다 짧은 경로는 inode 자체 내에 저장됩니다(일반적으로 데이터 블록에 대한 포인터를 저장하는 데 사용되는 필드 사용).


1. 이것은 를 사용하여 얻습니다 ls -ai1 testdir.
2. 해당 유형은 현재 "디렉토리"와 달라야 합니다.

답변2

Stéphane Gimenez의 게시물을 확장하면 새 디렉토리를 생성하는 것은 S_IFDIR의 st_mode 값(권한 모드 포함)을 사용하여 새 inode를 생성하고 연결된(2) 시스템을 사용하여 새 inode의 첫 번째 데이터 블록에 두 개의 항목을 생성하는 프로세스입니다. call: '.'은 이 새로운 inode를 가리키고 '..'는 상위 디렉토리를 가리키는데, 그런 다음 inode와 새 디렉토리의 이름을 사용하여 상위 디렉토리에 항목을 생성합니다. 첫 번째와 마지막 부분이 호출됩니다. mknod(2) 시스템에 의해. 또한 이제 루트만 mknod(2)를 사용하여 우리가 논의 중인 작업 유형을 수행할 수 있습니다.

예를 들어 mkdir("/home/larry.user/xyzzy", 0666)기본적으로 다음과 같습니다(SysV 일에 대한 C 코드[1]).

int mode = 0666;
char newdir[] = "/home/larry.user/xyzzy";
char path1[NAMESZ+4, path2[NAMESZ+4], *p;
mknod(newdir, S_IFDIR|mode);
strcpy(path1, newdir);
strcat(path1, "/."); /* "." link */
link(newdir, path1);
strcat(path1, ".");  /* ".." link */
strcpy(path2, newdir);
if ((p = strrchr(path2, '/') == (char *)0) /* root directory */
    link(".", path1);
else {
    *p = '\0';
    link(path2, path1);
}
  1. Haviland 및 Salama, "UNIX 시스템 프로그래밍", 1987, pp. 69-71.

이것은 너무 오류가 발생하기 쉬우므로(fsck의 주된 이유 중 하나), 이를 수행하기 위해 mkdir(2) 시스템 호출이 만들어졌습니다.

amy 파일 시스템 객체는 mknod(2)를 사용하여 생성할 수 있습니다: 일반 파일, 디렉토리, 장치 파일, 심볼릭 링크 등. 따라서 OP의 질문 중 하나에 대답하자면 예, 디렉토리는 파일입니다. 즉, "I/O 인터페이스를 통해 작동하는 파일 시스템에 상주하는 inode로 표시되는 개체입니다"라는 뜻입니다.

답변3

Unix/Linux 파일 시스템에 대해 더 자세히 알고 싶다면 두 권의 책을 추천합니다.Linux 커널에 대해 알아보기그리고리눅스 커널 개발. 리눅스 커널에 대해 배울 수 있는 최고의 책입니다.

"범용 파일 모델" Unix 시스템에서 각 디렉터리는 파일 및 디렉터리 목록이 포함된 파일로 처리됩니다.

VFS(Virtual File System)에서는 디렉터리를 호출합니다.dentry. 이것은 dentry 문자열 이름(이름), inode에 대한 포인터(d_inode) 및 상위 디렉토리 항목에 대한 포인터(d_parent). 아이노드는 파일 시스템에서 파일 정보를 처리하는 데 사용되는 구조이다. 예를 들어, 디렉토리가 있는 경우 /tmp/test/fooVFS는 경로 이름의 각 구성 요소에 대해 dentry 객체를 생성합니다. 따라서 하나의 dentry 개체, 루트 디렉터리의 항목에 대한 /두 번째 dentry 개체 , 테스트 디렉터리의 항목에 대한 세 번째 dentry 개체가 생성됩니다.testfoo

답변4

읽기부터 시작하시면 됩니다http://www.freebsd.org/doc/en/books/design-44bsd/book.html#OVERVIEW-FILESYSTEM. 자세한 내용은 훌륭한 고전 서적 "4.4 BSD 운영 체제의 설계 및 구현"을 참조하세요.

관련 정보