I am monitoring file operations events (VFS).
I have a problem with BTRFS filesystem, BTRFS is using subvolumes, All highest hierarchy directories in btrfs has the same inode (256/512).

Short story:
When I receive file operation event, I receive the path and then resolve it to inode.
By resolving I mean: given a path, I get its dentry (user_path() call), from dentry i pull: dEntry->d_inode->i_ino
The problem is I receive same inode for different directories on the same Device.
I guess, BTRFS has some sort of abstraction layer, that create a "virtual" inode number (the identical ones are virtual) - there is no way for two identical inodes on same device id.

Proof for device id issue:

From kernel I receive device id 29:

Code: device id resolving: for a given path (/home) -> Get the dentry with user_path, then dEntry->d_inode->i_sb->s_dev OR I run command:

"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

From user space I receive device 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

So I get 29 and 33 as device id.
Lets call device id 29 "actual id"", and 33 is "virtual id".
Is there a way to obtain the actual id from kernel code ?
I am looking for replacement to dEntry->d_inode->i_sb->s_dev.. to obtain the same id as we receive from user mode.

I am on Debian 7

2 Answers 2


The question is based on some common misconceptions, that UNIX filesystems are like MS-DOS ones so that there can be only one filesystem instance per block device (implying that a filesystem instance can only span a single block device), and only one root directory per filesystem instance.

Instead Btrs and ZFS can both span multiple block devices and can have multiple filesystem root directories in each instance.

All that UNIX filesystem semantics require is that the device-id (st_dev) and the i-node number (st_ino) uniquely identify an inode across a system. They don't require that the device-id correspond to just one block device or to any one block device. So the device-id stat reports is the only valid "actual" device-id, even if it is not the device-id of a block device.

Things are slightly more complicated, more details in this blog post.


Instead of going to the dentry - inode - superblock - device id.
I get the device Id using the getattr(..) on the dentry.

My solution is taken from the Suse patch in the subject (after alot of google digging).


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .