diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7011ac9..2d2d2af 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1978,10 +1978,10 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t 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;
+			up_read(&EXT4_I(inode)->i_data_sem);
 			break;
 		}
 
@@ -1989,6 +1989,7 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
 		if (unlikely(path[depth].p_hdr == NULL)) {
 			EXT4_ERROR_INODE(inode, "path[%d].p_hdr == NULL", depth);
 			err = -EIO;
+			up_read(&EXT4_I(inode)->i_data_sem);
 			break;
 		}
 		ex = path[depth].p_ext;
@@ -2028,6 +2029,8 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
 			BUG();
 		}
 		BUG_ON(end <= start);
+		up_read(&EXT4_I(inode)->i_data_sem);
+		BUG_ON(end <= start);
 
 		if (!exists) {
 			cbex.ec_block = start;
@@ -2045,7 +2048,6 @@ static int ext4_ext_walk_space(struct inode *inode, ext4_lblk_t block,
 			break;
 		}
 		err = func(inode, next, &cbex, ex, cbdata);
-		ext4_ext_drop_refs(path);
 
 		if (err < 0)
 			break;
