Commit f1e490a7 authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason

Btrfs: set i_size properly when fallocating and we already

xfstests exposed a problem with preallocate when it fallocates a range that
already has an extent.  We don't set the new i_size properly because we see that
we already have an extent.  This isn't right and we should update i_size if the
space already exists.  With this patch we now pass xfstests 075.  Thanks,
Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent f81c9cdc
...@@ -1631,11 +1631,15 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1631,11 +1631,15 @@ static long btrfs_fallocate(struct file *file, int mode,
cur_offset = alloc_start; cur_offset = alloc_start;
while (1) { while (1) {
u64 actual_end;
em = btrfs_get_extent(inode, NULL, 0, cur_offset, em = btrfs_get_extent(inode, NULL, 0, cur_offset,
alloc_end - cur_offset, 0); alloc_end - cur_offset, 0);
BUG_ON(IS_ERR_OR_NULL(em)); BUG_ON(IS_ERR_OR_NULL(em));
last_byte = min(extent_map_end(em), alloc_end); last_byte = min(extent_map_end(em), alloc_end);
actual_end = min_t(u64, extent_map_end(em), offset + len);
last_byte = (last_byte + mask) & ~mask; last_byte = (last_byte + mask) & ~mask;
if (em->block_start == EXTENT_MAP_HOLE || if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size && (cur_offset >= inode->i_size &&
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
...@@ -1648,6 +1652,16 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1648,6 +1652,16 @@ static long btrfs_fallocate(struct file *file, int mode,
free_extent_map(em); free_extent_map(em);
break; break;
} }
} else if (actual_end > inode->i_size &&
!(mode & FALLOC_FL_KEEP_SIZE)) {
/*
* We didn't need to allocate any more space, but we
* still extended the size of the file so we need to
* update i_size.
*/
inode->i_ctime = CURRENT_TIME;
i_size_write(inode, actual_end);
btrfs_ordered_update_i_size(inode, actual_end, NULL);
} }
free_extent_map(em); free_extent_map(em);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment