VFS(ファイルジョブイベント)を監視しています。
BTRFSファイルシステムに問題があります。 BTRFSはサブボリュームを使用し、btrfsのすべての最上位ディレクトリは同じinode(256/512)を持ちます。
短いストーリー:
ファイル操作イベントを受け取ったら、パスを受け取り、それをinodeに解析します。
解決するという意味は次のとおりです。パスが与えられたら、私がインポートするdentryからdentry(user_path()呼び出し)を取得します。 dEntry->d_inode->i_inoの
問題は、同じデバイスinodeの他のディレクトリから同じ内容を受け取ることです。
私の考えでは、BTRFSには「仮想」inode番号(同じinodeは仮想です)を生成する一種の抽象化階層があるようです。同じデバイスIDに2つの同じ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を取得します。
デバイスID29を「実ID」、33を「仮想ID」と呼ぶ。
カーネルコードから実際のIDを取得する方法はありますか?
dEntry->d_inode->i_sb->s_devの代替品を探しています。ユーザーモードで受信したのと同じIDを取得します。
私はDebian 7を使用しています
答え1
この質問は、いくつかの一般的な誤解、つまりUNIXファイルシステムがMS-DOSファイルシステムに似ているため、ブロックデバイスごとに1つのファイルシステムインスタンスしか存在できないという誤解です(ファイルシステムインスタンスは単一のブロックデバイスにしか存在しないことを意味します) )に基づいています。各ファイルシステムインスタンスにはルートディレクトリが1つしかありません。
これとは対照的に、BtrsとZFSは両方とも複数のブロックデバイスにまたがり、各インスタンス内に複数のファイルシステムルートを持つことができます。
すべてのUNIXファイルシステムセマンティクスで要求されるのは、デバイスID(st_dev
)とinode番号(st_ino
)がシステム全体でinodeを一意に識別することです。装置IDが1つのブロック装置または任意のブロック装置にのみ対応する必要はない。したがって、報告されたデバイスIDは、stat
ブロックデバイスのデバイスIDではなくても、唯一有効な「実際の」デバイスIDです。
状況は少し複雑で詳細に説明されています。このブログ投稿から。
答え2
代わりに、dentry-inode-superblock-device idにアクセスしてください。
私はデバイスIDを取得するためにdentryでgetattr(..)を使用します。
私の解決策はテーマのSuseパッチからもたらされました(多くのインターネット検索の後)。