Commit c2ddb612 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba
Browse files

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: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent d9ac19c3
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
+8 −9
Original line number Diff line number Diff line
@@ -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 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
		}

		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 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
			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;
+3 −0
Original line number Diff line number Diff line
@@ -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.
+3 −0
Original line number Diff line number Diff line
@@ -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);