@@ -323,6 +323,4 @@ static inline void btrfs_inode_resume_unlocked_dio(struct inode *inode)
&BTRFS_I(inode)->runtime_flags);
}
-bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end);
-
#endif
@@ -2439,7 +2439,9 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
if ((!ordered ||
(ordered->file_offset + ordered->len <= lockstart ||
ordered->file_offset > lockend)) &&
- !btrfs_page_exists_in_range(inode, lockstart, lockend)) {
+ !test_range_bit(&BTRFS_I(inode)->io_tree, lockstart,
+ lockend, EXTENT_UPTODATE, 0,
+ cached_state)) {
if (ordered)
btrfs_put_ordered_extent(ordered);
break;
@@ -7434,7 +7434,8 @@ out:
return ret;
}
-bool btrfs_page_exists_in_range(struct inode *inode, loff_t start, loff_t end)
+static bool btrfs_page_exists_in_range(struct inode *inode, loff_t start,
+ loff_t end)
{
struct radix_tree_root *root = &inode->i_mapping->page_tree;
int found = false;
In subpagesize-blocksize, we have multiple blocks in a page. Checking for existence of a page in the page cache isn't a sufficient check, since we could be truncating a subset of the blocks mapped by the page. So if the blocks that are neighboring the truncated block exist in the page cache, btrfs_page_exists_in_range() would always return 1. Hence check for the existence of EXTENT_UPTODATE bit on the file range mapped by the block being punched out. Signed-off-by: Chandan Rajendra <chandan@linux.vnet.ibm.com> --- fs/btrfs/btrfs_inode.h | 2 -- fs/btrfs/file.c | 4 +++- fs/btrfs/inode.c | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-)