2012-01-14 19:29:22

by Allison Henderson

[permalink] [raw]
Subject: [PATCH 0/3] ext4: punch hole beyond i_size

This patch set allows punch hole to punch beyond i_size.
Additionally some uneeded code has been removed, and
some return codes in ext4_punch_hole has been corrected.

Allison Henderson (3):
ext4: Allow punch hole beyond i_size
ext4: Remove uneeded i_size handling
ext4: Correct ext4_punch_hole return codes

fs/ext4/extents.c | 34 ----------------------------------
fs/ext4/inode.c | 6 +++---
2 files changed, 3 insertions(+), 37 deletions(-)



2012-01-14 19:29:24

by Allison Henderson

[permalink] [raw]
Subject: [PATCH 3/3] ext4: Correct ext4_punch_hole return codes

ext4_punch_hole returns -ENOTSUPP but it should
be using -EOPNOTSUPP

Signed-off-by: Allison Henderson <[email protected]>
---
:100644 100644 1380cd2... 38d8022... M fs/ext4/inode.c
fs/ext4/inode.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 1380cd2..38d8022 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3466,16 +3466,16 @@ int ext4_punch_hole(struct file *file, loff_t offset, loff_t length)
{
struct inode *inode = file->f_path.dentry->d_inode;
if (!S_ISREG(inode->i_mode))
- return -ENOTSUPP;
+ return -EOPNOTSUPP;

if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
/* TODO: Add support for non extent hole punching */
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}

if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) {
/* TODO: Add support for bigalloc file systems */
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
}

return ext4_ext_punch_hole(file, offset, length);
--
1.7.1


2012-01-14 19:29:23

by Allison Henderson

[permalink] [raw]
Subject: [PATCH 2/3] ext4: Remove uneeded i_size handling

This patch removes a fix that is now being addressed in another
patch. The code being removed also made the assumption that a
hole cannot exceed or start after i_size, but since this is no
longer the case and the source of the bug has been corrected in
a different patch, this code is no longer needed.

The removed code initally corrected a bug found in fsx,
where garbage data would appear in the last page after i_size, when
ever a hole ended in the same page as i_size. The cause of the cause
of the garbage data has been fixed in patch
"[PATCH 2/2] ext4: let ext4_bio_write_page handle EOF correctly"

This patch set has been tested with fsx on a 1k block size, and
successfully passed 24 hours.

Signed-off-by: Allison Henderson <[email protected]>
---
:100644 100644 9ec6249... e607880... M fs/ext4/extents.c
fs/ext4/extents.c | 20 --------------------
1 files changed, 0 insertions(+), 20 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 9ec6249..e607880 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4786,26 +4786,6 @@ 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) {
- err = ext4_discard_partial_page_buffers(handle,
- mapping, inode->i_size, page_len, 0);
-
- if (err)
- goto out;
- }
- }

2012-01-14 19:29:24

by Allison Henderson

[permalink] [raw]
Subject: [PATCH 1/3] ext4: Allow punch hole beyond i_size

This patch allows blocks beyond i_size to be punched out.
This early return to catch this condition is simply removed
allowing punch hole to proceed beyond i_size.

Signed-off-by: Allison Henderson <[email protected]>
---
:100644 100644 ad39627... 9ec6249... M fs/ext4/extents.c
fs/ext4/extents.c | 14 --------------
1 files changed, 0 insertions(+), 14 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index ad39627..9ec6249 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -4704,20 +4704,6 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t 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;
- }