linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: stable@vger.kernel.org
Cc: linux-xfs@vger.kernel.org, Brian Foster <bfoster@redhat.com>,
	Dave Chinner <david@fromorbit.com>
Subject: [PATCH 04/32] xfs: don't BUG() on mixed direct and mapped I/O
Date: Mon,  9 Jan 2017 16:38:35 +0100	[thread overview]
Message-ID: <1483976343-661-5-git-send-email-hch@lst.de> (raw)
In-Reply-To: <1483976343-661-1-git-send-email-hch@lst.de>

From: Brian Foster <bfoster@redhat.com>

commit 04197b341f23b908193308b8d63d17ff23232598 upstream.

We've had reports of generic/095 causing XFS to BUG() in
__xfs_get_blocks() due to the existence of delalloc blocks on a
direct I/O read. generic/095 issues a mix of various types of I/O,
including direct and memory mapped I/O to a single file. This is
clearly not supported behavior and is known to lead to such
problems. E.g., the lack of exclusion between the direct I/O and
write fault paths means that a write fault can allocate delalloc
blocks in a region of a file that was previously a hole after the
direct read has attempted to flush/inval the file range, but before
it actually reads the block mapping. In turn, the direct read
discovers a delalloc extent and cannot proceed.

While the appropriate solution here is to not mix direct and memory
mapped I/O to the same regions of the same file, the current
BUG_ON() behavior is probably overkill as it can crash the entire
system.  Instead, localize the failure to the I/O in question by
returning an error for a direct I/O that cannot be handled safely
due to delalloc blocks. Be careful to allow the case of a direct
write to post-eof delalloc blocks. This can occur due to speculative
preallocation and is safe as post-eof blocks are not accompanied by
dirty pages in pagecache (conversely, preallocation within eof must
have been zeroed, and thus dirtied, before the inode size could have
been increased beyond said blocks).

Finally, provide an additional warning if a direct I/O write occurs
while the file is memory mapped. This may not catch all problematic
scenarios, but provides a hint that some known-to-be-problematic I/O
methods are in use.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
---
 fs/xfs/xfs_aops.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 3e57a56..2693ba8 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1361,6 +1361,26 @@ __xfs_get_blocks(
 	if (error)
 		goto out_unlock;
 
+	/*
+	 * The only time we can ever safely find delalloc blocks on direct I/O
+	 * is a dio write to post-eof speculative preallocation. All other
+	 * scenarios are indicative of a problem or misuse (such as mixing
+	 * direct and mapped I/O).
+	 *
+	 * The file may be unmapped by the time we get here so we cannot
+	 * reliably fail the I/O based on mapping. Instead, fail the I/O if this
+	 * is a read or a write within eof. Otherwise, carry on but warn as a
+	 * precuation if the file happens to be mapped.
+	 */
+	if (direct && imap.br_startblock == DELAYSTARTBLOCK) {
+		if (!create || offset < i_size_read(VFS_I(ip))) {
+			WARN_ON_ONCE(1);
+			error = -EIO;
+			goto out_unlock;
+		}
+		WARN_ON_ONCE(mapping_mapped(VFS_I(ip)->i_mapping));
+	}
+
 	/* for DAX, we convert unwritten extents directly */
 	if (create &&
 	    (!nimaps ||
@@ -1450,8 +1470,6 @@ __xfs_get_blocks(
 	     (new || ISUNWRITTEN(&imap))))
 		set_buffer_new(bh_result);
 
-	BUG_ON(direct && imap.br_startblock == DELAYSTARTBLOCK);
-
 	return 0;
 
 out_unlock:
-- 
2.1.4


  parent reply	other threads:[~2017-01-09 15:39 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-09 15:38 4.9-stable updates for XFS Christoph Hellwig
2017-01-09 15:38 ` [PATCH 01/32] xfs: don't call xfs_sb_quota_from_disk twice Christoph Hellwig
2017-01-09 15:38 ` [PATCH 02/32] xfs: check return value of _trans_reserve_quota_nblks Christoph Hellwig
2017-01-09 15:38 ` [PATCH 03/32] xfs: don't skip cow forks w/ delalloc blocks in cowblocks scan Christoph Hellwig
2017-01-09 15:38 ` Christoph Hellwig [this message]
2017-01-09 15:38 ` [PATCH 05/32] xfs: provide helper for counting extents from if_bytes Christoph Hellwig
2017-01-09 15:38 ` [PATCH 06/32] xfs: check minimum block size for CRC filesystems Christoph Hellwig
2017-01-09 15:38 ` [PATCH 07/32] xfs: fix unbalanced inode reclaim flush locking Christoph Hellwig
2017-01-09 15:38 ` [PATCH 08/32] xfs: new inode extent list lookup helpers Christoph Hellwig
2017-01-09 15:38 ` [PATCH 09/32] xfs: factor rmap btree size into the indlen calculations Christoph Hellwig
2017-01-09 15:38 ` [PATCH 10/32] xfs: always succeed when deduping zero bytes Christoph Hellwig
2017-01-09 15:38 ` [PATCH 11/32] xfs: remove prev argument to xfs_bmapi_reserve_delalloc Christoph Hellwig
2017-01-09 15:38 ` [PATCH 12/32] xfs: track preallocation separately in xfs_bmapi_reserve_delalloc() Christoph Hellwig
2017-01-09 15:38 ` [PATCH 13/32] xfs: use new extent lookup helpers in __xfs_reflink_reserve_cow Christoph Hellwig
2017-01-09 15:38 ` [PATCH 14/32] xfs: clean up cow fork reservation and tag inodes correctly Christoph Hellwig
2017-01-09 15:38 ` [PATCH 15/32] xfs: use new extent lookup helpers xfs_file_iomap_begin_delay Christoph Hellwig
2017-01-09 15:38 ` [PATCH 16/32] xfs: pass post-eof speculative prealloc blocks to bmapi Christoph Hellwig
2017-01-09 15:38 ` [PATCH 17/32] xfs: Move AGI buffer type setting to xfs_read_agi Christoph Hellwig
2017-01-09 15:38 ` [PATCH 18/32] xfs: pass state not whichfork to trace_xfs_extlist Christoph Hellwig
2017-01-09 15:38 ` [PATCH 19/32] xfs: handle cow fork in xfs_bmap_trace_exlist Christoph Hellwig
2017-01-09 15:38 ` [PATCH 20/32] xfs: forbid AG btrees with level == 0 Christoph Hellwig
2017-01-09 15:38 ` [PATCH 21/32] xfs: check for bogus values in btree block headers Christoph Hellwig
2017-01-09 15:38 ` [PATCH 22/32] xfs: complain if we don't get nextents bmap records Christoph Hellwig
2017-01-09 15:38 ` [PATCH 23/32] xfs: don't crash if reading a directory results in an unexpected hole Christoph Hellwig
2017-01-09 15:38 ` [PATCH 24/32] xfs: error out if trying to add attrs and anextents > 0 Christoph Hellwig
2017-01-09 15:38 ` [PATCH 25/32] xfs: don't allow di_size with high bit set Christoph Hellwig
2017-01-09 15:38 ` [PATCH 26/32] xfs: don't cap maximum dedupe request length Christoph Hellwig
2017-01-09 15:38 ` [PATCH 27/32] xfs: ignore leaf attr ichdr.count in verifier during log replay Christoph Hellwig
2017-01-09 15:38 ` [PATCH 28/32] xfs: use GPF_NOFS when allocating btree cursors Christoph Hellwig
2017-01-09 15:39 ` [PATCH 29/32] xfs: fix double-cleanup when CUI recovery fails Christoph Hellwig
2017-01-09 15:39 ` [PATCH 30/32] xfs: use the actual AG length when reserving blocks Christoph Hellwig
2017-01-09 15:39 ` [PATCH 31/32] xfs: fix crash and data corruption due to removal of busy COW extents Christoph Hellwig
2017-01-09 15:39 ` [PATCH 32/32] xfs: fix max_retries _show and _store functions Christoph Hellwig
2017-01-10  0:21 ` 4.9-stable updates for XFS Darrick J. Wong
2017-01-10 10:37 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1483976343-661-5-git-send-email-hch@lst.de \
    --to=hch@lst.de \
    --cc=bfoster@redhat.com \
    --cc=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).