1

So, the problem is: I've got a block device, for example, /dev/sdd1, containing a filesystem, e.g. EXT3 or XFS, mounted under /mnt/testdisk.

There's also a file, /mnt/testdisk/somefile.bin.

What I want, is to get which device that file is on, in this case, "/dev/sdd1". And, to make the matters worse, I have to do it in both userspace and kernel module (It's a linux driver. It doesn't have to be portable).

In userspace: my current attempt is to open

/proc/mounts

and parse it line-by-line to find the best match for the pathname. It works, but I think there's must be a better way...

In kernel driver: I'm trying to open the file, "/mnt/testdisk/somefile.bin", using filp_open from linux/fs.h header.

struct file *testfile;
struct inode *inode;
testfile = filp_open("/mnt/testdisk/somefile.bin", (O_RDWR | O_LARGEFILE), OP_FLAGS);
inode = testfile->f_mapping->host;

however, for some reason

inode->i_bdev == NULL

so I can't extract block device path from that :(

I know that theoretically it's a bad thing to open files from kernelspace, but yeah, whatever, don't care.

So, for each case, what's the best way to solve that conundrum?

user2864740
  • 60,010
  • 15
  • 145
  • 220
user905747
  • 613
  • 1
  • 9
  • 18
  • I have a similar problem here - https://stackoverflow.com/q/72219414/1569204 with a horrible script as the answer https://stackoverflow.com/a/72219415/1569204 . There must be a better way. – Bruce Adams May 12 '22 at 17:05

2 Answers2

0

I think you are on the right way in the userspace by accessing /proc/mounts.

However you can not access userpace directories from kernel space (eg. /mnt/...). I suggest you take a look at how the kernel populates /proc/mount and use that as a starting point for implementing your functionality.

Take a look at the kernel source, that would be proc_namespace.c for you. Take a look at the show_vfsstat function.

Ortwin Angermeier
  • 5,957
  • 2
  • 34
  • 34
0

For the userspace portion, I would strace df -h:

df -h /mnt/testdisk/somefile.bin

And for the kernel portion, you can get the struct block_device by using the following:

struct file *testfile;
struct block_device *bdev;

testfile = filp_open("/mnt/testdisk/somefile.bin", (O_RDWR | O_LARGEFILE), OP_FLAGS);
bdev = testfile->f_inode->i_sb->s_bdev;

There is also a related question here.

jedix
  • 41
  • 2