Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

authored by

Josef Bacik and committed by
Chris Mason
f1e490a7 f81c9cdc

+14
+14
fs/btrfs/file.c
··· 1631 1631 1632 1632 cur_offset = alloc_start; 1633 1633 while (1) { 1634 + u64 actual_end; 1635 + 1634 1636 em = btrfs_get_extent(inode, NULL, 0, cur_offset, 1635 1637 alloc_end - cur_offset, 0); 1636 1638 BUG_ON(IS_ERR_OR_NULL(em)); 1637 1639 last_byte = min(extent_map_end(em), alloc_end); 1640 + actual_end = min_t(u64, extent_map_end(em), offset + len); 1638 1641 last_byte = (last_byte + mask) & ~mask; 1642 + 1639 1643 if (em->block_start == EXTENT_MAP_HOLE || 1640 1644 (cur_offset >= inode->i_size && 1641 1645 !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { ··· 1652 1648 free_extent_map(em); 1653 1649 break; 1654 1650 } 1651 + } else if (actual_end > inode->i_size && 1652 + !(mode & FALLOC_FL_KEEP_SIZE)) { 1653 + /* 1654 + * We didn't need to allocate any more space, but we 1655 + * still extended the size of the file so we need to 1656 + * update i_size. 1657 + */ 1658 + inode->i_ctime = CURRENT_TIME; 1659 + i_size_write(inode, actual_end); 1660 + btrfs_ordered_update_i_size(inode, actual_end, NULL); 1655 1661 } 1656 1662 free_extent_map(em); 1657 1663