@@ -696,6 +696,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno,
696
696
* it not only handles the fiemap for inlined files, but also deals
697
697
* with the fast symlink, cause they have no difference for extent
698
698
* mapping per se.
699
+ *
700
+ * Must be called with ip_alloc_sem semaphore held.
699
701
*/
700
702
static int ocfs2_fiemap_inline (struct inode * inode , struct buffer_head * di_bh ,
701
703
struct fiemap_extent_info * fieinfo ,
@@ -707,6 +709,7 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
707
709
u64 phys ;
708
710
u32 flags = FIEMAP_EXTENT_DATA_INLINE |FIEMAP_EXTENT_LAST ;
709
711
struct ocfs2_inode_info * oi = OCFS2_I (inode );
712
+ lockdep_assert_held_read (& oi -> ip_alloc_sem );
710
713
711
714
di = (struct ocfs2_dinode * )di_bh -> b_data ;
712
715
if (ocfs2_inode_is_fast_symlink (inode ))
@@ -722,8 +725,11 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
722
725
phys += offsetof(struct ocfs2_dinode ,
723
726
id2 .i_data .id_data );
724
727
728
+ /* Release the ip_alloc_sem to prevent deadlock on page fault */
729
+ up_read (& OCFS2_I (inode )-> ip_alloc_sem );
725
730
ret = fiemap_fill_next_extent (fieinfo , 0 , phys , id_count ,
726
731
flags );
732
+ down_read (& OCFS2_I (inode )-> ip_alloc_sem );
727
733
if (ret < 0 )
728
734
return ret ;
729
735
}
@@ -792,9 +798,11 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
792
798
len_bytes = (u64 )le16_to_cpu (rec .e_leaf_clusters ) << osb -> s_clustersize_bits ;
793
799
phys_bytes = le64_to_cpu (rec .e_blkno ) << osb -> sb -> s_blocksize_bits ;
794
800
virt_bytes = (u64 )le32_to_cpu (rec .e_cpos ) << osb -> s_clustersize_bits ;
795
-
801
+ /* Release the ip_alloc_sem to prevent deadlock on page fault */
802
+ up_read (& OCFS2_I (inode )-> ip_alloc_sem );
796
803
ret = fiemap_fill_next_extent (fieinfo , virt_bytes , phys_bytes ,
797
804
len_bytes , fe_flags );
805
+ down_read (& OCFS2_I (inode )-> ip_alloc_sem );
798
806
if (ret )
799
807
break ;
800
808
0 commit comments