diff options
-rw-r--r-- | fs/sysfs/dir.c | 1 | ||||
-rw-r--r-- | fs/sysfs/file.c | 31 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 15 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 6 | ||||
-rw-r--r-- | include/linux/sysfs.h | 27 |
5 files changed, 62 insertions, 18 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index aedaeba82ae5..53bc7fc31af3 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -636,6 +636,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | |||
636 | 636 | ||
637 | return sd; | 637 | return sd; |
638 | } | 638 | } |
639 | EXPORT_SYMBOL_GPL(sysfs_get_dirent); | ||
639 | 640 | ||
640 | static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | 641 | static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, |
641 | const char *name, struct sysfs_dirent **p_sd) | 642 | const char *name, struct sysfs_dirent **p_sd) |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index ce8339c70a4b..d0d79e6b6d11 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -453,6 +453,22 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | |||
453 | return POLLERR|POLLPRI; | 453 | return POLLERR|POLLPRI; |
454 | } | 454 | } |
455 | 455 | ||
456 | void sysfs_notify_dirent(struct sysfs_dirent *sd) | ||
457 | { | ||
458 | struct sysfs_open_dirent *od; | ||
459 | |||
460 | spin_lock(&sysfs_open_dirent_lock); | ||
461 | |||
462 | od = sd->s_attr.open; | ||
463 | if (od) { | ||
464 | atomic_inc(&od->event); | ||
465 | wake_up_interruptible(&od->poll); | ||
466 | } | ||
467 | |||
468 | spin_unlock(&sysfs_open_dirent_lock); | ||
469 | } | ||
470 | EXPORT_SYMBOL_GPL(sysfs_notify_dirent); | ||
471 | |||
456 | void sysfs_notify(struct kobject *k, char *dir, char *attr) | 472 | void sysfs_notify(struct kobject *k, char *dir, char *attr) |
457 | { | 473 | { |
458 | struct sysfs_dirent *sd = k->sd; | 474 | struct sysfs_dirent *sd = k->sd; |
@@ -463,19 +479,8 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr) | |||
463 | sd = sysfs_find_dirent(sd, dir); | 479 | sd = sysfs_find_dirent(sd, dir); |
464 | if (sd && attr) | 480 | if (sd && attr) |
465 | sd = sysfs_find_dirent(sd, attr); | 481 | sd = sysfs_find_dirent(sd, attr); |
466 | if (sd) { | 482 | if (sd) |
467 | struct sysfs_open_dirent *od; | 483 | sysfs_notify_dirent(sd); |
468 | |||
469 | spin_lock(&sysfs_open_dirent_lock); | ||
470 | |||
471 | od = sd->s_attr.open; | ||
472 | if (od) { | ||
473 | atomic_inc(&od->event); | ||
474 | wake_up_interruptible(&od->poll); | ||
475 | } | ||
476 | |||
477 | spin_unlock(&sysfs_open_dirent_lock); | ||
478 | } | ||
479 | 484 | ||
480 | mutex_unlock(&sysfs_mutex); | 485 | mutex_unlock(&sysfs_mutex); |
481 | } | 486 | } |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 14f0023984d7..ab343e371d64 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mount.h> | 16 | #include <linux/mount.h> |
17 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/module.h> | ||
19 | 20 | ||
20 | #include "sysfs.h" | 21 | #include "sysfs.h" |
21 | 22 | ||
@@ -115,3 +116,17 @@ out_err: | |||
115 | sysfs_dir_cachep = NULL; | 116 | sysfs_dir_cachep = NULL; |
116 | goto out; | 117 | goto out; |
117 | } | 118 | } |
119 | |||
120 | #undef sysfs_get | ||
121 | struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) | ||
122 | { | ||
123 | return __sysfs_get(sd); | ||
124 | } | ||
125 | EXPORT_SYMBOL_GPL(sysfs_get); | ||
126 | |||
127 | #undef sysfs_put | ||
128 | void sysfs_put(struct sysfs_dirent *sd) | ||
129 | { | ||
130 | __sysfs_put(sd); | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(sysfs_put); | ||
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index a5db496f71c7..93c6d6b27c4d 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -124,7 +124,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, | |||
124 | struct sysfs_dirent **p_sd); | 124 | struct sysfs_dirent **p_sd); |
125 | void sysfs_remove_subdir(struct sysfs_dirent *sd); | 125 | void sysfs_remove_subdir(struct sysfs_dirent *sd); |
126 | 126 | ||
127 | static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) | 127 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) |
128 | { | 128 | { |
129 | if (sd) { | 129 | if (sd) { |
130 | WARN_ON(!atomic_read(&sd->s_count)); | 130 | WARN_ON(!atomic_read(&sd->s_count)); |
@@ -132,12 +132,14 @@ static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) | |||
132 | } | 132 | } |
133 | return sd; | 133 | return sd; |
134 | } | 134 | } |
135 | #define sysfs_get(sd) __sysfs_get(sd) | ||
135 | 136 | ||
136 | static inline void sysfs_put(struct sysfs_dirent *sd) | 137 | static inline void __sysfs_put(struct sysfs_dirent *sd) |
137 | { | 138 | { |
138 | if (sd && atomic_dec_and_test(&sd->s_count)) | 139 | if (sd && atomic_dec_and_test(&sd->s_count)) |
139 | release_sysfs_dirent(sd); | 140 | release_sysfs_dirent(sd); |
140 | } | 141 | } |
142 | #define sysfs_put(sd) __sysfs_put(sd) | ||
141 | 143 | ||
142 | /* | 144 | /* |
143 | * inode.c | 145 | * inode.c |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 8ec406afb3eb..d8e0230f1e68 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -78,6 +78,8 @@ struct sysfs_ops { | |||
78 | ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); | 78 | ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); |
79 | }; | 79 | }; |
80 | 80 | ||
81 | struct sysfs_dirent; | ||
82 | |||
81 | #ifdef CONFIG_SYSFS | 83 | #ifdef CONFIG_SYSFS |
82 | 84 | ||
83 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | 85 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), |
@@ -118,10 +120,13 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
118 | const struct attribute *attr, const char *group); | 120 | const struct attribute *attr, const char *group); |
119 | 121 | ||
120 | void sysfs_notify(struct kobject *kobj, char *dir, char *attr); | 122 | void sysfs_notify(struct kobject *kobj, char *dir, char *attr); |
121 | 123 | void sysfs_notify_dirent(struct sysfs_dirent *sd); | |
124 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | ||
125 | const unsigned char *name); | ||
126 | struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); | ||
127 | void sysfs_put(struct sysfs_dirent *sd); | ||
122 | void sysfs_printk_last_file(void); | 128 | void sysfs_printk_last_file(void); |
123 | 129 | int __must_check sysfs_init(void); | |
124 | extern int __must_check sysfs_init(void); | ||
125 | 130 | ||
126 | #else /* CONFIG_SYSFS */ | 131 | #else /* CONFIG_SYSFS */ |
127 | 132 | ||
@@ -227,6 +232,22 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj, | |||
227 | static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr) | 232 | static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr) |
228 | { | 233 | { |
229 | } | 234 | } |
235 | static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) | ||
236 | { | ||
237 | } | ||
238 | static inline | ||
239 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | ||
240 | const unsigned char *name) | ||
241 | { | ||
242 | return NULL; | ||
243 | } | ||
244 | static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) | ||
245 | { | ||
246 | return NULL; | ||
247 | } | ||
248 | static inline void sysfs_put(struct sysfs_dirent *sd) | ||
249 | { | ||
250 | } | ||
230 | 251 | ||
231 | static inline int __must_check sysfs_init(void) | 252 | static inline int __must_check sysfs_init(void) |
232 | { | 253 | { |