|
@@ -336,6 +336,9 @@ static int hfsplus_free_extents(struct super_block *sb,
|
|
int i;
|
|
int i;
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
|
|
+ /* Mapping the allocation file may lock the extent tree */
|
|
|
|
+ WARN_ON(mutex_is_locked(&HFSPLUS_SB(sb)->ext_tree->tree_lock));
|
|
|
|
+
|
|
hfsplus_dump_extent(extent);
|
|
hfsplus_dump_extent(extent);
|
|
for (i = 0; i < 8; extent++, i++) {
|
|
for (i = 0; i < 8; extent++, i++) {
|
|
count = be32_to_cpu(extent->block_count);
|
|
count = be32_to_cpu(extent->block_count);
|
|
@@ -415,11 +418,13 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid,
|
|
if (res)
|
|
if (res)
|
|
break;
|
|
break;
|
|
start = be32_to_cpu(fd.key->ext.start_block);
|
|
start = be32_to_cpu(fd.key->ext.start_block);
|
|
- hfsplus_free_extents(sb, ext_entry,
|
|
|
|
- total_blocks - start,
|
|
|
|
- total_blocks);
|
|
|
|
hfs_brec_remove(&fd);
|
|
hfs_brec_remove(&fd);
|
|
|
|
+
|
|
|
|
+ mutex_unlock(&fd.tree->tree_lock);
|
|
|
|
+ hfsplus_free_extents(sb, ext_entry, total_blocks - start,
|
|
|
|
+ total_blocks);
|
|
total_blocks = start;
|
|
total_blocks = start;
|
|
|
|
+ mutex_lock(&fd.tree->tree_lock);
|
|
} while (total_blocks > blocks);
|
|
} while (total_blocks > blocks);
|
|
hfs_find_exit(&fd);
|
|
hfs_find_exit(&fd);
|
|
|
|
|
|
@@ -576,15 +581,20 @@ void hfsplus_file_truncate(struct inode *inode)
|
|
}
|
|
}
|
|
while (1) {
|
|
while (1) {
|
|
if (alloc_cnt == hip->first_blocks) {
|
|
if (alloc_cnt == hip->first_blocks) {
|
|
|
|
+ mutex_unlock(&fd.tree->tree_lock);
|
|
hfsplus_free_extents(sb, hip->first_extents,
|
|
hfsplus_free_extents(sb, hip->first_extents,
|
|
alloc_cnt, alloc_cnt - blk_cnt);
|
|
alloc_cnt, alloc_cnt - blk_cnt);
|
|
hfsplus_dump_extent(hip->first_extents);
|
|
hfsplus_dump_extent(hip->first_extents);
|
|
hip->first_blocks = blk_cnt;
|
|
hip->first_blocks = blk_cnt;
|
|
|
|
+ mutex_lock(&fd.tree->tree_lock);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt);
|
|
res = __hfsplus_ext_cache_extent(&fd, inode, alloc_cnt);
|
|
if (res)
|
|
if (res)
|
|
break;
|
|
break;
|
|
|
|
+ hfs_brec_remove(&fd);
|
|
|
|
+
|
|
|
|
+ mutex_unlock(&fd.tree->tree_lock);
|
|
start = hip->cached_start;
|
|
start = hip->cached_start;
|
|
hfsplus_free_extents(sb, hip->cached_extents,
|
|
hfsplus_free_extents(sb, hip->cached_extents,
|
|
alloc_cnt - start, alloc_cnt - blk_cnt);
|
|
alloc_cnt - start, alloc_cnt - blk_cnt);
|
|
@@ -596,7 +606,7 @@ void hfsplus_file_truncate(struct inode *inode)
|
|
alloc_cnt = start;
|
|
alloc_cnt = start;
|
|
hip->cached_start = hip->cached_blocks = 0;
|
|
hip->cached_start = hip->cached_blocks = 0;
|
|
hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
|
|
hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW);
|
|
- hfs_brec_remove(&fd);
|
|
|
|
|
|
+ mutex_lock(&fd.tree->tree_lock);
|
|
}
|
|
}
|
|
hfs_find_exit(&fd);
|
|
hfs_find_exit(&fd);
|
|
|
|
|