diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:31:04 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:33:45 -0500 |
| commit | 109d28152b6e9d5de64cd23e3bc08885ccb3d1ef (patch) | |
| tree | b7b8863faa05254781acfb85cc41da3eef467c6b /fs/sysfs | |
| parent | 168cf9af699e87d5a6f44b684583714ecabb8e71 (diff) | |
| parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) | |
Merge tag 'v2.6.33' for its firewire changes since last branch point
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'fs/sysfs')
| -rw-r--r-- | fs/sysfs/dir.c | 14 | ||||
| -rw-r--r-- | fs/sysfs/inode.c | 35 | ||||
| -rw-r--r-- | fs/sysfs/sysfs.h | 15 |
3 files changed, 44 insertions, 20 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f05f2303a8b8..699f371b9f12 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
| @@ -106,8 +106,10 @@ static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
| 106 | return NULL; | 106 | return NULL; |
| 107 | 107 | ||
| 108 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | 108 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); |
| 109 | if (likely(t == v)) | 109 | if (likely(t == v)) { |
| 110 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | ||
| 110 | return sd; | 111 | return sd; |
| 112 | } | ||
| 111 | if (t < 0) | 113 | if (t < 0) |
| 112 | return NULL; | 114 | return NULL; |
| 113 | 115 | ||
| @@ -130,6 +132,7 @@ static void sysfs_put_active(struct sysfs_dirent *sd) | |||
| 130 | if (unlikely(!sd)) | 132 | if (unlikely(!sd)) |
| 131 | return; | 133 | return; |
| 132 | 134 | ||
| 135 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
| 133 | v = atomic_dec_return(&sd->s_active); | 136 | v = atomic_dec_return(&sd->s_active); |
| 134 | if (likely(v != SD_DEACTIVATED_BIAS)) | 137 | if (likely(v != SD_DEACTIVATED_BIAS)) |
| 135 | return; | 138 | return; |
| @@ -194,15 +197,21 @@ static void sysfs_deactivate(struct sysfs_dirent *sd) | |||
| 194 | BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); | 197 | BUG_ON(sd->s_sibling || !(sd->s_flags & SYSFS_FLAG_REMOVED)); |
| 195 | sd->s_sibling = (void *)&wait; | 198 | sd->s_sibling = (void *)&wait; |
| 196 | 199 | ||
| 200 | rwsem_acquire(&sd->dep_map, 0, 0, _RET_IP_); | ||
| 197 | /* atomic_add_return() is a mb(), put_active() will always see | 201 | /* atomic_add_return() is a mb(), put_active() will always see |
| 198 | * the updated sd->s_sibling. | 202 | * the updated sd->s_sibling. |
| 199 | */ | 203 | */ |
| 200 | v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); | 204 | v = atomic_add_return(SD_DEACTIVATED_BIAS, &sd->s_active); |
| 201 | 205 | ||
| 202 | if (v != SD_DEACTIVATED_BIAS) | 206 | if (v != SD_DEACTIVATED_BIAS) { |
| 207 | lock_contended(&sd->dep_map, _RET_IP_); | ||
| 203 | wait_for_completion(&wait); | 208 | wait_for_completion(&wait); |
| 209 | } | ||
| 204 | 210 | ||
| 205 | sd->s_sibling = NULL; | 211 | sd->s_sibling = NULL; |
| 212 | |||
| 213 | lock_acquired(&sd->dep_map, _RET_IP_); | ||
| 214 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
| 206 | } | 215 | } |
| 207 | 216 | ||
| 208 | static int sysfs_alloc_ino(ino_t *pino) | 217 | static int sysfs_alloc_ino(ino_t *pino) |
| @@ -345,6 +354,7 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type) | |||
| 345 | 354 | ||
| 346 | atomic_set(&sd->s_count, 1); | 355 | atomic_set(&sd->s_count, 1); |
| 347 | atomic_set(&sd->s_active, 0); | 356 | atomic_set(&sd->s_active, 0); |
| 357 | sysfs_dirent_init_lockdep(sd); | ||
| 348 | 358 | ||
| 349 | sd->s_name = name; | 359 | sd->s_name = name; |
| 350 | sd->s_mode = mode; | 360 | sd->s_mode = mode; |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 220b758523ae..6a06a1d1ea7b 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
| @@ -81,24 +81,23 @@ int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr) | |||
| 81 | if (!sd_attrs) | 81 | if (!sd_attrs) |
| 82 | return -ENOMEM; | 82 | return -ENOMEM; |
| 83 | sd->s_iattr = sd_attrs; | 83 | sd->s_iattr = sd_attrs; |
| 84 | } else { | 84 | } |
| 85 | /* attributes were changed at least once in past */ | 85 | /* attributes were changed at least once in past */ |
| 86 | iattrs = &sd_attrs->ia_iattr; | 86 | iattrs = &sd_attrs->ia_iattr; |
| 87 | 87 | ||
| 88 | if (ia_valid & ATTR_UID) | 88 | if (ia_valid & ATTR_UID) |
| 89 | iattrs->ia_uid = iattr->ia_uid; | 89 | iattrs->ia_uid = iattr->ia_uid; |
| 90 | if (ia_valid & ATTR_GID) | 90 | if (ia_valid & ATTR_GID) |
| 91 | iattrs->ia_gid = iattr->ia_gid; | 91 | iattrs->ia_gid = iattr->ia_gid; |
| 92 | if (ia_valid & ATTR_ATIME) | 92 | if (ia_valid & ATTR_ATIME) |
| 93 | iattrs->ia_atime = iattr->ia_atime; | 93 | iattrs->ia_atime = iattr->ia_atime; |
| 94 | if (ia_valid & ATTR_MTIME) | 94 | if (ia_valid & ATTR_MTIME) |
| 95 | iattrs->ia_mtime = iattr->ia_mtime; | 95 | iattrs->ia_mtime = iattr->ia_mtime; |
| 96 | if (ia_valid & ATTR_CTIME) | 96 | if (ia_valid & ATTR_CTIME) |
| 97 | iattrs->ia_ctime = iattr->ia_ctime; | 97 | iattrs->ia_ctime = iattr->ia_ctime; |
| 98 | if (ia_valid & ATTR_MODE) { | 98 | if (ia_valid & ATTR_MODE) { |
| 99 | umode_t mode = iattr->ia_mode; | 99 | umode_t mode = iattr->ia_mode; |
| 100 | iattrs->ia_mode = sd->s_mode = mode; | 100 | iattrs->ia_mode = sd->s_mode = mode; |
| 101 | } | ||
| 102 | } | 101 | } |
| 103 | return 0; | 102 | return 0; |
| 104 | } | 103 | } |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index ca52e7b9d8f8..cdd9377a6e06 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | * This file is released under the GPLv2. | 8 | * This file is released under the GPLv2. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/lockdep.h> | ||
| 11 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
| 12 | 13 | ||
| 13 | struct sysfs_open_dirent; | 14 | struct sysfs_open_dirent; |
| @@ -50,6 +51,9 @@ struct sysfs_inode_attrs { | |||
| 50 | struct sysfs_dirent { | 51 | struct sysfs_dirent { |
| 51 | atomic_t s_count; | 52 | atomic_t s_count; |
| 52 | atomic_t s_active; | 53 | atomic_t s_active; |
| 54 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 55 | struct lockdep_map dep_map; | ||
| 56 | #endif | ||
| 53 | struct sysfs_dirent *s_parent; | 57 | struct sysfs_dirent *s_parent; |
| 54 | struct sysfs_dirent *s_sibling; | 58 | struct sysfs_dirent *s_sibling; |
| 55 | const char *s_name; | 59 | const char *s_name; |
| @@ -84,6 +88,17 @@ static inline unsigned int sysfs_type(struct sysfs_dirent *sd) | |||
| 84 | return sd->s_flags & SYSFS_TYPE_MASK; | 88 | return sd->s_flags & SYSFS_TYPE_MASK; |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 91 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
| 92 | #define sysfs_dirent_init_lockdep(sd) \ | ||
| 93 | do { \ | ||
| 94 | static struct lock_class_key __key; \ | ||
| 95 | \ | ||
| 96 | lockdep_init_map(&sd->dep_map, "s_active", &__key, 0); \ | ||
| 97 | } while(0) | ||
| 98 | #else | ||
| 99 | #define sysfs_dirent_init_lockdep(sd) do {} while(0) | ||
| 100 | #endif | ||
| 101 | |||
| 87 | /* | 102 | /* |
| 88 | * Context structure to be used while adding/removing nodes. | 103 | * Context structure to be used while adding/removing nodes. |
| 89 | */ | 104 | */ |
