diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 16:53:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-17 16:53:16 -0400 |
commit | 74a205a3f1a07cf0b72bf7816d75735a0d9c4c6b (patch) | |
tree | d977fe81c74a0728130c7e212f2c27eef8146e91 /fs | |
parent | dd26bf6d95f050c42cc8f15e750b09851e1fd30b (diff) | |
parent | 912335c43bb10d124471bf063a85e132aa814214 (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.c | 4 | ||||
-rw-r--r-- | fs/sysfs/file.c | 16 |
2 files changed, 15 insertions, 5 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index f71559784bfb..aa763ab00777 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) | |||
648 | { | 648 | { |
649 | struct proc_mounts *p = file->private_data; | 649 | struct proc_mounts *p = file->private_data; |
650 | struct mnt_namespace *ns = p->ns; | 650 | struct mnt_namespace *ns = p->ns; |
651 | unsigned res = 0; | 651 | unsigned res = POLLIN | POLLRDNORM; |
652 | 652 | ||
653 | poll_wait(file, &ns->poll, wait); | 653 | poll_wait(file, &ns->poll, wait); |
654 | 654 | ||
655 | spin_lock(&vfsmount_lock); | 655 | spin_lock(&vfsmount_lock); |
656 | if (p->event != ns->event) { | 656 | if (p->event != ns->event) { |
657 | p->event = ns->event; | 657 | p->event = ns->event; |
658 | res = POLLERR; | 658 | res |= POLLERR | POLLPRI; |
659 | } | 659 | } |
660 | spin_unlock(&vfsmount_lock); | 660 | spin_unlock(&vfsmount_lock); |
661 | 661 | ||
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); |