Commit f896adc4 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-4.20-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:
 "Here are hopefully the last set of fixes for 4.20.

  There's a fix for a longstanding statfs reporting problem with project
  quotas, a correction for page cache invalidation behaviors when
  fallocating near EOF, and a fix for a broken metadata verifier return
  code.

  Finally, the most important fix is to the pipe splicing code (aka the
  generic copy_file_range fallback) to avoid pointless short directio
  reads by only asking the filesystem for as much data as there are
  available pages in the pipe buffer. Our previous fix (simulated short
  directio reads because the number of pages didn't match the length of
  the read requested) caused subtle problems on overlayfs, so that part
  is reverted.

  Anyhow, this series passes fstests -g all on xfs and overlay+xfs, and
  has passed 17 billion fsx operations problem-free since I started
  testing

  Summary:

   - Fix broken project quota inode counts

   - Fix incorrect PAGE_MASK/PAGE_SIZE usage

   - Fix incorrect return value in btree verifier

   - Fix WARN_ON remap flags false positive

   - Fix splice read overflows"

* tag 'xfs-4.20-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  iomap: partially revert 4721a601 (simulated directio short read on EFAULT)
  splice: don't read more than available pipe space
  vfs: allow some remap flags to be passed to vfs_clone_file_range
  xfs: fix inverted return from xfs_btree_sblock_verify_crc
  xfs: fix PAGE_MASK usage in xfs_free_file_space
  fs/xfs: fix f_ffree value for statfs when project quota is set
parents 356ff8a9 8f67b5ad
...@@ -1877,15 +1877,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, ...@@ -1877,15 +1877,6 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
dio->wait_for_completion = true; dio->wait_for_completion = true;
ret = 0; ret = 0;
} }
/*
* Splicing to pipes can fail on a full pipe. We have to
* swallow this to make it look like a short IO
* otherwise the higher splice layers will completely
* mishandle the error and stop moving data.
*/
if (ret == -EFAULT)
ret = 0;
break; break;
} }
pos += ret; pos += ret;
......
...@@ -1956,7 +1956,7 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in, ...@@ -1956,7 +1956,7 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
struct inode *inode_out = file_inode(file_out); struct inode *inode_out = file_inode(file_out);
loff_t ret; loff_t ret;
WARN_ON_ONCE(remap_flags); WARN_ON_ONCE(remap_flags & REMAP_FILE_DEDUP);
if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
return -EISDIR; return -EISDIR;
......
...@@ -945,11 +945,16 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, ...@@ -945,11 +945,16 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
sd->flags &= ~SPLICE_F_NONBLOCK; sd->flags &= ~SPLICE_F_NONBLOCK;
more = sd->flags & SPLICE_F_MORE; more = sd->flags & SPLICE_F_MORE;
WARN_ON_ONCE(pipe->nrbufs != 0);
while (len) { while (len) {
size_t read_len; size_t read_len;
loff_t pos = sd->pos, prev_pos = pos; loff_t pos = sd->pos, prev_pos = pos;
ret = do_splice_to(in, &pos, pipe, len, flags); /* Don't try to read more the pipe has space for. */
read_len = min_t(size_t, len,
(pipe->buffers - pipe->nrbufs) << PAGE_SHIFT);
ret = do_splice_to(in, &pos, pipe, read_len, flags);
if (unlikely(ret <= 0)) if (unlikely(ret <= 0))
goto out_release; goto out_release;
......
...@@ -330,7 +330,7 @@ xfs_btree_sblock_verify_crc( ...@@ -330,7 +330,7 @@ xfs_btree_sblock_verify_crc(
if (xfs_sb_version_hascrc(&mp->m_sb)) { if (xfs_sb_version_hascrc(&mp->m_sb)) {
if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn))) if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
return __this_address; return false;
return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF); return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
} }
......
...@@ -1126,9 +1126,9 @@ xfs_free_file_space( ...@@ -1126,9 +1126,9 @@ xfs_free_file_space(
* page could be mmap'd and iomap_zero_range doesn't do that for us. * page could be mmap'd and iomap_zero_range doesn't do that for us.
* Writeback of the eof page will do this, albeit clumsily. * Writeback of the eof page will do this, albeit clumsily.
*/ */
if (offset + len >= XFS_ISIZE(ip) && ((offset + len) & PAGE_MASK)) { if (offset + len >= XFS_ISIZE(ip) && offset_in_page(offset + len) > 0) {
error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
(offset + len) & ~PAGE_MASK, LLONG_MAX); round_down(offset + len, PAGE_SIZE), LLONG_MAX);
} }
return error; return error;
......
...@@ -40,7 +40,7 @@ xfs_fill_statvfs_from_dquot( ...@@ -40,7 +40,7 @@ xfs_fill_statvfs_from_dquot(
statp->f_files = limit; statp->f_files = limit;
statp->f_ffree = statp->f_ffree =
(statp->f_files > dqp->q_res_icount) ? (statp->f_files > dqp->q_res_icount) ?
(statp->f_ffree - dqp->q_res_icount) : 0; (statp->f_files - dqp->q_res_icount) : 0;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment