btrfs: only update i_size in truncate paths that care
We currently will update the i_size of the inode as we truncate it down, however we skip this if we're calling btrfs_truncate_inode_items from the tree log code. However we also don't care about this in the case of evict. Instead keep track of this value in the btrfs_truncate_control and then have btrfs_truncate() and the free space cache truncate path both do the i_size update themselves. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
d9ac19c380
Коммит
c2ddb612a8
|
@ -338,6 +338,9 @@ int btrfs_truncate_free_space_cache(struct btrfs_trans_handle *trans,
|
|||
* need to check for -EAGAIN.
|
||||
*/
|
||||
ret = btrfs_truncate_inode_items(trans, root, inode, &control);
|
||||
|
||||
btrfs_inode_safe_disk_i_size_write(inode, control.last_size);
|
||||
|
||||
unlock_extent_cached(&inode->io_tree, 0, (u64)-1, &cached_state);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
|
|
@ -452,7 +452,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||
u64 extent_num_bytes = 0;
|
||||
u64 extent_offset = 0;
|
||||
u64 item_end = 0;
|
||||
u64 last_size = new_size;
|
||||
u32 found_type = (u8)-1;
|
||||
int del_item;
|
||||
int pending_del_nr = 0;
|
||||
|
@ -466,6 +465,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
|
|||
|
||||
BUG_ON(new_size > 0 && control->min_type != BTRFS_EXTENT_DATA_KEY);
|
||||
|
||||
control->last_size = new_size;
|
||||
|
||||
/*
|
||||
* For shareable roots we want to back off from time to time, this turns
|
||||
* out to be subvolume roots, reloc roots, and data reloc roots.
|
||||
|
@ -644,9 +645,9 @@ delete:
|
|||
}
|
||||
|
||||
if (del_item)
|
||||
last_size = found_key.offset;
|
||||
control->last_size = found_key.offset;
|
||||
else
|
||||
last_size = new_size;
|
||||
control->last_size = new_size;
|
||||
if (del_item) {
|
||||
if (!pending_del_nr) {
|
||||
/* No pending yet, add ourselves */
|
||||
|
@ -739,12 +740,10 @@ out:
|
|||
ret = err;
|
||||
}
|
||||
}
|
||||
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
|
||||
ASSERT(last_size >= new_size);
|
||||
if (!ret && last_size > new_size)
|
||||
last_size = new_size;
|
||||
btrfs_inode_safe_disk_i_size_write(inode, last_size);
|
||||
}
|
||||
|
||||
ASSERT(control->last_size >= new_size);
|
||||
if (!ret && control->last_size > new_size)
|
||||
control->last_size = new_size;
|
||||
|
||||
btrfs_free_path(path);
|
||||
return ret;
|
||||
|
|
|
@ -26,6 +26,9 @@ struct btrfs_truncate_control {
|
|||
/* OUT: the number of extents truncated. */
|
||||
u64 extents_found;
|
||||
|
||||
/* OUT: the last size we truncated this inode to. */
|
||||
u64 last_size;
|
||||
|
||||
/*
|
||||
* IN: minimum key type to remove. All key types with this type are
|
||||
* removed only if their offset >= new_size.
|
||||
|
|
|
@ -8620,6 +8620,9 @@ static int btrfs_truncate(struct inode *inode, bool skip_writeback)
|
|||
|
||||
ret = btrfs_truncate_inode_items(trans, root, BTRFS_I(inode),
|
||||
&control);
|
||||
|
||||
btrfs_inode_safe_disk_i_size_write(BTRFS_I(inode), control.last_size);
|
||||
|
||||
unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start,
|
||||
(u64)-1, &cached_state);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче