BTRFS 如何獲取真實設備 ID
我正在監視文件操作事件 (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探勘)。
這個問題基於一些常見的誤解,即 UNIX 文件系統類似於 MS-DOS 文件系統,因此每個塊設備只能有一個文件系統實例(意味著文件系統實例只能跨越一個塊設備),並且只有一個根目錄每個文件系統實例。
相反,Btrs 和 ZFS 都可以跨越多個塊設備,並且每個實例中都可以有多個文件系統根目錄。
UNIX 文件系統語義所要求的只是 device-id (
st_dev
) 和 i-node 編號 (st_ino
) 在系統中唯一標識一個 inode。它們不要求 device-id 只對應一個塊設備或任何一個塊設備。因此,設備 IDstat
報告是唯一有效的“實際”設備 ID,即使它不是塊設備的設備 ID。事情稍微複雜一些,這篇博文中有更多細節。