diff options
author | Neil Brown <neilb@suse.de> | 2008-07-15 18:58:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-10-16 12:24:47 -0400 |
commit | f1282c844e86db5a041afa41335b5f9eea6cec0c (patch) | |
tree | 3736285f2f7ce145fb06538d616a9c1165ffc125 /fs/sysfs/sysfs.h | |
parent | ec748fa9ed3fec44aeebbf86ae050b0cc7a978d9 (diff) |
sysfs: Support sysfs_notify from atomic context with new sysfs_notify_dirent
Support sysfs_notify from atomic context with new sysfs_notify_dirent
sysfs_notify currently takes sysfs_mutex.
This means that it cannot be called in atomic context.
sysfs_mutex is sometimes held over a malloc (sysfs_rename_dir)
so it can block on low memory.
In md I want to be able to notify on a sysfs attribute from
atomic context, and I don't want to block on low memory because I
could be in the writeout path for freeing memory.
So:
- export the "sysfs_dirent" structure along with sysfs_get, sysfs_put
and sysfs_get_dirent so I can get the sysfs_dirent that I want to
notify on and hold it in an md structure.
- split sysfs_notify_dirent out of sysfs_notify so the sysfs_dirent
can be notified on with no blocking (just a spinlock).
Signed-off-by: Neil Brown <neilb@suse.de>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs/sysfs.h')
-rw-r--r-- | fs/sysfs/sysfs.h | 6 |
1 files changed, 4 insertions, 2 deletions
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 |