aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/file.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 0705d15542c..15e5a1cd876 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1631,11 +1631,15 @@ static long btrfs_fallocate(struct file *file, int mode,
1631 1631
1632 cur_offset = alloc_start; 1632 cur_offset = alloc_start;
1633 while (1) { 1633 while (1) {
1634 u64 actual_end;
1635
1634 em = btrfs_get_extent(inode, NULL, 0, cur_offset, 1636 em = btrfs_get_extent(inode, NULL, 0, cur_offset,
1635 alloc_end - cur_offset, 0); 1637 alloc_end - cur_offset, 0);
1636 BUG_ON(IS_ERR_OR_NULL(em)); 1638 BUG_ON(IS_ERR_OR_NULL(em));
1637 last_byte = min(extent_map_end(em), alloc_end); 1639 last_byte = min(extent_map_end(em), alloc_end);
1640 actual_end = min_t(u64, extent_map_end(em), offset + len);
1638 last_byte = (last_byte + mask) & ~mask; 1641 last_byte = (last_byte + mask) & ~mask;
1642
1639 if (em->block_start == EXTENT_MAP_HOLE || 1643 if (em->block_start == EXTENT_MAP_HOLE ||
1640 (cur_offset >= inode->i_size && 1644 (cur_offset >= inode->i_size &&
1641 !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { 1645 !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
@@ -1648,6 +1652,16 @@ static long btrfs_fallocate(struct file *file, int mode,
1648 free_extent_map(em); 1652 free_extent_map(em);
1649 break; 1653 break;
1650 } 1654 }
1655 } else if (actual_end > inode->i_size &&
1656 !(mode & FALLOC_FL_KEEP_SIZE)) {
1657 /*
1658 * We didn't need to allocate any more space, but we
1659 * still extended the size of the file so we need to
1660 * update i_size.
1661 */
1662 inode->i_ctime = CURRENT_TIME;
1663 i_size_write(inode, actual_end);
1664 btrfs_ordered_update_i_size(inode, actual_end, NULL);
1651 } 1665 }
1652 free_extent_map(em); 1666 free_extent_map(em);
1653 1667