LinuxKernel – use of “container_of” macro

Why and HOW should we use this API?

/* device information */
struct scull_dev *dev = container_of(inode->i_cdev, struct scull_dev, cdev);

How on earth do we get back “struct scull_dev” by this API????

int scull_open(struct inode *inode, struct file *filp)
{
    struct scull_dev *dev; /* device information */

    dev = container_of(inode->i_cdev, struct scull_dev, cdev);
    filp->private_data = dev; /* for other methods */

    /* now trim to 0 the length of the device if open was write-only */
    if ( (filp->f_flags & O_ACCMODE) =  = O_WRONLY) {
        scull_trim(dev); /* ignore errors */
    }
    return 0;          /* success */
}

See section 3.5.1 

Asked on October 10, 2019 in Linux.
Add Comment
1 Answer(s)
#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})

Look carefully into the macro. Well, seems simple

The macro calculates the offset of the field from the beginning of the structure
and returns the address of the (ptr+offset) after casting to the type (which is passed as 2nd parameter)

Answered on October 10, 2019.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.