나는 Unix 기반 운영 체제에서 빈 디렉토리의 링크 수가 1이 아닌 2인 이유에 대해 많은 설명을 보았습니다. 다들 "." 때문이라고 하더군요. 각각 자신을 가리키는 디렉토리. "."라는 개념이 상대 경로를 지정하는 데 유용한 이유는 이해하지만 이를 파일 시스템 수준에서 구현하면 무엇을 얻을 수 있습니까? 경로를 취하는 쉘이나 시스템 호출에 경로를 해석하는 방법을 알려주면 어떨까요?
".."은 실제 링크이며 나에게 더 의미가 있습니다. 파일 시스템은 상위 디렉토리로 이동하기 위해 상위 디렉토리에 대한 포인터를 저장해야 합니다. 하지만 왜 그런지 이해가 안 돼요. '진정한 연결 고리가되는 것이 필요합니다. 이는 또한 구현 시 추악한 특수 사례로 이어지는 것 같습니다. 링크 수가 1보다 작은 inode에서 사용하는 여유 공간만 확보할 수 있다고 생각할 수 있지만 디렉토리인 경우 실제로 링크 수가 더 적은지 확인해야 합니다. 2보다. 왜 일관성이 없습니까?
답변1
참으로 흥미로운 질문입니다. 언뜻 보면 다음과 같은 장점이 있습니다.
.
첫째, ""는 셸이나 시스템 호출을 통해 현재 디렉터리로 해석될 수 있다고 명시합니다 . 그러나 디렉토리에 도트 입력을 사용하면 사실상 이러한 필요성이 사라지고 낮은 수준에서 일관성이 유지됩니다.
하지만 나는 이것이 이 디자인 결정의 기본 아이디어라고 생각하지 않습니다.
디렉터리에서 파일이 생성되거나 삭제되면 디렉터리의 수정 타임스탬프도 업데이트되어야 합니다. 이 타임스탬프는 해당 인덱스 노드에 저장됩니다. inode 번호는 해당 디렉토리 항목에 저장됩니다.
만약에점 항목은 존재하지 않으며 루틴은 해당 디렉토리 항목에서 inode 번호에 대한 상위 디렉토리를 검색해야 하며, 이로 인해 또 다른 디렉토리 검색이 발생합니다.
하지만다행히 현재 디렉터리에 일부 항목이 있습니다. 현재 디렉토리에 파일을 추가하거나 제거하는 루틴은 단순히 첫 번째 항목(일반적으로 점 항목이 있는 위치)으로 돌아가서 즉시 현재 디렉토리의 inode 번호를 찾습니다.
포인트 입력에는 세 번째 이점이 있습니다.
손상된 파일 시스템을 검사 하고 fsck
사용 가능 목록에도 없는 연결되지 않은 블록을 처리해야 할 때 데이터 블록(디렉토리 목록으로 해석될 때)에 inode를 가리키는 포인트 항목이 있는지 쉽게 확인할 수 있습니다. 차례로 데이터 블록을 가리킵니다. 그렇다면 데이터 블록은 손실된 디렉터리로 간주되어 다시 연결되어야 합니다.
답변2
(흠: 이제 다음 내용이 좀 서사적으로 변하고 있습니다...)
유닉스 파일 시스템의 디렉토리 디자인은 (현학적으로 말하자면,대개그러나 반드시 Unix 운영 체제에 연결될 필요는 없음)은 실제로 필요한 특수 사례의 수를 줄이는 놀라운 통찰력을 나타냅니다.
"디렉토리"는 실제로 파일 시스템의 파일일 뿐입니다. 파일 시스템에 있는 파일의 모든 실제 내용은 다음 위치에 있습니다.인덱스 노드(귀하의 질문을 통해 귀하가 이미 이에 대해 일부 알고 있음을 알 수 있습니다.) 디스크의 Inode에는 아무런 구조가 없습니다. 땅콩 버터처럼 디스크에 퍼져 있는 번호가 매겨진 바이트 덩어리일 뿐입니다. 이것은 아무런 목적도 없으며, 조금이라도 깔끔함을 느끼는 사람에게는 정말 싫은 일입니다.
이것오직특수 inode는 inode 번호 2입니다(레거시 이유로 인해 0이나 1이 아님). inode 2는 디렉터리 파일입니다.루트 디렉토리. 시스템이 파일 시스템을 마운트할 때 부팅하기 전에 디렉토리 inode 2를 읽어야 한다는 것을 "인식"합니다.
디렉토리 파일은 opendir(3)과 친구들이 읽는 내부 구조를 가진 파일일 뿐입니다. dir(5)에서 내부 구조를 볼 수 있습니다(운영 체제에 따라 다름). 살펴보면 디렉토리 파일 항목에 파일에 대한 정보가 거의 포함되어 있지 않음을 알 수 있습니다. 모든 정보는 inode 파일에 있습니다. 이 파일의 몇 가지 특별한 점 중 하나는 쓰기를 허용하는 모드에서 디렉토리 파일을 열려고 하면 open(2) 함수가 오류를 발생시킨다는 것입니다. 다양한 다른 명령(예: hexdump
)은 디렉토리 파일을 일반적인 방식으로 처리하는 것을 거부합니다. 이는 아마도 사용자가 원하는 것이 아닐 수도 있기 때문입니다(그러나 이는 파일 시스템이 아닌 특수한 경우입니다).
ㅏ하드 링크디렉토리 파일 맵의 항목에 지나지 않습니다. 이러한 맵에는 둘 이상의 항목이 있을 수 있으며 둘 다 동일한 inode 번호에 매핑됩니다. 따라서 해당 inode에 대한 하드 링크가 두 개(또는 그 이상) 있습니다. 이는 또한 이유를 설명합니다.모든파일에 하나 이상의 "하드 링크"가 있습니다. inode에는 파일 시스템의 디렉터리 파일에서 inode가 언급된 횟수를 기록하는 참조 횟수가 있습니다(이 숫자는 작업을 수행할 때 표시되는 숫자입니다 ls -l
).
좋습니다. 이제 업무를 시작하겠습니다.
카탈로그 파일은 문자열("파일 이름")을 숫자(inode 번호)로 매핑한 것입니다. 이러한 inode 번호는 디렉터리 "안에" 있는 파일의 inode 번호입니다. 이 디렉토리에 "있는" 파일은 다른 디렉토리 파일을 포함할 수 있으므로 해당 inode 번호는 디렉토리에 나열된 번호 중 하나입니다. 따라서 file 이 있는 경우 /tmp/foo/bar
디렉토리 파일에는 해당 문자열을 해당 파일의 inode에 매핑하는 foo
항목이 포함됩니다 . bar
카탈로그 "에 있는" 카탈로그 파일에 대한 항목이 카탈로그 파일에도 있습니다 /tmp
.foo
/tmp
mkdir(2)을 사용하여 디렉토리를 생성할 때 이 함수는
- 올바른 내부 구조(일부 inode 번호 포함)로 디렉토리 파일을 생성합니다.
- 새 디렉토리의 이름을 이 새 inode(링크 중 하나)에 매핑하는 상위 디렉토리에 항목을 추가합니다.
- 새 디렉터리에 항목을 추가하고 "." 문자열을 동일한 inode에 매핑합니다(이는 다른 링크를 나타냅니다).
- 새 디렉터리에 다른 항목을 추가하고 문자열 ".."을 (2) 단계에서 수정한 디렉터리 파일의 inode에 매핑합니다(이는 하위 디렉터리가 포함된 디렉터리 파일에 많은 수의 하드 링크가 표시된다는 의미입니다).
최종 결과는 (거의) 유일한 특수 사례는 다음과 같습니다.
- open(2) 함수는 쓰기를 위해 디렉토리 파일을 여는 것을 방지함으로써 사용자가 자책하기 어렵게 만듭니다.
- mkdir(2) 함수는 순전히 파일 시스템에서 쉽게 이동할 수 있도록 새 디렉토리 파일에 몇 가지 추가 항목("." 및 "..")을 추가하여 일을 훌륭하고 단순하게 유지합니다. "."이 없어도 파일 시스템이 제대로 작동할지 의심됩니다. 및 ".."이 있지만 사용하기 어려울 수 있습니다.
- 디렉토리 파일은 "특수"로 표시된 몇 안 되는 파일 유형 중 하나입니다. 이는 본질적으로 open(2)과 같은 기능이 약간 다르게 동작하도록 지시합니다.
st_mode
통계(2)를 참조하세요 .
(원래 stackoverflow 질문, 2011-10-20에서 복사됨)