Ext4 Punch Hole Support: Clear Hole
PATCH v7 2/5 Ext4 Punch Hole Support: Clear Hole
This patch adds routines needed to zero out the unblock aligned data of the hole.
The existing ext4_block_truncate_page routine that is used to zero out unblock aligned data from truncate has been modified to accept a length parameter, and renamed to ext4_block_zero_page_range.
The function can now be used to zero out the head of a block, the tail of a block, or the middle of a block. The existing ext4_block_truncate_page has now become a wrapper to this function
---
:100644 100644 3ba6c31... 95efb4e... M fs/ext4/ext4.h
:100644 100644 f92c58b... 8ce382d... M fs/ext4/inode.c
fs/ext4/ext4.h | 2 ++ fs/ext4/inode.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-)
fs/ext4/ext4.h +2 -0
@@ -1758,6 +1758,8 @@ extern int ext4_writepage_trans_blocks(struct inode *);extern int ext4_chunk_trans_blocks (struct inode *,int nrblocks);extern int ext4_block_truncate_page (handle_t *handle,struct address_space *mapping,loff_t from); +extern int ext4_block_zero_page_range (handle_t *handle, +struct address_space *mapping,loff_t from,loff_t length);extern int ext4_page_mkwrite (struct vm_area_struct *vma,struct vm_fault *vmf);extern qsize_t *ext4_get_reserved_space (struct inode *inode); extern void ext4_da_update_reserve_space(struct inode *inode,
fs/ext4/inode.c +31 -2
@@ -3916,9 +3916,30 @@ void ext4_set_aops(struct inode *inode)int ext4_block_truncate_page (handle_t *handle,struct address_space *mapping,loff_t from) { +unsigned offset = from & (PAGE_CACHE_SIZE -1 ); +unsigned length; +unsigned blocksize; +struct inode *inode = mapping->host; + + blocksize = inode->i_sb->s_blocksize; + length = blocksize - (offset & (blocksize -1 )); + +return ext4_block_zero_page_range (handle, mapping, from, length); +} + +/* +* ext4_block_zero_page_range() zeros out a mapping of length 'length' +* starting from file offset 'from'. The range to be zero'd must +* be contained with in one block. If the specified range exceeds +* the end of the block it will be shortened to end of the block +* that cooresponds to 'from' +*/ +int ext4_block_zero_page_range (handle_t *handle, +struct address_space *mapping,loff_t from,loff_t length) +{ext4_fsblk_t index = from >>PAGE_CACHE_SHIFT ;unsigned offset = from & (PAGE_CACHE_SIZE -1 ); -unsigned blocksize, length, pos; +unsigned blocksize, max, pos;ext4_lblk_t iblock;struct inode *inode = mapping->host;struct buffer_head *bh;
@@ -3931,7 +3952,15 @@ int ext4_block_truncate_page(handle_t *handle,return -EINVAL ; blocksize = inode->i_sb->s_blocksize; - length = blocksize - (offset & (blocksize -1 )); + max = blocksize - (offset & (blocksize -1 )); + +/* +* correct length if it does not fall between +* 'from' and the end of the block +*/ +if (length > max || length <0 ) + length = max; + iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);if (!page_has_buffers (page))
Signature · 1 line
1.7.1
Quoted 8 lines · Allison Henderson
This patch adds routines needed to zero out the unblock aligned data of the hole.
The existing
ext4_block_truncate_pageroutine that is used to zero out unblock aligned data from truncate has been modified to accept a length parameter, and renamed toext4_block_zero_page_range.
Quoted 6 lines
The function can now be used to zero out the head of a block, the tail of a block, or the middle of a block. The existing
ext4_block_truncate_pagehas now become a wrapper to this functionSigned-off-by Allison Henderson <[email protected]>
I have looked at this patch before, so you could add my reviewed-by here too.
Quoted 73 lines
---
:100644 100644 3ba6c31... 95efb4e... Mfs/ext4/ext4.h
:100644 100644 f92c58b... 8ce382d... Mfs/ext4/inode.cfs/ext4/ext4.h | 2 ++ fs/ext4/inode.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-)fs/ext4/ext4.h +2
-0@@ -1758,6 +1758,8 @@ extern int ext4_writepage_trans_blocks(struct inode *);extern int ext4_chunk_trans_blocks (struct inode *,int nrblocks);extern int ext4_block_truncate_page (handle_t *handle,struct address_space *mapping,loff_t from); +extern int ext4_block_zero_page_range (handle_t *handle, +struct address_space *mapping,loff_t from,loff_t length);extern int ext4_page_mkwrite (struct vm_area_struct *vma,struct vm_fault *vmf);extern qsize_t *ext4_get_reserved_space (struct inode *inode); extern void ext4_da_update_reserve_space(struct inode *inode,fs/ext4/inode.c +31
-2@@ -3916,9 +3916,30 @@ void ext4_set_aops(struct inode *inode)int ext4_block_truncate_page (handle_t *handle,struct address_space *mapping,loff_t from) { +unsigned offset = from & (PAGE_CACHE_SIZE -1 ); +unsigned length; +unsigned blocksize; +struct inode *inode = mapping->host; + + blocksize = inode->i_sb->s_blocksize; + length = blocksize - (offset & (blocksize -1 )); + +return ext4_block_zero_page_range (handle, mapping, from, length); +} + +/* +* ext4_block_zero_page_range() zeros out a mapping of length 'length' +* starting from file offset 'from'. The range to be zero'd must +* be contained with in one block. If the specified range exceeds +* the end of the block it will be shortened to end of the block +* that cooresponds to 'from' +*/ +int ext4_block_zero_page_range (handle_t *handle, +struct address_space *mapping,loff_t from,loff_t length) +{ext4_fsblk_t index = from >>PAGE_CACHE_SHIFT ;unsigned offset = from & (PAGE_CACHE_SIZE -1 ); -unsigned blocksize, length, pos; +unsigned blocksize, max, pos;ext4_lblk_t iblock;struct inode *inode = mapping->host;struct buffer_head *bh;@@ -3931,7 +3952,15 @@ int ext4_block_truncate_page(handle_t *handle,return -EINVAL ; blocksize = inode->i_sb->s_blocksize; - length = blocksize - (offset & (blocksize -1 )); + max = blocksize - (offset & (blocksize -1 )); + +/* +* correct length if it does not fall between +* 'from' and the end of the block +*/ +if (length > max || length <0 ) + length = max; + iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);if (!page_has_buffers (page))