Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 273098
b: refs/heads/master
c: 2be4751
h: refs/heads/master
v: v3
  • Loading branch information
Allison Henderson authored and Theodore Ts'o committed Sep 3, 2011
1 parent a67ff5c commit 7071820
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ba06208a1315ab2d2217e09c79582b886c9f629e
refs/heads/master: 2be4751b21ae1cacb002da48cfc5bf6743fee8c1
41 changes: 37 additions & 4 deletions trunk/fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -4166,6 +4166,20 @@ 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;
}

first_block = (offset + sb->s_blocksize - 1) >>
EXT4_BLOCK_SIZE_BITS(sb);
last_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb);
Expand All @@ -4182,11 +4196,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 */
Expand Down Expand Up @@ -4249,6 +4262,26 @@ 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;
}
}

/* If there are no blocks to remove, return now */
if (first_block >= last_block)
goto out;
Expand Down

0 comments on commit 7071820

Please sign in to comment.