diff options
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/bin.c | 13 | ||||
| -rw-r--r-- | fs/sysfs/file.c | 16 | 
2 files changed, 16 insertions, 13 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 93e0c0281d4..9345806c885 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -157,14 +157,9 @@ static ssize_t write(struct file *file, const char __user *userbuf,  			count = size - offs;  	} -	temp = kmalloc(count, GFP_KERNEL); -	if (!temp) -		return -ENOMEM; - -	if (copy_from_user(temp, userbuf, count)) { -		count = -EFAULT; -		goto out_free; -	} +	temp = memdup_user(userbuf, count); +	if (IS_ERR(temp)) +		return PTR_ERR(temp);  	mutex_lock(&bb->mutex); @@ -176,8 +171,6 @@ static ssize_t write(struct file *file, const char __user *userbuf,  	if (count > 0)  		*off = offs + count; -out_free: -	kfree(temp);  	return count;  } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 289c43a4726..b1606e07b7a 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -446,11 +446,11 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)  	if (buffer->event != atomic_read(&od->event))  		goto trigger; -	return 0; +	return DEFAULT_POLLMASK;   trigger:  	buffer->needs_read_fill = 1; -	return POLLERR|POLLPRI; +	return DEFAULT_POLLMASK|POLLERR|POLLPRI;  }  void sysfs_notify_dirent(struct sysfs_dirent *sd) @@ -667,6 +667,7 @@ struct sysfs_schedule_callback_struct {  	struct work_struct	work;  }; +static struct workqueue_struct *sysfs_workqueue;  static DEFINE_MUTEX(sysfs_workq_mutex);  static LIST_HEAD(sysfs_workq);  static void sysfs_schedule_callback_work(struct work_struct *work) @@ -715,11 +716,20 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),  	mutex_lock(&sysfs_workq_mutex);  	list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)  		if (ss->kobj == kobj) { +			module_put(owner);  			mutex_unlock(&sysfs_workq_mutex);  			return -EAGAIN;  		}  	mutex_unlock(&sysfs_workq_mutex); +	if (sysfs_workqueue == NULL) { +		sysfs_workqueue = create_workqueue("sysfsd"); +		if (sysfs_workqueue == NULL) { +			module_put(owner); +			return -ENOMEM; +		} +	} +  	ss = kmalloc(sizeof(*ss), GFP_KERNEL);  	if (!ss) {  		module_put(owner); @@ -735,7 +745,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),  	mutex_lock(&sysfs_workq_mutex);  	list_add_tail(&ss->workq_list, &sysfs_workq);  	mutex_unlock(&sysfs_workq_mutex); -	schedule_work(&ss->work); +	queue_work(sysfs_workqueue, &ss->work);  	return 0;  }  EXPORT_SYMBOL_GPL(sysfs_schedule_callback);  | 
