Re: [PATCH 4.19 077/243] iomap: dio data corruption and spurious errors when pipes fill

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 12, 2019 at 08:50:25AM +0900, Nobuhiro Iwamatsu wrote:
> On Wed, Dec 11, 2019 at 04:03:59PM +0100, Greg Kroah-Hartman wrote:
> > From: Dave Chinner <dchinner@xxxxxxxxxx>
> > 
> > [ Upstream commit 4721a6010990971440b4ffefbdf014976b8eda2f ]
> > 
> > When doing direct IO to a pipe for do_splice_direct(), then pipe is
> > trivial to fill up and overflow as it can only hold 16 pages. At
> > this point bio_iov_iter_get_pages() then returns -EFAULT, and we
> > abort the IO submission process. Unfortunately, iomap_dio_rw()
> > propagates the error back up the stack.
> > 
> > The error is converted from the EFAULT to EAGAIN in
> > generic_file_splice_read() to tell the splice layers that the pipe
> > is full. do_splice_direct() completely fails to handle EAGAIN errors
> > (it aborts on error) and returns EAGAIN to the caller.
> > 
> > copy_file_write() then completely fails to handle EAGAIN as well,
> > and so returns EAGAIN to userspace, having failed to copy the data
> > it was asked to.
> > 
> > Avoid this whole steaming pile of fail by having iomap_dio_rw()
> > silently swallow EFAULT errors and so do short reads.
> > 
> > To make matters worse, iomap_dio_actor() has a stale data exposure
> > bug bio_iov_iter_get_pages() fails - it does not zero the tail block
> > that it may have been left uncovered by partial IO. Fix the error
> > handling case to drop to the sub-block zeroing rather than
> > immmediately returning the -EFAULT error.
> > 
> > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
> > Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> > Reviewed-by: Christoph Hellwig <hch@xxxxxx>
> > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> > Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
> 
> 
> 
> This commit also seems to require the following 2 commits:
> 
> commit 8f67b5adc030553fbc877124306f3f3bdab89aa8
> Author: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> Date:   Sun Dec 2 08:38:07 2018 -0800
> 
>     iomap: partially revert 4721a601099 (simulated directio short read on EFAULT)
> 
>     In commit 4721a601099, we tried to fix a problem wherein directio reads
>     into a splice pipe will bounce EFAULT/EAGAIN all the way out to
>     userspace by simulating a zero-byte short read.  This happens because
>     some directio read implementations (xfs) will call
>     bio_iov_iter_get_pages to grab pipe buffer pages and issue asynchronous
>     reads, but as soon as we run out of pipe buffers that _get_pages call
>     returns EFAULT, which the splice code translates to EAGAIN and bounces
>     out to userspace.
> 
>     In that commit, the iomap code catches the EFAULT and simulates a
>     zero-byte read, but that causes assertion errors on regular splice reads
>     because xfs doesn't allow short directio reads.  This causes infinite
>     splice() loops and assertion failures on generic/095 on overlayfs
>     because xfs only permit total success or total failure of a directio
>     operation.  The underlying issue in the pipe splice code has now been
>     fixed by changing the pipe splice loop to avoid avoid reading more data
>     than there is space in the pipe.
> 
>     Therefore, it's no longer necessary to simulate the short directio, so
>     remove the hack from iomap.
> 
>     Fixes: 4721a601099 ("iomap: dio data corruption and spurious errors when pipes fill")
>     Reported-by: Murphy Zhou <jencce.kernel@xxxxxxxxx>
>     Ranted-by: Amir Goldstein <amir73il@xxxxxxxxx>
>     Reviewed-by: Christoph Hellwig <hch@xxxxxx>
>     Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> i
> commit 17614445576b6af24e9cf36607c6448164719c96
> Author: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> Date:   Fri Nov 30 10:37:49 2018 -0800
> 
>     splice: don't read more than available pipe space
> 
>     In commit 4721a601099, we tried to fix a problem wherein directio reads
>     into a splice pipe will bounce EFAULT/EAGAIN all the way out to
>     userspace by simulating a zero-byte short read.  This happens because
>     some directio read implementations (xfs) will call
>     bio_iov_iter_get_pages to grab pipe buffer pages and issue asynchronous
>     reads, but as soon as we run out of pipe buffers that _get_pages call
>     returns EFAULT, which the splice code translates to EAGAIN and bounces
>     out to userspace.
> 
>     In that commit, the iomap code catches the EFAULT and simulates a
>     zero-byte read, but that causes assertion errors on regular splice reads
>     because xfs doesn't allow short directio reads.
> 
>     The brokenness is compounded by splice_direct_to_actor immediately
>     bailing on do_splice_to returning <= 0 without ever calling ->actor
>     (which empties out the pipe), so if userspace calls back we'll EFAULT
>     again on the full pipe, and nothing ever gets copied.
> 
>     Therefore, teach splice_direct_to_actor to clamp its requests to the
>     amount of free space in the pipe and remove the simulated short read
>     from the iomap directio code.
> 
>     Fixes: 4721a601099 ("iomap: dio data corruption and spurious errors when pipes fill")
>     Reported-by: Murphy Zhou <jencce.kernel@xxxxxxxxx>
>     Ranted-by: Amir Goldstein <amir73il@xxxxxxxxx>
>     Reviewed-by: Christoph Hellwig <hch@xxxxxx>
>     Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> 

Sasha has queued these up already, thanks.

greg k-h



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux