diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 20:13:50 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-05-12 20:13:50 -0400 |
commit | 9717a91b01feda644f45fd63624a641385ef8f2d (patch) | |
tree | c2abccf2e761596b361146de3041143f7db21c29 | |
parent | 323ee8fc544d407eb053471b9607f95f987f5f12 (diff) |
hfs: switch to ->iterate_shared()
exact parallel of hfsplus analogue
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/hfs/catalog.c | 3 | ||||
-rw-r--r-- | fs/hfs/dir.c | 12 | ||||
-rw-r--r-- | fs/hfs/hfs_fs.h | 1 | ||||
-rw-r--r-- | fs/hfs/inode.c | 2 |
4 files changed, 15 insertions, 3 deletions
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 1eb5d415d434..98cde8ba5dc2 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c | |||
@@ -240,10 +240,13 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str) | |||
240 | } | 240 | } |
241 | } | 241 | } |
242 | 242 | ||
243 | /* we only need to take spinlock for exclusion with ->release() */ | ||
244 | spin_lock(&HFS_I(dir)->open_dir_lock); | ||
243 | list_for_each_entry(rd, &HFS_I(dir)->open_dir_list, list) { | 245 | list_for_each_entry(rd, &HFS_I(dir)->open_dir_list, list) { |
244 | if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0) | 246 | if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0) |
245 | rd->file->f_pos--; | 247 | rd->file->f_pos--; |
246 | } | 248 | } |
249 | spin_unlock(&HFS_I(dir)->open_dir_lock); | ||
247 | 250 | ||
248 | res = hfs_brec_remove(&fd); | 251 | res = hfs_brec_remove(&fd); |
249 | if (res) | 252 | if (res) |
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index e9f2b855f831..163190ecc0d2 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c | |||
@@ -161,8 +161,14 @@ static int hfs_readdir(struct file *file, struct dir_context *ctx) | |||
161 | } | 161 | } |
162 | file->private_data = rd; | 162 | file->private_data = rd; |
163 | rd->file = file; | 163 | rd->file = file; |
164 | spin_lock(&HFS_I(inode)->open_dir_lock); | ||
164 | list_add(&rd->list, &HFS_I(inode)->open_dir_list); | 165 | list_add(&rd->list, &HFS_I(inode)->open_dir_list); |
166 | spin_unlock(&HFS_I(inode)->open_dir_lock); | ||
165 | } | 167 | } |
168 | /* | ||
169 | * Can be done after the list insertion; exclusion with | ||
170 | * hfs_delete_cat() is provided by directory lock. | ||
171 | */ | ||
166 | memcpy(&rd->key, &fd.key, sizeof(struct hfs_cat_key)); | 172 | memcpy(&rd->key, &fd.key, sizeof(struct hfs_cat_key)); |
167 | out: | 173 | out: |
168 | hfs_find_exit(&fd); | 174 | hfs_find_exit(&fd); |
@@ -173,9 +179,9 @@ static int hfs_dir_release(struct inode *inode, struct file *file) | |||
173 | { | 179 | { |
174 | struct hfs_readdir_data *rd = file->private_data; | 180 | struct hfs_readdir_data *rd = file->private_data; |
175 | if (rd) { | 181 | if (rd) { |
176 | inode_lock(inode); | 182 | spin_lock(&HFS_I(inode)->open_dir_lock); |
177 | list_del(&rd->list); | 183 | list_del(&rd->list); |
178 | inode_unlock(inode); | 184 | spin_unlock(&HFS_I(inode)->open_dir_lock); |
179 | kfree(rd); | 185 | kfree(rd); |
180 | } | 186 | } |
181 | return 0; | 187 | return 0; |
@@ -303,7 +309,7 @@ static int hfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
303 | 309 | ||
304 | const struct file_operations hfs_dir_operations = { | 310 | const struct file_operations hfs_dir_operations = { |
305 | .read = generic_read_dir, | 311 | .read = generic_read_dir, |
306 | .iterate = hfs_readdir, | 312 | .iterate_shared = hfs_readdir, |
307 | .llseek = generic_file_llseek, | 313 | .llseek = generic_file_llseek, |
308 | .release = hfs_dir_release, | 314 | .release = hfs_dir_release, |
309 | }; | 315 | }; |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 79daa097929a..fa3eed86837c 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -69,6 +69,7 @@ struct hfs_inode_info { | |||
69 | struct hfs_cat_key cat_key; | 69 | struct hfs_cat_key cat_key; |
70 | 70 | ||
71 | struct list_head open_dir_list; | 71 | struct list_head open_dir_list; |
72 | spinlock_t open_dir_lock; | ||
72 | struct inode *rsrc_inode; | 73 | struct inode *rsrc_inode; |
73 | 74 | ||
74 | struct mutex extents_lock; | 75 | struct mutex extents_lock; |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index cb1e5faa2fb7..ba533c79a806 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -187,6 +187,7 @@ struct inode *hfs_new_inode(struct inode *dir, struct qstr *name, umode_t mode) | |||
187 | 187 | ||
188 | mutex_init(&HFS_I(inode)->extents_lock); | 188 | mutex_init(&HFS_I(inode)->extents_lock); |
189 | INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list); | 189 | INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list); |
190 | spin_lock_init(&HFS_I(inode)->open_dir_lock); | ||
190 | hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name); | 191 | hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name); |
191 | inode->i_ino = HFS_SB(sb)->next_id++; | 192 | inode->i_ino = HFS_SB(sb)->next_id++; |
192 | inode->i_mode = mode; | 193 | inode->i_mode = mode; |
@@ -318,6 +319,7 @@ static int hfs_read_inode(struct inode *inode, void *data) | |||
318 | HFS_I(inode)->rsrc_inode = NULL; | 319 | HFS_I(inode)->rsrc_inode = NULL; |
319 | mutex_init(&HFS_I(inode)->extents_lock); | 320 | mutex_init(&HFS_I(inode)->extents_lock); |
320 | INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list); | 321 | INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list); |
322 | spin_lock_init(&HFS_I(inode)->open_dir_lock); | ||
321 | 323 | ||
322 | /* Initialize the inode */ | 324 | /* Initialize the inode */ |
323 | inode->i_uid = hsb->s_uid; | 325 | inode->i_uid = hsb->s_uid; |