aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-05-12 20:13:50 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-05-12 20:13:50 -0400
commit9717a91b01feda644f45fd63624a641385ef8f2d (patch)
treec2abccf2e761596b361146de3041143f7db21c29
parent323ee8fc544d407eb053471b9607f95f987f5f12 (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.c3
-rw-r--r--fs/hfs/dir.c12
-rw-r--r--fs/hfs/hfs_fs.h1
-rw-r--r--fs/hfs/inode.c2
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));
167out: 173out:
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
304const struct file_operations hfs_dir_operations = { 310const 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;