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 93e0c0281d45..9345806c8853 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, | |||
157 | count = size - offs; | 157 | count = size - offs; |
158 | } | 158 | } |
159 | 159 | ||
160 | temp = kmalloc(count, GFP_KERNEL); | 160 | temp = memdup_user(userbuf, count); |
161 | if (!temp) | 161 | if (IS_ERR(temp)) |
162 | return -ENOMEM; | 162 | return PTR_ERR(temp); |
163 | |||
164 | if (copy_from_user(temp, userbuf, count)) { | ||
165 | count = -EFAULT; | ||
166 | goto out_free; | ||
167 | } | ||
168 | 163 | ||
169 | mutex_lock(&bb->mutex); | 164 | mutex_lock(&bb->mutex); |
170 | 165 | ||
@@ -176,8 +171,6 @@ static ssize_t write(struct file *file, const char __user *userbuf, | |||
176 | if (count > 0) | 171 | if (count > 0) |
177 | *off = offs + count; | 172 | *off = offs + count; |
178 | 173 | ||
179 | out_free: | ||
180 | kfree(temp); | ||
181 | return count; | 174 | return count; |
182 | } | 175 | } |
183 | 176 | ||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 289c43a47263..b1606e07b7a3 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) | |||
446 | if (buffer->event != atomic_read(&od->event)) | 446 | if (buffer->event != atomic_read(&od->event)) |
447 | goto trigger; | 447 | goto trigger; |
448 | 448 | ||
449 | return 0; | 449 | return DEFAULT_POLLMASK; |
450 | 450 | ||
451 | trigger: | 451 | trigger: |
452 | buffer->needs_read_fill = 1; | 452 | buffer->needs_read_fill = 1; |
453 | return POLLERR|POLLPRI; | 453 | return DEFAULT_POLLMASK|POLLERR|POLLPRI; |
454 | } | 454 | } |
455 | 455 | ||
456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) | 456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) |
@@ -667,6 +667,7 @@ struct sysfs_schedule_callback_struct { | |||
667 | struct work_struct work; | 667 | struct work_struct work; |
668 | }; | 668 | }; |
669 | 669 | ||
670 | static struct workqueue_struct *sysfs_workqueue; | ||
670 | static DEFINE_MUTEX(sysfs_workq_mutex); | 671 | static DEFINE_MUTEX(sysfs_workq_mutex); |
671 | static LIST_HEAD(sysfs_workq); | 672 | static LIST_HEAD(sysfs_workq); |
672 | static void sysfs_schedule_callback_work(struct work_struct *work) | 673 | static void sysfs_schedule_callback_work(struct work_struct *work) |
@@ -715,11 +716,20 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | |||
715 | mutex_lock(&sysfs_workq_mutex); | 716 | mutex_lock(&sysfs_workq_mutex); |
716 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) | 717 | list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) |
717 | if (ss->kobj == kobj) { | 718 | if (ss->kobj == kobj) { |
719 | module_put(owner); | ||
718 | mutex_unlock(&sysfs_workq_mutex); | 720 | mutex_unlock(&sysfs_workq_mutex); |
719 | return -EAGAIN; | 721 | return -EAGAIN; |
720 | } | 722 | } |
721 | mutex_unlock(&sysfs_workq_mutex); | 723 | mutex_unlock(&sysfs_workq_mutex); |
722 | 724 | ||
725 | if (sysfs_workqueue == NULL) { | ||
726 | sysfs_workqueue = create_workqueue("sysfsd"); | ||
727 | if (sysfs_workqueue == NULL) { | ||
728 | module_put(owner); | ||
729 | return -ENOMEM; | ||
730 | } | ||
731 | } | ||
732 | |||
723 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | 733 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); |
724 | if (!ss) { | 734 | if (!ss) { |
725 | module_put(owner); | 735 | module_put(owner); |
@@ -735,7 +745,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | |||
735 | mutex_lock(&sysfs_workq_mutex); | 745 | mutex_lock(&sysfs_workq_mutex); |
736 | list_add_tail(&ss->workq_list, &sysfs_workq); | 746 | list_add_tail(&ss->workq_list, &sysfs_workq); |
737 | mutex_unlock(&sysfs_workq_mutex); | 747 | mutex_unlock(&sysfs_workq_mutex); |
738 | schedule_work(&ss->work); | 748 | queue_work(sysfs_workqueue, &ss->work); |
739 | return 0; | 749 | return 0; |
740 | } | 750 | } |
741 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | 751 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); |