Linux

BTRFS 如何獲取真實設備 ID

  • August 27, 2021

我正在監視文件操作事件 (VFS)。

我對 BTRFS 文件系統有問題,BTRFS 正在使用子卷,btrfs 中的所有最高層次目錄都具有相同的 inode (256/512)。

小故事:

當我收到文件操作事件時,我收到路徑,然後將其解析為 inode。

通過解決我的意思是:給定一個路徑,我得到它的dentry(user_path()呼叫),從dentry 我拉:dEntry->d_inode->i_ino

問題是我在同一設備上為不同目錄收到相同的inode。

我猜,BTRFS 有某種抽象層,它創建一個“虛擬”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

所以我得到 29 和 33 作為設備 ID。

讓我們將設備 ID 29 稱為“實際 ID”,而 33 是​​“虛擬 ID”。

有沒有辦法從核心程式碼中獲取實際 ID?

我正在尋找 dEntry->d_inode->i_sb->s_dev 的替代品。獲取與我們從使用者模式收到的相同的 id。

我在 Debian 7

而不是去dentry - inode - superblock - 設備ID。

我使用 dentry 上的 getattr(..) 獲取設備 ID。

我的解決方案取自主題中的 Suse 更新檔(經過大量Google探勘)。

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

這個問題基於一些常見的誤解,即 UNIX 文件系統類似於 MS-DOS 文件系統,因此每個塊設備只能有一個文件系統實例(意味著文件系統實例只能跨越一個塊設備),並且只有一個根目錄每個文件系統實例。

相反,Btrs 和 ZFS 都可以跨越多個塊設備,並且每個實例中都可以有多個文件系統根目錄。

UNIX 文件系統語義所要求的只是 device-id ( st_dev) 和 i-node 編號 ( st_ino) 在系統中唯一標識一個 inode。它們不要求 device-id 只對應一個塊設備或任何一個塊設備。因此,設備 IDstat報告是唯一有效的“實際”設備 ID,即使它不是塊設備的設備 ID。

事情稍微複雜一些,這篇博文中有更多細節。

引用自:https://unix.stackexchange.com/questions/345220