+++ /dev/null
-commit c1a9f672dd752df609a38126e33457c2064329e6
-Author: Johann Lombardi <johann@sun.com>
-Date: Wed Oct 6 15:26:43 2010 +0200
-
- Revert "ext4: Fix potential fiemap deadlock (mmap_sem vs. i_data_sem)"
-
- This reverts commit fab3a549e204172236779f502eccb4f9bf0dc87d.
-
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 06328d3..51c9452 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -1862,9 +1862,7 @@ int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
- while (block < last && block != EXT_MAX_BLOCK) {
- num = last - block;
- /* find extent for this block */
-- down_read(&EXT4_I(inode)->i_data_sem);
- path = ext4_ext_find_extent(inode, block, path);
-- up_read(&EXT4_I(inode)->i_data_sem);
- if (IS_ERR(path)) {
- err = PTR_ERR(path);
- path = NULL;
-@@ -3956,8 +3954,10 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
- * Walk the extent tree gathering extent information.
- * ext4_ext_fiemap_cb will push extents back to user.
- */
-+ down_read(&EXT4_I(inode)->i_data_sem);
- error = ext4_ext_walk_space(inode, start_blk, len_blks,
- ext4_ext_fiemap_cb, fieinfo);
-+ up_read(&EXT4_I(inode)->i_data_sem);
- }
-
- return error;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17))
# define fsfilt_up_truncate_sem(inode) up(&LDISKFS_I(inode)->truncate_sem);
# define fsfilt_down_truncate_sem(inode) down(&LDISKFS_I(inode)->truncate_sem);
+# define fsfilt_up_truncate_sem_in_cb(inode) do { } while (0)
+# define fsfilt_down_truncate_sem_in_cb(inode) do { } while (0)
#else
# ifdef HAVE_EXT4_LDISKFS
+# ifdef WALK_SPACE_HAS_DATA_SEM /* We only use it in fsfilt_map_nblocks() for now */
+# define fsfilt_up_truncate_sem(inode) do{ }while(0)
+# define fsfilt_down_truncate_sem(inode) do{ }while(0)
+# define fsfilt_up_truncate_sem_in_cb(inode) up_write((&EXT4_I(inode)->i_data_sem))
+# define fsfilt_down_truncate_sem_in_cb(inode) down_write((&EXT4_I(inode)->i_data_sem))
+# else
# define fsfilt_up_truncate_sem(inode) up_write((&LDISKFS_I(inode)->i_data_sem));
# define fsfilt_down_truncate_sem(inode) down_write((&LDISKFS_I(inode)->i_data_sem));
+# define fsfilt_up_truncate_sem_in_cb(inode) do { } while (0)
+# define fsfilt_down_truncate_sem_in_cb(inode) do { } while (0)
+# endif
# else
# define fsfilt_up_truncate_sem(inode) mutex_unlock(&LDISKFS_I(inode)->truncate_mutex);
# define fsfilt_down_truncate_sem(inode) mutex_lock(&LDISKFS_I(inode)->truncate_mutex);
+# define fsfilt_up_truncate_sem_in_cb(inode) do { } while (0)
+# define fsfilt_down_truncate_sem_in_cb(inode) do { } while (0)
# endif
#endif
return EXT_REPEAT;
}
+ /* In 2.6.32 kernel, ext4_ext_walk_space()'s callback func is not
+ * protected by i_data_sem, we need do it ourselves, since we create
+ * file system blocks */
+ fsfilt_down_truncate_sem_in_cb(inode);
+
count = cex->ec_len;
pblock = new_blocks(handle, base, path, cex->ec_block, &count, &err);
if (!pblock)
BUG_ON(le32_to_cpu(nex.ee_block) != cex->ec_block);
out:
+ fsfilt_up_truncate_sem_in_cb(inode);
ext3_journal_stop(handle);
map:
if (err >= 0) {