Getting file descriptors and details within kernel space without open()

Could anyone provide the code to overcome this problem?

Effectively how do we obtain the struct inode* from kernel level given the file /dev/driver1?

Given in user space that:

int fd;
fd = open("/dev/driver1", O_RDWR | O_SYNC);

In Kernel space:

static long dev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
struct dev_handle *handle;
handle = file->private_data;    

Assuming that, we do not go by that path,

How do we obtain within the kernel itself, by eg. hard coding the file->private_data to be given to handle?

Upvotes: 6

Views: 7979

Answers (2)

nos
nos

Reputation: 229108

Your code is in the dev_ioctl function ? If so, then

static long dev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
    struct dev_handle *handle;
    struct inode *inode;
    handle = file->private_data;    
    inode = file->f_inode;

There seems to be no sane documentation for locking requirements, so you should probably try to dig up similar code and see how it operates on the f_inode member.

Upvotes: 1

Valeri Atamaniouk
Valeri Atamaniouk

Reputation: 5163

You are looking for filp_open function. From file include/linux/fs.h:

struct file *filp_open(const char *filename, int flags, umode_t mode);

Here is a link to function source and documentation: http://lxr.free-electrons.com/source/fs/open.c#L937

If you really need FD, you can use sys_open (not exported in newer kernels):

long sys_open(const char __user *filename, int flags, int mode);

You can find a very good answer on a similar question: How to read/write files within a Linux kernel module?

Edit (how to get inode):

You can get cached inode from struct file:

struct file *file = ...;
struct inode *inode = file->inode;

If you want it with locking: here is a background: Documentation/filesystems/path-lookup.txt

The starting point for traversing is current->fs->root. There is a number of function in kernel, that already do the work, you can find them in fs/namei.c source file.

There is a function: kern_path:

int error;
struct inode *inode;
struct path path;

error = kern_path(pathname, LOOKUP_FOLLOW, &path);
if (error) ...;

inode = path.dentry->d_inode;

Upvotes: 2

Related Questions