@@ -402,19 +402,26 @@ xfs_file_splice_read(
402402 if (XFS_FORCED_SHUTDOWN (ip -> i_mount ))
403403 return - EIO ;
404404
405- xfs_rw_ilock (ip , XFS_IOLOCK_SHARED );
406-
407405 trace_xfs_file_splice_read (ip , count , * ppos , ioflags );
408406
409- /* for dax, we need to avoid the page cache */
410- if (IS_DAX (VFS_I (ip )))
411- ret = default_file_splice_read (infilp , ppos , pipe , count , flags );
412- else
413- ret = generic_file_splice_read (infilp , ppos , pipe , count , flags );
414- if (ret > 0 )
415- XFS_STATS_ADD (ip -> i_mount , xs_read_bytes , ret );
407+ /*
408+ * DAX inodes cannot ues the page cache for splice, so we have to push
409+ * them through the VFS IO path. This means it goes through
410+ * ->read_iter, which for us takes the XFS_IOLOCK_SHARED. Hence we
411+ * cannot lock the splice operation at this level for DAX inodes.
412+ */
413+ if (IS_DAX (VFS_I (ip ))) {
414+ ret = default_file_splice_read (infilp , ppos , pipe , count ,
415+ flags );
416+ goto out ;
417+ }
416418
419+ xfs_rw_ilock (ip , XFS_IOLOCK_SHARED );
420+ ret = generic_file_splice_read (infilp , ppos , pipe , count , flags );
417421 xfs_rw_iunlock (ip , XFS_IOLOCK_SHARED );
422+ out :
423+ if (ret > 0 )
424+ XFS_STATS_ADD (ip -> i_mount , xs_read_bytes , ret );
418425 return ret ;
419426}
420427
0 commit comments