diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/extents.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 9b9251adb400..d6bca2a1debe 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -5395,7 +5395,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5395 | ext4_lblk_t punch_start, punch_stop; | 5395 | ext4_lblk_t punch_start, punch_stop; |
5396 | handle_t *handle; | 5396 | handle_t *handle; |
5397 | unsigned int credits; | 5397 | unsigned int credits; |
5398 | loff_t new_size; | 5398 | loff_t new_size, ioffset; |
5399 | int ret; | 5399 | int ret; |
5400 | 5400 | ||
5401 | /* Collapse range works only on fs block size aligned offsets. */ | 5401 | /* Collapse range works only on fs block size aligned offsets. */ |
@@ -5418,8 +5418,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5418 | return ret; | 5418 | return ret; |
5419 | } | 5419 | } |
5420 | 5420 | ||
5421 | /* | ||
5422 | * Need to round down offset to be aligned with page size boundary | ||
5423 | * for page size > block size. | ||
5424 | */ | ||
5425 | ioffset = round_down(offset, PAGE_SIZE); | ||
5426 | |||
5421 | /* Write out all dirty pages */ | 5427 | /* Write out all dirty pages */ |
5422 | ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); | 5428 | ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, |
5429 | LLONG_MAX); | ||
5423 | if (ret) | 5430 | if (ret) |
5424 | return ret; | 5431 | return ret; |
5425 | 5432 | ||
@@ -5441,7 +5448,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) | |||
5441 | goto out_mutex; | 5448 | goto out_mutex; |
5442 | } | 5449 | } |
5443 | 5450 | ||
5444 | truncate_pagecache(inode, offset); | 5451 | truncate_pagecache(inode, ioffset); |
5445 | 5452 | ||
5446 | /* Wait for existing dio to complete */ | 5453 | /* Wait for existing dio to complete */ |
5447 | ext4_inode_block_unlocked_dio(inode); | 5454 | ext4_inode_block_unlocked_dio(inode); |