diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-07-18 06:20:23 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 06:20:23 -0400 |
| commit | cd569ef5d6ff9f43e9504f1ffc7fdbe356518149 (patch) | |
| tree | 9a4ab5e600fd09e991aa1fbb69adb1c7950898a4 /fs/configfs/symlink.c | |
| parent | 6879827f4e08da219c99b91e4e1d793a924103e3 (diff) | |
| parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) | |
Merge branch 'linus' into x86/urgent
Diffstat (limited to 'fs/configfs/symlink.c')
| -rw-r--r-- | fs/configfs/symlink.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index 2a731ef5f305..0004d18c40ac 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c | |||
| @@ -77,12 +77,15 @@ static int create_link(struct config_item *parent_item, | |||
| 77 | sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); | 77 | sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL); |
| 78 | if (sl) { | 78 | if (sl) { |
| 79 | sl->sl_target = config_item_get(item); | 79 | sl->sl_target = config_item_get(item); |
| 80 | /* FIXME: needs a lock, I'd bet */ | 80 | spin_lock(&configfs_dirent_lock); |
| 81 | list_add(&sl->sl_list, &target_sd->s_links); | 81 | list_add(&sl->sl_list, &target_sd->s_links); |
| 82 | spin_unlock(&configfs_dirent_lock); | ||
| 82 | ret = configfs_create_link(sl, parent_item->ci_dentry, | 83 | ret = configfs_create_link(sl, parent_item->ci_dentry, |
| 83 | dentry); | 84 | dentry); |
| 84 | if (ret) { | 85 | if (ret) { |
| 86 | spin_lock(&configfs_dirent_lock); | ||
| 85 | list_del_init(&sl->sl_list); | 87 | list_del_init(&sl->sl_list); |
| 88 | spin_unlock(&configfs_dirent_lock); | ||
| 86 | config_item_put(item); | 89 | config_item_put(item); |
| 87 | kfree(sl); | 90 | kfree(sl); |
| 88 | } | 91 | } |
| @@ -137,8 +140,12 @@ int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symna | |||
| 137 | goto out_put; | 140 | goto out_put; |
| 138 | 141 | ||
| 139 | ret = type->ct_item_ops->allow_link(parent_item, target_item); | 142 | ret = type->ct_item_ops->allow_link(parent_item, target_item); |
| 140 | if (!ret) | 143 | if (!ret) { |
| 141 | ret = create_link(parent_item, target_item, dentry); | 144 | ret = create_link(parent_item, target_item, dentry); |
| 145 | if (ret && type->ct_item_ops->drop_link) | ||
| 146 | type->ct_item_ops->drop_link(parent_item, | ||
| 147 | target_item); | ||
| 148 | } | ||
| 142 | 149 | ||
| 143 | config_item_put(target_item); | 150 | config_item_put(target_item); |
| 144 | path_put(&nd.path); | 151 | path_put(&nd.path); |
| @@ -169,7 +176,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 169 | parent_item = configfs_get_config_item(dentry->d_parent); | 176 | parent_item = configfs_get_config_item(dentry->d_parent); |
| 170 | type = parent_item->ci_type; | 177 | type = parent_item->ci_type; |
| 171 | 178 | ||
| 179 | spin_lock(&configfs_dirent_lock); | ||
| 172 | list_del_init(&sd->s_sibling); | 180 | list_del_init(&sd->s_sibling); |
| 181 | spin_unlock(&configfs_dirent_lock); | ||
| 173 | configfs_drop_dentry(sd, dentry->d_parent); | 182 | configfs_drop_dentry(sd, dentry->d_parent); |
| 174 | dput(dentry); | 183 | dput(dentry); |
| 175 | configfs_put(sd); | 184 | configfs_put(sd); |
| @@ -184,8 +193,9 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 184 | type->ct_item_ops->drop_link(parent_item, | 193 | type->ct_item_ops->drop_link(parent_item, |
| 185 | sl->sl_target); | 194 | sl->sl_target); |
| 186 | 195 | ||
| 187 | /* FIXME: Needs lock */ | 196 | spin_lock(&configfs_dirent_lock); |
| 188 | list_del_init(&sl->sl_list); | 197 | list_del_init(&sl->sl_list); |
| 198 | spin_unlock(&configfs_dirent_lock); | ||
| 189 | 199 | ||
| 190 | /* Put reference from create_link() */ | 200 | /* Put reference from create_link() */ |
| 191 | config_item_put(sl->sl_target); | 201 | config_item_put(sl->sl_target); |
