BTRFS는 실제 장치 ID를 어떻게 얻습니까?

BTRFS는 실제 장치 ID를 어떻게 얻습니까?

VFS(파일 작업 이벤트)를 모니터링하고 있습니다.
BTRFS 파일 시스템에 문제가 있습니다. BTRFS는 하위 볼륨을 사용하고 btrfs의 모든 최상위 디렉터리는 동일한 inode(256/512)를 갖습니다.

짧은 이야기:
파일 작업 이벤트를 받으면 경로를 수신하고 이를 inode로 구문 분석합니다.
해결한다는 의미는 다음과 같습니다. 경로가 주어지면 내가 가져오는 dentry에서 dentry(user_path() 호출)를 얻습니다. dEntry->d_inode->i_ino
문제는 동일한 장치 inode의 다른 디렉터리에서 동일한 내용을 수신한다는 것입니다.
내 생각에 BTRFS에는 "가상" inode 번호(동일한 inode는 가상임)를 생성하는 일종의 추상화 계층이 있는 것 같습니다. 동일한 장치 ID에 두 개의 동일한 inode를 갖는 것은 불가능합니다.

장치 ID 문제 증명:

커널로부터 장치 ID 29를 받았습니다.

코드: 장치 ID 확인: 지정된 경로(/home)에 대해 -> user_path를 사용하여 dentry를 가져온 다음 dEntry->d_inode->i_sb->s_dev 또는 다음 명령을 실행합니다.

"grep btrfs /proc/self/mountinfo | less"

산출:

/proc/self/mountinfo return inode 29 also: 34 18 0:29 /home /home rw,noatime,nodiratime shared:19 - btrfs /dev/md127 rw,nospace_cache,subvolid=257,subvol=/home

사용자 공간에서 장치 ID 33을 받습니다.

root@nas-B9-43-AA:/# stat /home
  File: `/home'
  Size: 90              Blocks: 0          IO Block: 4096   directory
Device: 21h/33d Inode: 256         Links: 1

root@nas-B9-43-AA:/# mountpoint -d /home
0:33

그래서 장치 ID로 29와 33을 얻습니다.
장치 ID 29를 "실제 ID", 33을 "가상 ID"라고 부르겠습니다.
커널 코드에서 실제 ID를 얻는 방법이 있습니까?
dEntry->d_inode->i_sb->s_dev의 대체품을 찾고 있습니다. 사용자 모드에서 받은 것과 동일한 ID를 가져옵니다.

나는 데비안 7을 사용하고 있습니다

답변1

이 질문은 몇 가지 일반적인 오해, 즉 UNIX 파일 시스템이 MS-DOS 파일 시스템과 유사하므로 블록 장치당 하나의 파일 시스템 인스턴스만 있을 수 있다는 오해(파일 시스템 인스턴스는 단일 블록 장치에만 걸쳐 있을 수 있음을 의미함)에 근거합니다. 각 파일 시스템 인스턴스에는 루트 디렉터리가 하나만 있을 수 있습니다.

이와 대조적으로 Btrs와 ZFS는 모두 여러 블록 장치에 걸쳐 있을 수 있으며 각 인스턴스 내에 여러 파일 시스템 루트가 있을 수 있습니다.

모든 UNIX 파일 시스템 의미 체계에서 요구하는 것은 장치 ID( st_dev)와 inode 번호( st_ino)가 시스템 전체에서 inode를 고유하게 식별한다는 것입니다. 장치 ID가 하나의 블록 장치 또는 임의의 블록 장치에만 해당할 필요는 없습니다. 따라서 보고된 장치 ID는 stat블록 장치의 장치 ID가 아니더라도 유일하게 유효한 "실제" 장치 ID입니다.

상황이 조금 더 복잡하고 더 자세히 설명되어 있습니다.이 블로그 게시물에서.

답변2

대신 dentry-inode-superblock-device id로 이동하세요.
나는 장치 ID를 얻기 위해 dentry에서 getattr(..)을 사용합니다.

내 솔루션은 테마의 Suse 패치에서 가져왔습니다(많은 인터넷 검색 후).

https://patchwork.kernel.org/patch/2825842/

관련 정보