From: Allison Henderson <achender@linux.vnet.ibm.com>
To: linux-ext4@vger.kernel.org
Cc: Allison Henderson <achender@linux.vnet.ibm.com>
Subject: [PATCH 3/6 v5] ext4: fix 2nd xfstests 127 punch hole failure
Date: Sat, 20 Aug 2011 19:29:44 -0700 [thread overview]
Message-ID: <1313893787-25460-4-git-send-email-achender@linux.vnet.ibm.com> (raw)
In-Reply-To: <1313893787-25460-1-git-send-email-achender@linux.vnet.ibm.com>
This patch fixes a second punch hole bug found by xfstests 127.
This bug happens because punch hole needs to flush the pages
of the hole to avoid race conditions. But if the end of the
hole is in the same page as i_size, the buffer heads beyond
i_size need to be unmapped and the page needs to be zeroed
after it is flushed.
To correct this, the new ext4_discard_partial_page_buffers
routine is used to zero and unmap the partial page
beyond i_size if the end of the hole appears in the same
page as i_size.
The code has also been optimized to set the end of the hole
to the page after i_size if the specified hole exceeds i_size,
and the code that flushes the pages has been simplified.
Signed-off-by: Allison Henderson <achender@linux.vnet.ibm.com>
---
:100644 100644 cd58117... 0d7617d... M fs/ext4/extents.c
fs/ext4/extents.c | 38 ++++++++++++++++++++++++++++++++++----
1 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index cd58117..0d7617d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4161,6 +4161,20 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t first_page, last_page, first_page_offset, last_page_offset;
int ret, credits, blocks_released, err = 0;
+ /* No need to punch hole beyond i_size */
+ if (offset >= inode->i_size)
+ return 0;
+
+ /*
+ * If the hole extends beyond i_size, set the hole
+ * to end after the page that contains i_size
+ */
+ if (offset + length > inode->i_size) {
+ length = inode->i_size +
+ PAGE_CACHE_SIZE - (inode->i_size & (PAGE_CACHE_SIZE - 1)) -
+ offset;
+ }
+
first_block = (offset + sb->s_blocksize - 1) >>
EXT4_BLOCK_SIZE_BITS(sb);
last_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
@@ -4180,11 +4194,10 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
*/
if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
err = filemap_write_and_wait_range(mapping,
- first_page_offset == 0 ? 0 : first_page_offset-1,
- last_page_offset);
+ offset, offset + length - 1);
- if (err)
- return err;
+ if (err)
+ return err;
}
/* Now release the pages */
@@ -4239,6 +4252,23 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
}
}
+
+ /*
+ * If i_size is contained in the last page, we need to
+ * unmap and zero the partial page after i_size
+ */
+ if (inode->i_size >> PAGE_CACHE_SHIFT == last_page &&
+ inode->i_size % PAGE_CACHE_SIZE != 0) {
+
+ page_len = PAGE_CACHE_SIZE -
+ (inode->i_size & (PAGE_CACHE_SIZE - 1));
+
+ if (page_len > 0) {
+ ext4_discard_partial_page_buffers(handle,
+ mapping, inode->i_size, page_len, 0);
+ }
+ }
+
/* If there are no blocks to remove, return now */
if (first_block >= last_block)
goto out;
--
1.7.1
next prev parent reply other threads:[~2011-08-21 2:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-21 2:29 [PATCH 0/6 v5] ext4: fix 1k block bugs Allison Henderson
2011-08-21 2:29 ` [PATCH 1/6 v5] ext4: Add new ext4_discard_partial_page_buffers routines Allison Henderson
2011-08-22 2:38 ` Ted Ts'o
2011-08-22 14:33 ` Allison Henderson
2011-08-21 2:29 ` [PATCH 2/6 v5] ext4: fix xfstests 75, 112, 127 punch hole failure Allison Henderson
2011-08-21 2:29 ` Allison Henderson [this message]
2011-08-21 2:29 ` [PATCH 4/6 v5] ext4: Correct large hole offset calcuation Allison Henderson
2011-08-22 15:50 ` Eric Sandeen
2011-08-22 17:19 ` Allison Henderson
2011-08-21 2:29 ` [PATCH 5/6 v5] ext4: fix fsx truncate failure Allison Henderson
2011-08-23 2:36 ` Ted Ts'o
2011-08-23 2:51 ` Allison Henderson
2011-08-21 2:29 ` [PATCH 6/6 v5] ext4: fix partial page writes Allison Henderson
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=1313893787-25460-4-git-send-email-achender@linux.vnet.ibm.com \
--to=achender@linux.vnet.ibm.com \
--cc=linux-ext4@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).