summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-17 13:53:16 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-17 13:53:16 -0700
commit74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b (patch)
treed977fe81c74a0728130c7e212f2c27eef8146e91 /fs
parentdd26bf6d95f050c42cc8f15e750b09851e1fd30b (diff)
parent912335c43bb10d124471bf063a85e132aa814214 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: UIO: fix specific device driver missing statement for depmod Driver core: remove pr_fmt() from dynamic_dev_dbg() printk driver core: prevent device_for_each_child from oopsing dynamic debug: resurrect old pr_debug() semantics as pr_devel() Driver Core: early platform driver proc: mounts_poll() make consistent to mdstat_poll sysfs: sysfs poll keep the poll rule of regular file. driver core: allow non-root users to listen to uevents driver core: fix driver_match_device sysfs: don't use global workqueue in sysfs_schedule_callback()
Diffstat (limited to 'fs')
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/sysfs/file.c16
2 files changed, 15 insertions, 5 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f71559784bf..aa763ab0077 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -648,14 +648,14 @@ static unsigned mounts_poll(struct file *file, poll_table *wait)
{
struct proc_mounts *p = file->private_data;
struct mnt_namespace *ns = p->ns;
- unsigned res = 0;
+ unsigned res = POLLIN | POLLRDNORM;
poll_wait(file, &ns->poll, wait);
spin_lock(&vfsmount_lock);
if (p->event != ns->event) {
p->event = ns->event;
- res = POLLERR;
+ res |= POLLERR | POLLPRI;
}
spin_unlock(&vfsmount_lock);
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);