디렉터리 크기가 다른 파일과 다르게 보고되는 이유는 무엇입니까?

디렉터리 크기가 다른 파일과 다르게 보고되는 이유는 무엇입니까?

빈 디렉토리가 왜 4096바이트의 공간을 차지하는지 알고 싶습니다.이것질문. 공간이 블록 단위로 할당된다고 하니 새 디렉터리의 크기는 4096바이트다.

그러나 "일반" 파일의 할당도 블록 단위로 수행된다고 확신합니다. 적어도 그렇죠윈도우 파일 시스템적어도 ext*에서는 비슷해야 한다고 생각합니다.

이제 내가 이해한 바에 따르면 다른 유형의 파일(예: 파일, 심볼릭 링크 등)에 대한 크기 목록은 실제 크기를 기준으로 수행됩니다. 빈 파일을 생성하면 크기가 0으로 표시되기 때문입니다. 몇 글자를 입력하면 <문자 수>바이트가 크기 등으로 표시됩니다.

그래서 내 질문은 다른 파일의 할당도 블록 단위로 수행되지만 보고 디렉터리 및 파일 크기에 대한 정책은 왜 다른가요?입니다.

밝히다

나는 그 질문이 충분히 명확하다고 생각했지만 분명히 그렇지 않았습니다. 나는 여기서 문제를 명확히하려고 노력할 것입니다.

1) 내가 생각하는 디렉토리는 무엇입니까?

다음 예를 통해 디렉토리에 대한 나의 이해를 설명하려고 합니다. 읽어보신 후 틀린 부분이 있으면 알려주세요.

이라는 디렉터리가 있다고 가정해 보겠습니다 mydir. f0, f1및 3개의 파일이 포함되어 있다고 가정합니다 f2. 각 파일의 길이가 1바이트라고 가정합니다.

자, 무엇입니까 mydir? 이는 문자열 "f0"과 f0지정된 inode 번호 등의 내용을 포함하는 inode에 대한 포인터입니다 . 문자열 "f1"과 f1그것이 가리키는 inode 번호. 문자열 "f2"와 f2inode 번호가 가리킵니다. (적어도 제가 생각하는 디렉토리는 그렇습니다. 제가 틀렸다면 정정해 주십시오.)

이제 디렉터리 크기를 계산하는 방법에는 두 가지가 있습니다.

mydir1) 지적된 inode의 크기를 계산합니다.

2) 콘텐츠가 가리키는 인덱스 노드의 크기를 합산합니다 mydir.

1이 더 직관에 어긋나더라도 이것이 사용되는 방법이라고 가정합니다. (이 문제에서는 실제로 어떤 방법을 사용하는지는 중요하지 않습니다.) 그러면 의 크기는 mydir다음과 같이 계산됩니다.

2 + 2 + 2 + 3 * <space_required_to_store_an_inode_number>

2는 각 파일 이름의 길이가 2바이트이기 때문입니다.

2) 질문:

이제 문제는 디렉토리가 정확하다고 생각한다고 가정할 때 mydir방법 1을 사용하든 방법 2를 사용하여 크기를 계산하든 보고된 크기는 4096보다 훨씬 작아야 한다는 것입니다.

이제 4096바이트가 보고되는 이유는 할당이 블록 단위로 이루어지기 때문이라고 말할 수 있습니다. 따라서 보고된 크기가 너무 큽니다.

하지만 다음에 말씀드리자면, 일반 파일의 경우 할당도 블록 단위로 이루어집니다. (바라보다트리거의 답변참고) 그럼에도 불구하고 해당 치수는 실제 치수로 보고됩니다. (1개의 문자가 포함된 경우 1바이트, 2개의 문자가 포함된 경우 2바이트 등)

그래서 내 질문은 정책 보고 디렉터리 크기가 정책 보고 일반 파일 크기와 왜 그렇게 다른가 하는 것입니다.

추가 지침:

비어 있지 않은 파일과 빈 디렉터리에 할당된 초기 블록 수는 8블록이라는 것을 알고 있습니다. (바라보다트리거의 답변) 그러면 일반 파일과 디렉터리에 동일한 수의 블록이 할당되었음에도 불구하고 보고된 디렉터리 크기가 훨씬 더 큰 이유는 무엇입니까?

답변1

내 생각에 당신이 혼란스러워하는 이유는 디렉토리가 무엇인지 모르기 때문이라고 생각합니다.. 이를 위해 한 걸음 물러서서 Unix 파일 시스템이 어떻게 작동하는지 살펴보겠습니다.

Unix 파일 시스템은 몇 개입니까?분리디스크의 데이터 주소 지정 개념:

  • 데이터 블록디스크에 있는 블록의 집합입니다.콘텐츠파일의.
  • 인덱스 노드다음과 같은 파일에 대한 메타데이터를 포함하는 해당 파일 시스템 내의 고유한 숫자 주소를 가진 파일 시스템의 특수 블록입니다.
    • 권한
    • 접근/수정 시간
    • 크기
    • 데이터 블록에 대한 포인터(블록, 범위 등의 목록일 수 있음)
  • 파일 이름inode에 매핑된 파일 시스템 루트의 계층적 위치입니다.

즉, "파일"은 실제로 다음 세 가지로 구성됩니다.

  1. 파일 시스템의 PATH
  2. 메타데이터가 있는 인덱스 노드
  3. inode가 가리키는 데이터 블록

대부분의 경우 사용자는 파일을 "파일 이름과 관련된 엔터티"의 동의어로 생각합니다. 이는 낮은 수준 엔터티나 파일/소켓 API를 다룰 때만 inode나 데이터 블록을 생각하는 경우입니다. 디렉터리는 이러한 하위 수준 엔터티 중 하나입니다.

디렉토리는 여러 개의 다른 파일을 포함하는 파일로 생각할 수 있습니다. 이것은 절반만 사실입니다. 디렉토리는 파일 이름을 inode 번호에 매핑하는 파일입니다. 파일을 "포함"하지는 않지만 파일 이름에 대한 포인터입니다. 다음과 같은 항목이 포함된 텍스트 파일이라고 생각하세요.

  • . - 인덱스 노드 1234
  • .. - 아이노드 200
  • 문서 - Inode 2008
  • README.txt - 아이노드 2009

위 항목의 이름은 다음과 같습니다.디렉토리 항목. 기본적으로 파일 이름에서 inode 번호로의 매핑입니다. 디렉토리는 디렉토리 항목을 포함하는 특수 파일입니다.

물론 이는 단순화된 것이지만 기본 아이디어와 기타 디렉토리의 특이한 점을 설명합니다.

  • 디렉토리가 자체 크기를 모르는 이유는 무엇입니까?
    • 여기에는 다른 콘텐츠에 대한 포인터만 포함되어 있으므로 해당 콘텐츠를 반복하여 크기를 찾아야 합니다.
  • 디렉토리가 결코 비어 있지 않은 이유는 무엇입니까?
    • 최소한 . 및 .. 항목이 포함되어 있기 때문입니다. 따라서 올바른 디렉터리는 최소한 이러한 항목을 포함할 수 있는 가장 작은 파일 크기만큼 작아야 합니다. 대부분의 파일 시스템에서는 최소 4096바이트입니다.
  • 파일 이름을 바꿀 때 상위 디렉터리에 대한 쓰기 권한이 필요한 이유는 무엇입니까?
    • 파일을 변경할 뿐만 아니라 파일을 가리키는 디렉토리 항목도 변경하기 때문입니다.
  • ls가 디렉토리에 대해 이상한 수의 "링크"를 표시하는 이유는 무엇입니까?
    • 디렉토리는 그 자체, 상위 디렉토리 및 하위 디렉토리에 의해 참조(링크)될 수 있습니다.
  • 하드 링크의 기능은 무엇이며 심볼릭 링크와 어떻게 다릅니까?
    • 하드 링크가 추가되었습니다디렉토리 항목동일한 inode 번호를 가리킵니다. inode 번호를 가리키기 때문에 동일한 파일 시스템의 파일만 가리킬 수 있습니다(inode는 파일 시스템에 대해 로컬임).
    • 기호 링크는 별도의 파일 이름을 가리키는 새 inode를 추가합니다. 파일 이름을 참조하므로 트리의 모든 파일을 가리킬 수 있습니다.

하지만 기다려! 이상한 일들이 일어나고 있습니다!

ls -ld somedirectoryls -l somefile파일 크기는 파일의 실제 크기 대신 항상 4096으로 표시됩니다 . 왜?

혼란스러운 점 1: "크기"라고 하면 다음 두 가지를 의미할 수 있습니다.

  • inode에 저장된 파일 크기
  • 할당 크기는 inode와 관련된 블록 수에 각 블록 크기를 곱한 값입니다.

일반적으로 말하면, 같은 숫자가 아닙니다. 뛰어 stat들어 보세요정기적인파일을 보면 이 차이점을 볼 수 있습니다.

파일 시스템이 비어 있지 않은 파일을 생성할 때 일반적으로 데이터 블록을 그룹으로 할당합니다. 이는 파일이 빠른 속도로 늘어나거나 줄어드는 경향이 있기 때문입니다. 파일 시스템이 파일을 표현하는 데 필요한 만큼의 데이터 블록만 할당하면 증가/축소가 느려지고 조각화가 심각한 문제가 됩니다. 따라서 실제로 파일 시스템은 작은 변경 사항을 위해 공간을 재할당할 필요가 없습니다. 이는 디스크에 파일이 "점유"했지만 완전히 사용되지 않는 공간이 많이 있을 수 있음을 의미합니다.

파일 시스템은 이 모든 사용되지 않은 공간을 어떻게 처리합니까? 아무것도 없습니다. 필요성을 느낄 때까지. 파일 시스템 최적화 도구(백그라운드에서 실행되는 온라인 최적화 도구, fsck의 일부일 수도 있고 파일 시스템 자체에 내장되어 있을 수도 있음)가 이와 같이 느껴진다면 파일의 데이터 블록을 재할당할 수 있습니다. 이동 시 블록이 사용되어 사용되지 않은 블록이 해제됩니다. 블록 등

이제 일반 파일과 디렉터리의 차이점을 살펴보겠습니다. 디렉터리는 파일 시스템의 "백본"을 형성하기 때문에 자주 액세스하거나 수정해야 할 수 있으므로 최적화해야 한다고 예상할 수 있습니다. 그래서 당신은 그들이 전혀 무너지는 것을 원하지 않습니다. 디렉토리가 생성되면 항상최대 출력디렉토리 항목이 너무 많아도 모든 데이터 블록의 크기는 동일합니다. 파일과 달리 디렉토리는 일반적으로 크기와 증가율이 제한되어 있으므로 디렉토리의 경우에는 괜찮습니다.

4096 보고된 디렉터리 크기는 디렉터리의 항목 수가 아니라 디렉터리 inode에 저장된 "파일 크기" 숫자입니다. 이는 고정된 숫자가 아닙니다. 디렉터리에 할당된 블록 수에 맞는 최대 바이트 수입니다. 일반적으로 이는 모든 콘텐츠가 포함된 파일에 할당된 512바이트/블록 x 8블록입니다. 그런데 디렉터리의 경우 파일 크기와 할당 크기는 동일합니다. 단일 그룹으로 할당되므로 파일 시스템 최적화 프로그램은 해당 블록을 이동하지 않습니다.

디렉토리가 커짐에 따라 더 많은 데이터 블록이 할당되고최대 출력그에 따라 파일 크기를 조정하여 이러한 블록을 차단합니다.

따라서 할당된 데이터 블록의 크기로 설정된 디렉토리 inode에 대한 파일 크기 필드를 표시합니다 ls.stat

답변2

초기 빈 디렉토리 크기는 파일 시스템에 따라 다르다고 생각합니다. 또한 액세스 권한이 있는 ext3 및 ext4 파일 시스템에서 4096바이트의 빈 디렉토리를 얻습니다. 일종의 NFS 마운트 NAS에서는 80바이트의 빈 디렉토리가 나타납니다. ReiserFS 파일 시스템에 대한 액세스 권한이 없으며 새로 생성된 빈 디렉토리의 크기가 흥미로울 것입니다.

전통적으로 디렉토리는 해당 inode(파일을 설명하는 디스크 구조)에 디렉토리임을 나타내는 비트가 설정된 파일입니다. 파일은 가변 길이 레코드로 채워집니다. 내용은 다음과 같습니다 /usr/include/linux/dirent.h.

struct dirent64 {
    __u64       d_ino;
    __s64       d_off;
    unsigned short  d_reclen;
    unsigned char   d_type;
    char        d_name[256];
};

이 값을 사용하여 카탈로그 파일 항목을 건너뛸 수 있습니다 d_off. 항목이 삭제되면( 명령에서 사용되는 unlink()시스템 호출 ) 누락된 레코드를 설명하기 위해 이전 항목의 값이 증가됩니다. 어떤 레코드도 "압축"되지 않습니다. 가장 간단한 접근 방식은 디렉토리 파일의 모든 항목이 몇 바이트를 차지하고 있는지 알아보거나 단순히 알아내는 대신 파일에 할당된 디스크 블록의 바이트 수를 기준으로 할당을 표시하는 것입니다. 디렉토리 파일에 몇 바이트가 있습니까? 마지막 항목.rmd_off

오늘날 디렉토리에는 B-트리 또는해시 트리. 블록 단위로 디렉터리를 생성하는 것이 성능이 크게 향상되거나 기존 디렉터리와 비슷하게 내부에 "빈 공간"이 있어서 디렉터리의 "실제 크기"(바이트)를 결정하기가 어렵다고 생각합니다. . 한동안 사용되어 왔으며 많은 파일이 제거되고 추가된 것입니다. 블록 수에 블록당 바이트 수를 곱하여 표시하는 것이 더 쉽습니다.

답변3

파일에는 할당된 블록이 없을 수 있습니다. 플래그는 -s이러한 ls차이를 표시하는 반면, 디렉토리에는 특정 수의 최소 블록이 할당되어 기본 크기가 됩니다. (이러한 개념을 창 밖으로 던지는 멋진 최신 파일 시스템을 사용하지 않는 한) 예를 들면 다음과 같습니다.

% mkdir testfoo
% cd testfoo/
% mkdir foodir
% touch foofile
% ln -s foofile foosln
% ls -ld foo*
drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
-rw-rw-r--  1 jmates  jmates    0 Oct  5 19:48 foofile
lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
% ls -lds foo*
8 drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
0 -rw-rw-r--  1 jmates  jmates    0 Oct  5 19:48 foofile
0 lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
% 

필요한 세부 정보를 저장하기 위해 7바이트가 할당되어 있지만 여기의 기호 링크는 어떤 블록도 차지하지 않습니다. readlink(2)정말 호기심이 많습니다! 어쨌든 이제 foofile1~2바이트를 채워 보겠습니다 .

% echo >> foofile a
% ls -lds foo*
8 drwxrwxr-x  2 jmates  jmates  512 Oct  5 19:48 foodir
8 -rw-rw-r--  1 jmates  jmates    2 Oct  5 19:49 foofile
0 lrwxrwxr-x  1 jmates  jmates    7 Oct  5 19:48 foosln -> foofile
%

할당된 블록이 2바이트(추가 및 개행 문자 ) 만큼만 foofile점프된 것을 볼 수 있습니다 .8aecho

파일이 희소할 수도 있습니다. 이는 파일과 상호 작용하는 도구가 희소성을 처리하는 방식에 따라 보고된 파일 크기가 실제 콘텐츠와 다를 수 있다는 또 다른 이유입니다.

또한 디렉터리 크기를 늘리고, 매우 긴 이름을 가진 많은 파일을 생성하고, 각각의 새로운 긴 파일 이름이 생성된 후 디렉터리(및 할당된 블록)의 크기에 어떤 일이 발생하는지 확인할 수 있습니다.ls -lds .

관련 정보