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
1207
1208
디렉토리와 파일의 inode 번호입니다 . 그러나 VFAT 파일 시스템에는 inode 개념이 없습니다.
Linux는 inode 개념이 없는 파일 시스템의 파일에 inode 번호를 어떻게 할당합니까?
답변1
tl;dr: 가상, 휘발성 또는 inode 독립적 파일 시스템의 경우 inode 번호는 일반적으로 inode가 생성될 때 단조롭게 증가하는 32비트 카운터에서 생성됩니다. 나머지 inode(예: 권한)는 기본 파일 시스템의 동등한 데이터에서 구축되거나 {uid,gid}=
그러한 개념이 존재하지 않는 경우 설치 시 설정된 값(예:)으로 대체됩니다.
제목의 질문(즉, 추상적으로 Linux가 inode 개념이 없는 파일 시스템에 inode 번호를 할당하는 방법)에 대답하려면 파일 시스템에 따라 다릅니다. 일부 가상 또는 inodeless 파일 시스템의 경우 inode 번호는 get_next_ino
인스턴스화 시 풀에서 가져옵니다. 그러나 여기에는 많은 문제가 있습니다.
get_next_ino()
32비트 inode 번호는 64비트 커널에서도 사용됩니다. 왜냐하면 전통적인 32비트 사용자 영역 처리는 그렇지 않기 때문입니다_FILE_OFFSET_BITS=64
.get_next_ino()
여러 파일 시스템에서 사용되는 전역 증분 카운터이므로 오버플로 위험이 더욱 증가합니다.
이런 질문도 내 이유 중 하나야작년에 tmpfs는 get_next_ino가 지원하는 inode에서 멀어졌습니다..
따라서 tmpfs는 대부분의 휘발성 또는 "노드리스" 파일 시스템 형식에 대한 예외입니다. get_next_ino
5.11부터 소켓, 파이프, 램프 등은 여전히 이 풀을 사용합니다.
FAT 파일 시스템에 대한 구체적인 질문은 fs/fat/inode.c
FAT 파일 시스템에 할당된 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;
}
이것은 기본적으로 다음과 같이 말합니다.
- 이 슈퍼블록에 대한 FAT inode 생성 잠금을 가져옵니다.
- 슈퍼블록의 이 위치에 인덱스 노드가 이미 존재하는지 확인합니다. 그렇다면 인덱스 노드가 잠금 해제되고 반환됩니다.
- 그렇지 않으면 새 인덱스 노드를 만듭니다.
- inode 번호를 가져옵니다
iunique(sb, MSDOS_ROOT_INO)
(나중에 자세히 설명). - 동등한 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 구현과 같은)이 필요한 파일 시스템이 더 많아질 수 있습니다.
결론적으로:
- 대부분의 가상 또는 inodeless 파일 시스템은 단조롭게 증가하는 카운터를 사용하여 inode 번호를 나타냅니다.
- 이 카운터는 온디스크 노드리스 파일 시스템*의 경우에도 불안정합니다. 파일 시스템에 대한 다른 변경 없이 다시 마운트할 때 변경될 수 있습니다.
- 이 상태의 대부분의 파일 시스템( tmpfs 제외
inode64
)은 여전히 32비트 카운터를 사용하므로 과도하게 사용하면 카운터가 오버플로되어 중복 inode가 발생할 수 있습니다.
* ...공평하게 말하면 이는 다음 파일 시스템의 경우에도 계약상 적용됩니다.하다inode가 변경될 때 개념이 있습니다. i_generation
inode 번호는 일반적으로 물리적 위치 또는 이와 유사한 것과 관련되어 있기 때문에 실제로는 발생할 가능성이 없습니다.