aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/bin.c13
-rw-r--r--fs/sysfs/file.c16
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
179out_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
456void sysfs_notify_dirent(struct sysfs_dirent *sd) 456void 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
670static struct workqueue_struct *sysfs_workqueue;
670static DEFINE_MUTEX(sysfs_workq_mutex); 671static DEFINE_MUTEX(sysfs_workq_mutex);
671static LIST_HEAD(sysfs_workq); 672static LIST_HEAD(sysfs_workq);
672static void sysfs_schedule_callback_work(struct work_struct *work) 673static 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}
741EXPORT_SYMBOL_GPL(sysfs_schedule_callback); 751EXPORT_SYMBOL_GPL(sysfs_schedule_callback);