I've seen lots of questions about getting a file's path from it's inode, but almost none about doing the reverse. My kernel module needs to do this to get further information about the subjects of requests passed to open()
, such as its file flags or whether or not it's a device. From what I was able to scrounge together from mailing lists, manual pages, and the Linux source code, I came up with this small function:
struct inode* get_inode_from_pathname(const char *pathname) {
struct path path;
kern_path(pathname, LOOKUP_FOLLOW, &path);
return path.dentry->d_inode;
}
Trying to use it in my replacement system call makes kernel messages get printed to the console, though:
struct inode *current_inode;
...
asmlinkage int custom_open(char const *__user file_name, int flags, int mode) {
current_inode = get_inode_from_pathname(file_name);
printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode);
printk(KERN_INFO "i_mode of %s:%hu\n", file_name, current_inode->i_mode);
return real_open(file_name, flags, mode);
}
Is there a better way to do this? I'm almost positive my way is wrong.
You can use the kern_path
kernel API to get the inode information from the path string. This function in turn calls the do_path_lookup()
function which performs the path look up operation. You can verify the results of the kern_path
function by printing the inode number (i_ino
field of the inode structure) of the inode you get from your get_inode_from_pathname
function and matching it with the inode number from an ls
command (ls -i <path of the file>
)
I made the following kernel module and it's not crashing the kernel. I am using 2.6.39 kernel.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <linux/namei.h>
char *path_name = "/home/shubham/test_prgs/temp.c";
int myinit(void)
{
struct inode *inode;
struct path path;
kern_path(path_name, LOOKUP_FOLLOW, &path);
inode = path.dentry->d_inode;
printk("Path name : %s, inode :%lu\n", path_name, inode->i_ino);
return 0;
}
void myexit(void)
{
return;
}
module_init(myinit);
module_exit(myexit);
//MODULE_AUTHOR("Shubham");
//MODULE_DESCRIPTION("Module to get inode from path");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
Can you send the crash stack trace?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With