···240240 }241241 }242242243243+ /* we only need to take spinlock for exclusion with ->release() */244244+ spin_lock(&HFS_I(dir)->open_dir_lock);243245 list_for_each_entry(rd, &HFS_I(dir)->open_dir_list, list) {244246 if (fd.tree->keycmp(fd.search_key, (void *)&rd->key) < 0)245247 rd->file->f_pos--;246248 }249249+ spin_unlock(&HFS_I(dir)->open_dir_lock);247250248251 res = hfs_brec_remove(&fd);249252 if (res)
+9-3
fs/hfs/dir.c
···161161 }162162 file->private_data = rd;163163 rd->file = file;164164+ spin_lock(&HFS_I(inode)->open_dir_lock);164165 list_add(&rd->list, &HFS_I(inode)->open_dir_list);166166+ spin_unlock(&HFS_I(inode)->open_dir_lock);165167 }168168+ /*169169+ * Can be done after the list insertion; exclusion with170170+ * hfs_delete_cat() is provided by directory lock.171171+ */166172 memcpy(&rd->key, &fd.key, sizeof(struct hfs_cat_key));167173out:168174 hfs_find_exit(&fd);···179173{180174 struct hfs_readdir_data *rd = file->private_data;181175 if (rd) {182182- inode_lock(inode);176176+ spin_lock(&HFS_I(inode)->open_dir_lock);183177 list_del(&rd->list);184184- inode_unlock(inode);178178+ spin_unlock(&HFS_I(inode)->open_dir_lock);185179 kfree(rd);186180 }187181 return 0;···309303310304const struct file_operations hfs_dir_operations = {311305 .read = generic_read_dir,312312- .iterate = hfs_readdir,306306+ .iterate_shared = hfs_readdir,313307 .llseek = generic_file_llseek,314308 .release = hfs_dir_release,315309};