From: Liu Bo <bo.li.liu@oracle.com>
To: linux-btrfs@vger.kernel.org
Cc: David Sterba <dsterba@suse.cz>, Qu Wenruo <quwenruo@cn.fujitsu.com>
Subject: [PATCH v2] Btrfs: fix unexpected file hole after disk errors
Date: Mon, 6 Mar 2017 12:23:30 -0800 [thread overview]
Message-ID: <1488831810-26684-1-git-send-email-bo.li.liu@oracle.com> (raw)
In-Reply-To: <1488330280-22678-1-git-send-email-bo.li.liu@oracle.com>
Btrfs creates hole extents to cover any unwritten section right before
doing buffer writes after commit 3ac0d7b96a26 ("btrfs: Change the expanding
write sequence to fix snapshot related bug.").
However, that takes the start position of the buffered write to compare
against the current EOF, hole extents would be created only if (EOF <
start).
If the EOF is at the middle of the buffered write, no hole extents will be
created and a file hole without a hole extent is left in this file.
This bug was revealed by generic/019 in fstests. 'fsstress' in this test
may create the above situation and the test then fails all requests
including writes, so the buffer write which is supposed to cover the
hole (without the hole extent) couldn't make it on disk. Running fsck
against such btrfs ends up with detecting file extent holes.
Things could be more serious, some stale data would be exposed to
userspace if files with this kind of hole are truncated to a position of
the hole, because the on-disk inode size is beyond the last extent in the
file.
This fixes the bug by comparing the end position against the EOF.
Cc: David Sterba <dsterba@suse.cz>
Cc: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
---
v2: update comments to be precise.
fs/btrfs/file.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 520cb72..dcf0286 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1865,11 +1865,13 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
pos = iocb->ki_pos;
count = iov_iter_count(from);
start_pos = round_down(pos, fs_info->sectorsize);
+ end_pos = round_up(pos + count, fs_info->sectorsize);
oldsize = i_size_read(inode);
- if (start_pos > oldsize) {
- /* Expand hole size to cover write data, preventing empty gap */
- end_pos = round_up(pos + count,
- fs_info->sectorsize);
+ if (end_pos > oldsize) {
+ /*
+ * Expand hole size to cover write data in order to prevent an
+ * empty gap in case of a write failure.
+ */
err = btrfs_cont_expand(inode, oldsize, end_pos);
if (err) {
inode_unlock(inode);
--
2.5.5
next prev parent reply other threads:[~2017-03-06 22:18 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-01 1:04 [PATCH 1/2] Btrfs: fix unexpected file hole after disk errors Liu Bo
2017-03-01 1:04 ` [PATCH 2/2] Btrfs: remove start_pos Liu Bo
2017-03-01 8:48 ` Qu Wenruo
2017-03-06 21:09 ` Liu Bo
2017-03-01 2:44 ` [PATCH 1/2] Btrfs: fix unexpected file hole after disk errors Qu Wenruo
2017-03-06 19:27 ` Liu Bo
2017-03-01 5:22 ` Qu Wenruo
2017-03-06 20:23 ` Liu Bo [this message]
2017-03-07 0:28 ` [PATCH v2] " Qu Wenruo
2017-03-28 12:50 ` David Sterba
2017-03-28 18:40 ` Liu Bo
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=1488831810-26684-1-git-send-email-bo.li.liu@oracle.com \
--to=bo.li.liu@oracle.com \
--cc=dsterba@suse.cz \
--cc=linux-btrfs@vger.kernel.org \
--cc=quwenruo@cn.fujitsu.com \
/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).