hfs: switch to ->iterate_shared()

exact parallel of hfsplus analogue

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index 1eb5d41..98cde8b 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -240,10 +240,13 @@
 		}
 	}
 
+	/* we only need to take spinlock for exclusion with ->release() */
+	spin_lock(&HFS_I(dir)->open_dir_lock);
 	list_for_each_entry(rd, &HFS_I(dir)->open_dir_list, list) {
 		if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0)
 			rd->file->f_pos--;
 	}
+	spin_unlock(&HFS_I(dir)->open_dir_lock);
 
 	res = hfs_brec_remove(&fd);
 	if (res)
diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c
index e9f2b85..163190ec 100644
--- a/fs/hfs/dir.c
+++ b/fs/hfs/dir.c
@@ -161,8 +161,14 @@
 		}
 		file->private_data = rd;
 		rd->file = file;
+		spin_lock(&HFS_I(inode)->open_dir_lock);
 		list_add(&rd->list, &HFS_I(inode)->open_dir_list);
+		spin_unlock(&HFS_I(inode)->open_dir_lock);
 	}
+	/*
+	 * Can be done after the list insertion; exclusion with
+	 * hfs_delete_cat() is provided by directory lock.
+	 */
 	memcpy(&rd->key, &fd.key, sizeof(struct hfs_cat_key));
 out:
 	hfs_find_exit(&fd);
@@ -173,9 +179,9 @@
 {
 	struct hfs_readdir_data *rd = file->private_data;
 	if (rd) {
-		inode_lock(inode);
+		spin_lock(&HFS_I(inode)->open_dir_lock);
 		list_del(&rd->list);
-		inode_unlock(inode);
+		spin_unlock(&HFS_I(inode)->open_dir_lock);
 		kfree(rd);
 	}
 	return 0;
@@ -303,7 +309,7 @@
 
 const struct file_operations hfs_dir_operations = {
 	.read		= generic_read_dir,
-	.iterate	= hfs_readdir,
+	.iterate_shared	= hfs_readdir,
 	.llseek		= generic_file_llseek,
 	.release	= hfs_dir_release,
 };
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index 79daa09..fa3eed8 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -69,6 +69,7 @@
 	struct hfs_cat_key cat_key;
 
 	struct list_head open_dir_list;
+	spinlock_t open_dir_lock;
 	struct inode *rsrc_inode;
 
 	struct mutex extents_lock;
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index cb1e5fa..ba533c7 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -187,6 +187,7 @@
 
 	mutex_init(&HFS_I(inode)->extents_lock);
 	INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
+	spin_lock_init(&HFS_I(inode)->open_dir_lock);
 	hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
 	inode->i_ino = HFS_SB(sb)->next_id++;
 	inode->i_mode = mode;
@@ -318,6 +319,7 @@
 	HFS_I(inode)->rsrc_inode = NULL;
 	mutex_init(&HFS_I(inode)->extents_lock);
 	INIT_LIST_HEAD(&HFS_I(inode)->open_dir_list);
+	spin_lock_init(&HFS_I(inode)->open_dir_lock);
 
 	/* Initialize the inode */
 	inode->i_uid = hsb->s_uid;