lkml.org 
[lkml]   [2014]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/4] chardev: Increment cdev reference count when i_cdev references it
    Date
    Currently i_cdev reference to a character device isn't accounted in the
    reference count of the character device. This then requires us to track
    all references through a list of all inodes referencing a character
    device which is somewhat clumsy and requires list_head in each inode in
    the system.

    So make i_cdev a reference like any other.

    Signed-off-by: Jan Kara <jack@suse.cz>
    ---
    fs/char_dev.c | 12 +++++++++---
    1 file changed, 9 insertions(+), 3 deletions(-)

    diff --git a/fs/char_dev.c b/fs/char_dev.c
    index f77f7702fabe..21c210dbdba1 100644
    --- a/fs/char_dev.c
    +++ b/fs/char_dev.c
    @@ -388,12 +388,13 @@ static int chrdev_open(struct inode *inode, struct file *filp)
    we dropped the lock. */
    p = inode->i_cdev;
    if (!p) {
    + /* Use reference from kobj_lookup for i_cdev ref */
    inode->i_cdev = p = new;
    list_add(&inode->i_devices, &p->list);
    new = NULL;
    - } else if (!cdev_get(p))
    - ret = -ENXIO;
    - } else if (!cdev_get(p))
    + }
    + }
    + if (!cdev_get(p))
    ret = -ENXIO;
    spin_unlock(&cdev_lock);
    cdev_put(new);
    @@ -421,10 +422,15 @@ static int chrdev_open(struct inode *inode, struct file *filp)

    void cd_forget(struct inode *inode)
    {
    + struct cdev *cdev;
    +
    spin_lock(&cdev_lock);
    list_del_init(&inode->i_devices);
    + cdev = inode->i_cdev;
    inode->i_cdev = NULL;
    spin_unlock(&cdev_lock);
    + if (cdev)
    + cdev_put(cdev);
    }

    static void cdev_purge(struct cdev *cdev)
    --
    1.8.1.4


    \
     
     \ /
      Last update: 2014-10-22 22:41    [W:2.985 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site