Commit 427ac533 authored by Maneesh Soni's avatar Maneesh Soni Committed by Greg Kroah-Hartman

[PATCH] kobject/sysfs race fix

The following patch fixes the race involved between unregistering a kobject
and simultaneously opeing a corresponding attribute file in sysfs.

Ideally sysfs should take a ref.  to the kobject as long as it has dentries
referring to the kobjects, but because of current limitations in
module/kobject ref counting, sysfs's pinning of kobject leads to
hang/delays in rmmod of certain modules.  The patch checks for unhashed
dentries in check_perm() while opening a sysfs file.  If the dentry is
still hashed then it goes ahead and takes the ref to kobject.  This done
under the per dentry lock.  It does this in the inline routine
sysfs_get_kobject(dentry).
parent 8bcb3f98
......@@ -94,7 +94,7 @@ static ssize_t write(struct file * file, const char __user * userbuf,
static int open(struct inode * inode, struct file * file)
{
struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
struct bin_attribute * attr = file->f_dentry->d_fsdata;
int error = -EINVAL;
......
......@@ -238,7 +238,7 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
static int check_perm(struct inode * inode, struct file * file)
{
struct kobject * kobj = kobject_get(file->f_dentry->d_parent->d_fsdata);
struct kobject *kobj = sysfs_get_kobject(file->f_dentry->d_parent);
struct attribute * attr = file->f_dentry->d_fsdata;
struct sysfs_buffer * buffer;
struct sysfs_ops * ops = NULL;
......
......@@ -11,3 +11,16 @@ extern void sysfs_hash_and_remove(struct dentry * dir, const char * name);
extern int sysfs_create_subdir(struct kobject *, const char *, struct dentry **);
extern void sysfs_remove_subdir(struct dentry *);
static inline struct kobject *sysfs_get_kobject(struct dentry *dentry)
{
struct kobject * kobj = NULL;
spin_lock(&dentry->d_lock);
if (!d_unhashed(dentry))
kobj = kobject_get(dentry->d_fsdata);
spin_unlock(&dentry->d_lock);
return kobj;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment