Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 331621
b: refs/heads/master
c: 02d262d
h: refs/heads/master
i:
  331619: 1aea125
v: v3
  • Loading branch information
Dmitry Monakhov authored and Theodore Ts'o committed Oct 1, 2012
1 parent 4d5fca2 commit 7995a44
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 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: 1f555cfa29e8f787d675e8390f88ce517a37271a
refs/heads/master: 02d262dffcf4c74e5c4612ee736bdb94f18ed5b9
53 changes: 36 additions & 17 deletions trunk/fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -4794,9 +4794,32 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
loff_t first_page_offset, last_page_offset;
int credits, err = 0;

/*
* Write out all dirty pages to avoid race conditions
* Then release them.
*/
if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
err = filemap_write_and_wait_range(mapping,
offset, offset + length - 1);

if (err)
return err;
}

mutex_lock(&inode->i_mutex);
/* It's not possible punch hole on append only file */
if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
err = -EPERM;
goto out_mutex;
}
if (IS_SWAPFILE(inode)) {
err = -ETXTBSY;
goto out_mutex;
}

/* No need to punch hole beyond i_size */
if (offset >= inode->i_size)
return 0;
goto out_mutex;

/*
* If the hole extends beyond i_size, set the hole
Expand All @@ -4814,33 +4837,25 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
first_page_offset = first_page << PAGE_CACHE_SHIFT;
last_page_offset = last_page << PAGE_CACHE_SHIFT;

/*
* Write out all dirty pages to avoid race conditions
* Then release them.
*/
if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
err = filemap_write_and_wait_range(mapping,
offset, offset + length - 1);

if (err)
return err;
}

/* Now release the pages */
if (last_page_offset > first_page_offset) {
truncate_pagecache_range(inode, first_page_offset,
last_page_offset - 1);
}

/* finish any pending end_io work */
/* Wait all existing dio workers, newcomers will block on i_mutex */
ext4_inode_block_unlocked_dio(inode);
inode_dio_wait(inode);
err = ext4_flush_completed_IO(inode);
if (err)
return err;
goto out_dio;

credits = ext4_writepage_trans_blocks(inode);
handle = ext4_journal_start(inode, credits);
if (IS_ERR(handle))
return PTR_ERR(handle);
if (IS_ERR(handle)) {
err = PTR_ERR(handle);
goto out_dio;
}


/*
Expand Down Expand Up @@ -4930,6 +4945,10 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length)
inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
ext4_mark_inode_dirty(handle, inode);
ext4_journal_stop(handle);
out_dio:
ext4_inode_resume_unlocked_dio(inode);
out_mutex:
mutex_unlock(&inode->i_mutex);
return err;
}
int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
Expand Down

0 comments on commit 7995a44

Please sign in to comment.