diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index 6d1878b99b30..166f963d32fa 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -290,7 +290,7 @@ int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type) u32 total_blocks, blocks, start; u32 cnid = be32_to_cpu(file->FlNum); struct hfs_extent *extent; - int res, i; + int res, i, n = 0; if (type == HFS_FK_DATA) { total_blocks = be32_to_cpu(file->PyLen); @@ -317,6 +317,14 @@ int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type) if (res) return res; do { + if (n > 3 ) { + hfs_find_exit(&fd); + schedule_timeout_uninterruptible(HZ/10); + res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd); + if (res) + return res; + n = 0; + } res = __hfs_ext_read_extent(&fd, extent, cnid, total_blocks, type); if (res) break; @@ -324,6 +332,7 @@ int hfs_free_fork(struct super_block *sb, struct hfs_cat_file *file, int type) hfs_free_extents(sb, extent, total_blocks - start, total_blocks); hfs_brec_remove(&fd); total_blocks = start; + n++; } while (total_blocks > blocks); hfs_find_exit(&fd); @@ -479,7 +488,7 @@ void hfs_file_truncate(struct inode *inode) struct hfs_find_data fd; u16 blk_cnt, alloc_cnt, start; u32 size; - int res; + int res, n = 0; hfs_dbg(INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino, (long long)HFS_I(inode)->phys_size, @@ -516,6 +525,14 @@ void hfs_file_truncate(struct inode *inode) return; } while (1) { + if (n > 3 ) { + hfs_find_exit(&fd); + schedule_timeout_uninterruptible(HZ/10); + res = hfs_find_init(HFS_SB(sb)->ext_tree, &fd); + if (res) + return; + n = 0; + } if (alloc_cnt == HFS_I(inode)->first_blocks) { hfs_free_extents(sb, HFS_I(inode)->first_extents, alloc_cnt, alloc_cnt - blk_cnt); @@ -538,6 +555,7 @@ void hfs_file_truncate(struct inode *inode) HFS_I(inode)->cached_start = HFS_I(inode)->cached_blocks = 0; HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); hfs_brec_remove(&fd); + n++; } hfs_find_exit(&fd); mutex_unlock(&HFS_I(inode)->extents_lock);