From: Jan Kara <jack@suse.com>
To: linux-ext4@vger.kernel.org
Cc: Ted Tso <tytso@mit.edu>, Dan Williams <dan.j.williams@intel.com>,
ross.zwisler@linux.intel.com, willy@linux.intel.com,
Jan Kara <jack@suse.com>
Subject: [PATCH 4/9] ext4: Fix races of writeback with punch hole and zero range
Date: Thu, 22 Oct 2015 10:15:56 +0200 [thread overview]
Message-ID: <1445501761-14528-5-git-send-email-jack@suse.com> (raw)
In-Reply-To: <1445501761-14528-1-git-send-email-jack@suse.com>
When doing delayed allocation, update of on-disk inode size is postponed
until IO submission time. However hole punch or zero range fallocate
calls can end up discarding the tail page cache page and thus on-disk
inode size would never be properly updated.
Make sure the on-disk inode size is updated before truncating page
cache.
Signed-off-by: Jan Kara <jack@suse.com>
---
fs/ext4/ext4.h | 3 +++
fs/ext4/extents.c | 5 +++++
fs/ext4/inode.c | 35 ++++++++++++++++++++++++++++++++++-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c19ff61ccbdf..c86546efec30 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2691,6 +2691,9 @@ static inline int ext4_update_inode_size(struct inode *inode, loff_t newsize)
return changed;
}
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+ loff_t len);
+
struct ext4_group_info {
unsigned long bb_state;
struct rb_root bb_free_root;
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 892245a55c53..9977b557d50d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4843,6 +4843,11 @@ static long ext4_zero_range(struct file *file, loff_t offset,
* released from page cache.
*/
down_write(&EXT4_I(inode)->i_mmap_sem);
+ ret = ext4_update_disksize_before_punch(inode, offset, len);
+ if (ret) {
+ up_write(&EXT4_I(inode)->i_mmap_sem);
+ goto out_dio;
+ }
/* Now release the pages and zero block aligned part of pages */
truncate_pagecache_range(inode, start, end - 1);
inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 36ad45906d26..f72212ef1fee 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3517,6 +3517,35 @@ int ext4_can_truncate(struct inode *inode)
}
/*
+ * We have to make sure i_disksize gets properly updated before we truncate
+ * page cache due to hole punching or zero range. Otherwise i_disksize update
+ * can get lost as it may have been postponed to submission of writeback but
+ * that will never happen after we truncate page cache.
+ */
+int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+ loff_t len)
+{
+ handle_t *handle;
+ loff_t size = i_size_read(inode);
+
+ WARN_ON(!mutex_is_locked(&inode->i_mutex));
+ if (offset > size || offset + len < size)
+ return 0;
+
+ if (EXT4_I(inode)->i_disksize >= size)
+ return 0;
+
+ handle = ext4_journal_start(inode, EXT4_HT_MISC, 1);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ ext4_update_i_disksize(inode, size);
+ ext4_mark_inode_dirty(handle, inode);
+ ext4_journal_stop(handle);
+
+ return 0;
+}
+
+/*
* ext4_punch_hole: punches a hole in a file by releaseing the blocks
* associated with the given offset and length
*
@@ -3594,9 +3623,13 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
last_block_offset = round_down((offset + length), sb->s_blocksize) - 1;
/* Now release the pages and zero block aligned part of pages*/
- if (last_block_offset > first_block_offset)
+ if (last_block_offset > first_block_offset) {
+ ret = ext4_update_disksize_before_punch(inode, offset, length);
+ if (ret)
+ goto out_dio;
truncate_pagecache_range(inode, first_block_offset,
last_block_offset);
+ }
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
credits = ext4_writepage_trans_blocks(inode);
--
2.1.4
next prev parent reply other threads:[~2015-10-22 8:16 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-22 8:15 [PATCH 0/9 v2] ext4: Punch hole and DAX fixes Jan Kara
2015-10-22 8:15 ` [PATCH 1/9] ext4: Fix races between page faults and hole punching Jan Kara
2015-10-24 1:21 ` Theodore Ts'o
2015-10-25 4:58 ` Jan Kara
2015-10-22 8:15 ` [PATCH 2/9] ext4: Move unlocked dio protection from ext4_alloc_file_blocks() Jan Kara
2015-10-22 8:15 ` [PATCH 3/9] ext4: Fix races between buffered IO and collapse / insert range Jan Kara
2015-10-24 1:22 ` Theodore Ts'o
2015-10-24 4:59 ` Theodore Ts'o
2015-10-22 8:15 ` Jan Kara [this message]
2015-10-22 8:15 ` [PATCH 5/9] ext4: Document lock ordering Jan Kara
2015-10-22 8:15 ` [PATCH 6/9] ext4: Get rid of EXT4_GET_BLOCKS_NO_LOCK flag Jan Kara
2015-10-22 8:15 ` [PATCH 7/9] ext4: Provide ext4_issue_zeroout() Jan Kara
2015-10-22 8:16 ` [PATCH 8/9] ext4: Implement allocation of pre-zeroed blocks Jan Kara
2015-10-22 8:16 ` [PATCH 9/9] ext4: Use pre-zeroed blocks for DAX page faults Jan Kara
2015-10-25 9:23 ` Theodore Ts'o
2015-10-22 18:09 ` [PATCH 0/9 v2] ext4: Punch hole and DAX fixes Ross Zwisler
2015-10-22 21:14 ` Jan Kara
2015-10-23 3:35 ` Eryu Guan
-- strict thread matches above, loose matches on Subject: below --
2015-11-04 16:18 [PATCH 0/9 v3] " Jan Kara
2015-11-04 16:18 ` [PATCH 4/9] ext4: Fix races of writeback with punch hole and zero range Jan Kara
2015-11-10 19:50 [PATCH 0/9 v4] ext4: Punch hole and DAX fixes Jan Kara
2015-11-10 19:50 ` [PATCH 4/9] ext4: Fix races of writeback with punch hole and zero range Jan Kara
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=1445501761-14528-5-git-send-email-jack@suse.com \
--to=jack@suse.com \
--cc=dan.j.williams@intel.com \
--cc=linux-ext4@vger.kernel.org \
--cc=ross.zwisler@linux.intel.com \
--cc=tytso@mit.edu \
--cc=willy@linux.intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.