왜 '.' 유닉스의 하드 링크?


51

유닉스 기반 OS에서 빈 디렉토리에 대한 링크 수가 1이 아닌 2 인 이유에 대한 많은 설명을 보았습니다. 모두 '.'때문이라고 말합니다. 모든 디렉토리가 자신을 가리키는 디렉토리. 왜 '.'라는 개념이 있는지 이해합니다. 상대 경로를 지정하는 데 유용하지만 파일 시스템 수준에서 구현하면 얻을 수있는 것은 무엇입니까? 경로를 취하는 쉘이나 시스템 호출이 그것을 해석하는 방법을 알고있는 이유는 무엇입니까?

'..'은 실제 링크입니다. 훨씬 더 의미가 있습니다. 파일 시스템은 포인터를 상위 디렉토리로 다시 저장해야합니다. 그러나 나는 왜 '.' 실제 연결이 필요합니다. 또한 구현에서 추악한 특수 사례로 이어질 것 같습니다. 링크 수가 1 미만인 inode가 사용하는 공간 만 확보 할 수 있다고 생각할 수 있지만 디렉토리 인 경우 실제로 확인해야합니다. 링크 수가 2보다 적습니다. 왜 불일치가 발생합니까?


1
일단 당신 ..의 나무 걷기 소프트웨어가 이미 "부모 디렉토리 링크에서주기를 따르지 말 것" 예외 를 가져야 할 필요가 있기 때문에, .링크를 제외하고는 복잡성이 더해지지 않습니다 .
dmckee

답변:


37

실제로 흥미로운 질문입니다. 언뜻보기에 다음과 같은 장점이 있습니다.

우선 " ."을 현재 디렉토리로 해석 하는 것은 쉘이나 시스템 호출에 의해 수행 될 수 있다고합니다. 그러나 디렉토리에 점 항목이 있으면 실제로 이러한 필요성이 제거되고 더 낮은 수준에서도 일관성이 유지됩니다.

그러나 이것이이 디자인 결정의 기본 아이디어라고 생각하지 않습니다.

디렉토리에서 파일을 만들거나 제거 할 때 디렉토리의 수정 타임 스탬프도 업데이트해야합니다. 이 타임 스탬프는 inode에 저장됩니다. inode 번호는 해당 디렉토리 항목에 저장됩니다.

경우 도트 항목이되지 않을 것, 루틴은 다시 디렉토리 검색을 야기 상위 디렉토리에서이 디렉토리에 대한 항목에서 inode 번호를 검색해야합니다.

그러나 다행히도 현재 디렉토리에 점 항목이 있습니다. 현재 디렉토리에서 파일을 추가 또는 제거하는 루틴은 첫 번째 항목 (점 엔트리가 일반적으로 상주하는)으로 되돌아 가야하며 현재 디렉토리의 inode 번호를 즉시 찾았습니다.

도트 항목에 대한 세 번째 좋은 점이 있습니다.

fsck무료 목록에도 포함되지 않은 비 연결된 블록을 처리하는 검사 썩은 파일 시스템 및 데이터 블록 (디렉토리 목록으로 해석 할 때) 아이 노드를 가리키는 것 도트 항목이있는 경우는 확인하기가 쉽다 다시이 데이터 블록을 가리 킵니다. 그렇다면이 데이터 블록은 다시 연결해야하는 유실 된 디렉토리로 간주 될 수 있습니다.


매우 유용한 답변입니다.
Navaneeth KN

6
디렉토리 inode를 검색하는 루틴에 대한 의견은 가짜입니다. 커널 루틴은 .현재 디렉토리에서 찾아 볼 필요가 없습니다 . 실제로 이런 식으로 작동하는 커널을 찾을 수 없다면 (의심 스럽다 ...)
Dietrich Epp

1
@DietrichEpp에 동의합니다. 시스템 이 처음에 디렉토리 엔트리 를 볼 수 있으려면 이미 inode에 대해 알고 있어야합니다. 디렉토리 엔트리를 포함하는 데이터 블록에 도달하는 방법이기 때문입니다.
Lqueryvg

10

(흠 : 다음은 이제 서사시입니다 ...)

유닉스의 디렉토리의 디자인은 (현학적 수있는,있다 된 파일 시스템 일반적으로 하지만 반드시 유닉스의 OS에 연결)이 실제로 필요한 특별한 경우의 수를 감소 멋진 통찰력을 나타냅니다.

'디렉토리'는 실제로 파일 시스템의 파일입니다. 파일 시스템에있는 파일의 모든 실제 내용은 inode입니다 (질문에서, 당신은 이미이 것들 중 일부를 알고 있음을 알 수 있습니다). 디스크의 inode에는 구조가 없습니다. 디스크에 땅콩 버터처럼 퍼져있는 많은 수의 바이트 블록입니다. 이것은 유용하지 않으며, 단정 한 마음을 가진 사람이라면 누구나 기피 할 수 있습니다.

유일한 특별한 아이 노드는 (전통의 이유로하지 0 또는 1) 아이 노드 수를 2; inode 2는 디렉토리 파일 인 루트 디렉토리 입니다. 시스템이 파일 시스템을 마운트하면 시작하기 위해 indir 2를 읽어야한다는 것을 '알고'있습니다.

디렉토리 파일은 opendir (3)과 친구들에 의해 읽히기위한 내부 구조를 가진 파일 일뿐입니다. 내부 구조는 dir (5)에 기록되어 있습니다 (OS에 따라 다름). 이를 보면 디렉토리 파일 항목에 파일에 대한 정보가 거의 포함되어 있지 않다는 것을 알 수 있습니다. 이 파일에서 특별한 몇 가지 사항 중 하나는 쓰기를 허용하는 모드로 디렉토리 파일을 열려고하면 open (2) 함수에 오류가 발생한다는 것입니다. 여러 가지 다른 명령 (하나의 예를 선택하기 위해 hexdump)은 디렉토리 파일에서 정상적인 방식으로 작동하지 않을 것입니다. 왜냐하면 그것은 아마도 원하는 것이 아니기 때문입니다 (그러나 파일 시스템이 아닌 특수한 경우입니다).

하드 링크는 디렉토리 파일의 맵의 항목보다 아무것도 더도 적습니다. 같은 맵에 두 개의 (또는 그 이상) 항목을 가질 수 있으며, 둘 다 동일한 inode 번호로 매핑됩니다. 따라서이 inode에는 두 개 이상의 하드 링크가 있습니다. 또한 모든 파일에 하나 이상의 '하드 링크'가있는 이유도 설명합니다 . inode는 참조 횟수를 가지며, 파일 시스템 어딘가의 디렉토리 파일에 inode가 몇 번 언급되었는지 기록합니다 (이것은 사용자가 볼 때 표시되는 숫자입니다 ls -l).

OK : 우리는 지금 요점에 도달하고 있습니다.

디렉토리 파일은 문자열 ( 'filenames')을 숫자 (inode number)로 매핑 한 것입니다. 이러한 inode 번호는 해당 디렉토리에있는 파일의 inode 번호입니다. 해당 디렉토리에 '있는'파일에는 다른 디렉토리 파일이 포함될 수 있으므로 해당 inode 번호는 디렉토리에 나열된 파일 중 하나입니다. 따라서 file이 있으면 /tmp/foo/bar디렉토리 파일에 foo해당 항목을 포함하고 bar해당 문자열을 해당 파일의 inode에 매핑합니다. 디렉토리 파일의 항목도 있습니다 /tmp디렉토리 파일, foo디렉토리 '에'입니다 /tmp.

mkdir (2)를 사용하여 디렉토리를 만들면 해당 함수

  1. 올바른 내부 구조로 디렉토리 파일 (일부 inode 번호)을 작성합니다.
  2. 새 디렉토리의 이름을이 새 inode (링크 중 하나를 설명)에 매핑하여 상위 디렉토리에 항목을 추가합니다.
  3. 문자열 '.'을 매핑하여 새 디렉토리에 항목을 추가합니다. 동일한 inode에 (이것은 다른 링크를 설명합니다)
  4. 새 디렉토리에 다른 항목을 추가하고 문자열 '..'을 2 단계에서 수정 한 디렉토리 파일의 inode에 매핑합니다 (하위 디렉토리를 포함하는 디렉토리 파일에서 볼 수있는 많은 수의 하드 링크를 설명 함) ).

최종 결과는 (거의) 유일한 특별한 경우입니다.

  • open (2) 함수는 쓰기 위해 디렉토리 파일을 열지 못하게하여 발에 쏠 수 없도록합니다.
  • mkdir (2) 함수는 새 디렉토리 파일에 몇 개의 추가 항목 ( '.'및 '..')을 추가하여 파일 시스템을 편리하게 이동할 수 있도록하여 편리하고 멋지게 만듭니다. 파일 시스템이 '.'없이 완벽하게 작동한다고 생각합니다. 그리고 '..'이지만 사용하기에는 고통 스러울 것입니다.
  • 디렉토리 파일은 '특별한'것으로 표시되는 몇 가지 유형의 파일 중 하나입니다. 이것은 실제로 open (2)와 같이 약간 다르게 동작하도록 지시하는 것입니다. st_modestat (2)를 참조하십시오 .

(스택 오버플로 원문 2011-10-20에서 복사 함)


1
블록을 inode와 혼동하고 있습니다. 짧은 파일의 경우 파일 내용 inode 내부에 있을 수 있지만 inode가 구조화되지 않았다고 주장하는 것은 거짓입니다. 그것들은 파일을 찾을 수있는 파일 이름을 제외하고 거의 모든 파일 메타 데이터를 포함하는 고도로 구조화되어 있습니다. inode는 파일 내용이있는 디스크의 블록에 대한 포인터 (직접, 간접, 이중 간접 등)를 포함합니다.
Phil P

1
아니요, 블록을 inode와 혼동하지 않습니다. inode는 블록 위에있는 추상화이며,이 게시물의 요점은 파일과 디렉토리 간의 관계와 그 내용을 설명하는 것이 었습니다. 모든 파일 시스템 구조는 디렉토리 파일에서 가져옵니다. 이미 inode 구현에 얽매이지 않고 충분히 길었습니다! (즉, 첫 두 단락을 더 명확하게 작성할 수 있음). 또한 보시다시피, 파일에 대한 모든 정보 (이름 제외)는 디렉토리 파일이 아니라 inode에 있다고 명시 적으로 언급합니다.
Norman Grey

@NormanGray : 자신을 변호하더라도 발로 쏴 버립니다. "파일 시스템에있는 파일의 모든 실제 내용이 inodes ...."라고 말했습니다. 잘못되었습니다.  파일의 속성 / 속성 (예 : 소유자, 권한, 수정 시간 등)이 inode에 저장됩니다. 일반 파일 의 내용 은 데이터 블록에 저장됩니다. inode 구현에서 혼란스러워하고 싶지 않다면 그렇게하지 말고 과도하게 단순화하지 마십시오.
G-Man
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.