Linux는 inode 기반이 아닌 파일 시스템에서 inode 번호를 어떻게 할당합니까?

Linux는 inode 기반이 아닌 파일 시스템에서 inode 번호를 어떻게 할당합니까?

ls -li이는 VFAT 파일 시스템에 대한 명령의 출력입니다.

% ls -li
合計 736
1207 drwxr-xr-x 3 root root  16384  3月 10 10:42 efi
1208 -rwxr-xr-x 1 root root 721720  3月 22 14:15 kernel.bin

12071208디렉토리와 파일의 inode 번호입니다 . 그러나 VFAT 파일 시스템에는 inode 개념이 없습니다.

Linux는 inode 개념이 없는 파일 시스템의 파일에 inode 번호를 어떻게 할당합니까?

답변1

tl;dr: 가상, 휘발성 또는 inode 독립적 파일 시스템의 경우 inode 번호는 일반적으로 inode가 생성될 때 단조롭게 증가하는 32비트 카운터에서 생성됩니다. 나머지 inode(예: 권한)는 기본 파일 시스템의 동등한 데이터에서 구축되거나 {uid,gid}=그러한 개념이 존재하지 않는 경우 설치 시 설정된 값(예:)으로 대체됩니다.


제목의 질문(즉, 추상적으로 Linux가 inode 개념이 없는 파일 시스템에 inode 번호를 할당하는 방법)에 대답하려면 파일 시스템에 따라 다릅니다. 일부 가상 또는 inodeless 파일 시스템의 경우 inode 번호는 get_next_ino인스턴스화 시 풀에서 가져옵니다. 그러나 여기에는 많은 문제가 있습니다.

  1. get_next_ino()32비트 inode 번호는 64비트 커널에서도 사용됩니다. 왜냐하면 전통적인 32비트 사용자 영역 처리는 그렇지 않기 때문입니다 _FILE_OFFSET_BITS=64.
  2. get_next_ino()여러 파일 시스템에서 사용되는 전역 증분 카운터이므로 오버플로 위험이 더욱 증가합니다.

이런 질문도 내 이유 중 하나야작년에 tmpfs는 get_next_ino가 지원하는 inode에서 멀어졌습니다..

따라서 tmpfs는 대부분의 휘발성 또는 "노드리스" 파일 시스템 형식에 대한 예외입니다. get_next_ino5.11부터 소켓, 파이프, 램프 등은 여전히 ​​이 풀을 사용합니다.


FAT 파일 시스템에 대한 구체적인 질문은 fs/fat/inode.cFAT 파일 시스템에 할당된 inode 번호는 어디에 있습니까? 내부를 살펴보면 fat_build_inode(원천):

struct inode *fat_build_inode(struct super_block *sb,
                              struct msdos_dir_entry *de, loff_t i_pos)
{
        struct inode *inode;
        int err;

        fat_lock_build_inode(MSDOS_SB(sb));
        inode = fat_iget(sb, i_pos);
        if (inode)
                goto out;
        inode = new_inode(sb);
        if (!inode) {
                inode = ERR_PTR(-ENOMEM);
                goto out;
        }
        inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
        inode_set_iversion(inode, 1);
        err = fat_fill_inode(inode, de);
        if (err) {
                iput(inode);
                inode = ERR_PTR(err);
                goto out;
        }
        fat_attach(inode, i_pos);
        insert_inode_hash(inode);
out:
        fat_unlock_build_inode(MSDOS_SB(sb));
        return inode;
}

이것은 기본적으로 다음과 같이 말합니다.

  1. 이 슈퍼블록에 대한 FAT inode 생성 잠금을 가져옵니다.
  2. 슈퍼블록의 이 위치에 인덱스 노드가 이미 존재하는지 확인합니다. 그렇다면 인덱스 노드가 잠금 해제되고 반환됩니다.
  3. 그렇지 않으면 새 인덱스 노드를 만듭니다.
  4. inode 번호를 가져옵니다 iunique(sb, MSDOS_ROOT_INO)(나중에 자세히 설명).
  5. 동등한 FAT 데이터 구조에서 나머지 inode를 채웁니다.

inode->i_ino = iunique(sb, MSDOS_ROOT_INO);여기서 inode 번호를 설정합니다. iunique(원천)는 주어진 슈퍼블록에 대해 고유한 inode 번호를 제공하는 파일 시스템 독립적인 함수입니다. 이는 슈퍼블록 + inode 기반 해시 테이블 및 단조롭게 증가하는 카운터를 사용하여 이를 수행합니다.

ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
        static DEFINE_SPINLOCK(iunique_lock);
        static unsigned int counter;
        ino_t res;

        rcu_read_lock();
        spin_lock(&iunique_lock);
        do {
                if (counter <= max_reserved)
                        counter = max_reserved + 1;
                res = counter++;
        } while (!test_inode_iunique(sb, res)); /* nb: this checks the hash table */
        spin_unlock(&iunique_lock);
        rcu_read_unlock();

        return res;
}

이 점에서 이는 이전에 언급한 것과 매우 유사합니다 get_next_ino. 전역(파이프, 소켓 등)이 아닌 슈퍼블록당, 기본 해시 테이블을 기반으로 하는 일부 충돌 방지 보호 기능이 있습니다. get_next_ino레거시 애플리케이션에서 EOVERFLOW를 시도하고 방지하기 위한 방법으로 32비트 inode 번호를 사용하는 동작 도 상속하므로 inode64앞으로는 64비트 inode 수정(앞서 언급한 tmpfs 구현과 같은)이 필요한 파일 시스템이 더 많아질 수 있습니다.

결론적으로:

  1. 대부분의 가상 또는 inodeless 파일 시스템은 단조롭게 증가하는 카운터를 사용하여 inode 번호를 나타냅니다.
  2. 이 카운터는 온디스크 노드리스 파일 시스템*의 경우에도 불안정합니다. 파일 시스템에 대한 다른 변경 없이 다시 마운트할 때 변경될 수 있습니다.
  3. 이 상태의 대부분의 파일 시스템( tmpfs 제외 inode64)은 여전히 ​​32비트 카운터를 사용하므로 과도하게 사용하면 카운터가 오버플로되어 중복 inode가 발생할 수 있습니다.

* ...공평하게 말하면 이는 다음 파일 시스템의 경우에도 계약상 적용됩니다.하다inode가 변경될 때 개념이 있습니다. i_generationinode 번호는 일반적으로 물리적 위치 또는 이와 유사한 것과 관련되어 있기 때문에 실제로는 발생할 가능성이 없습니다.

관련 정보