Question

I've got some linux drivers I'm trying to port from linux 2.4 to 3.0. During this lengthy span of time, the argument list of ioctl (unlocked_ioctl now) changed a bit:

-static int can_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long can_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 

The code was using the inode to get the minor version and was passing it to some other commands. Now that inode isn't a "free-be" given in the ioctl parameter list, how can I get it?

Is it possible to derive from the file pointer? or should I "save" a global pointer to it when it shows up in the _open() method? I'd rather avoid that if there's a better way.

Was it helpful?

Solution 2

oop, just figured it out by poking around the kernel and looking at other drivers (don't know why it didn't occur to me to do that before). In case anyone else is interested you can get the inode from the file pointer passed into the ioctl as such:

long can_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    struct inode *inode = file->f_path.dentry->d_inode;

If anyone knows why this is a bad idea (I just took it from another driver), or if there's a better/preferred way let me know.

OTHER TIPS

You can get the inode from struct file * file in the kernel space. here is the brief struct map

file->f_path.d.dentry->d_inode; you can find the definition followed.

for dentry struct in dcache.h

struct dentry {
    atomic_t d_count;
    unsigned int d_flags;       /* protected by d_lock */
    spinlock_t d_lock;      /* per dentry lock */
    int d_mounted;
    struct inode *d_inode;      /* Where the name belongs to - NULL is
                                 * negative */
    /*
     * The next three fields are touched by __d_lookup.  Place them here
     * so they all fit in a cache line.
     */
    struct hlist_node d_hash;   /* lookup hash list */

for the file structure in fs.h

 file {
           /*  
            * fu_list becomes invalid after file_free is called and queued via
            * fu_rcuhead for RCU freeing
            */
           ...
           struct path             f_path;
           #define f_dentry        f_path.dentry
           #define f_vfsmnt        f_path.mnt
           const struct file_operations    *f_op;
           spinlock_t              f_lock;  /* f_ep_links, f_flags, no IRQ */
           #ifdef CONFIG_SMP
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top