diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-03-15 15:51:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-15 15:29:26 -0700 |
commit | e7b0d26a86943370c04d6833c6edba2a72a6e240 (patch) | |
tree | 696e696176a1e72abb80afa6112fc057b39bf86b /fs/sysfs/inode.c | |
parent | d9a9cdfb078d755e648d53ec25b7370f84ee5729 (diff) | |
download | kernel_samsung_aries-e7b0d26a86943370c04d6833c6edba2a72a6e240.zip kernel_samsung_aries-e7b0d26a86943370c04d6833c6edba2a72a6e240.tar.gz kernel_samsung_aries-e7b0d26a86943370c04d6833c6edba2a72a6e240.tar.bz2 |
[PATCH] sysfs: reinstate exclusion between method calls and attribute unregistration
This patch (as869) reinstates the mutual exclusion between sysfs
attribute method calls and attribute unregistration. The
previously-reported deadlocks have been fixed, and this exclusion is
by far the simplest way to avoid races during driver unbinding.
The check for orphaned read-buffers has been moved down slightly, so
that the remainder of a partially-read buffer will still be available
to userspace even after the attribute has been unregistered.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/sysfs/inode.c')
-rw-r--r-- | fs/sysfs/inode.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index ccb7d72..4de5c6b 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -222,13 +222,17 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) static inline void orphan_all_buffers(struct inode *node) { - struct sysfs_buffer_collection *set = node->i_private; + struct sysfs_buffer_collection *set; struct sysfs_buffer *buf; mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); - if (node->i_private) { - list_for_each_entry(buf, &set->associates, associates) + set = node->i_private; + if (set) { + list_for_each_entry(buf, &set->associates, associates) { + down(&buf->sem); buf->orphaned = 1; + up(&buf->sem); + } } mutex_unlock(&node->i_mutex); } |