Commit 00f5c795 authored by Chris Mason's avatar Chris Mason
Browse files

btrfs_drop_extents: make sure the item is getting smaller before truncate

parent ca664626
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1037,7 +1037,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end);
extern struct file_operations btrfs_file_operations;
int btrfs_drop_extents(struct btrfs_trans_handle *trans,
		       struct btrfs_root *root, struct inode *inode,
		       u64 start, u64 end, u64 inline_end, u64 *hint_block);
		       u64 start, u64 end, u64 inline_limit, u64 *hint_block);
/* tree-defrag.c */
int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
			struct btrfs_root *root, int cache_only);
+8 −0
Original line number Diff line number Diff line
@@ -45,6 +45,9 @@ static int cache_block_group(struct btrfs_root *root,
	u64 first_free;
	int found = 0;

	if (!block_group)
		return 0;

	root = root->fs_info->extent_root;
	free_space_cache = &root->fs_info->free_space_cache;

@@ -168,6 +171,11 @@ static u64 find_search_start(struct btrfs_root *root,
	u64 cache_miss = 0;
	int wrapped = 0;

	if (!cache) {
		cache = btrfs_lookup_block_group(root->fs_info, search_start);
		if (!cache)
			return search_start;
	}
again:
	ret = cache_block_group(root, cache);
	if (ret)
+15 −15
Original line number Diff line number Diff line
@@ -377,23 +377,23 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
 */
int btrfs_drop_extents(struct btrfs_trans_handle *trans,
		       struct btrfs_root *root, struct inode *inode,
		       u64 start, u64 end, u64 inline_end, u64 *hint_byte)
		       u64 start, u64 end, u64 inline_limit, u64 *hint_byte)
{
	int ret;
	struct btrfs_key key;
	u64 extent_end = 0;
	u64 search_start = start;
	struct extent_buffer *leaf;
	int slot;
	struct btrfs_file_extent_item *extent;
	u64 extent_end = 0;
	int keep;
	struct btrfs_file_extent_item old;
	struct btrfs_path *path;
	u64 search_start = start;
	struct btrfs_key key;
	struct btrfs_file_extent_item old;
	int keep;
	int slot;
	int bookend;
	int found_type;
	int found_extent;
	int found_inline;
	int recow;
	int ret;

	btrfs_drop_extent_cache(inode, start, end - 1);

@@ -502,7 +502,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
			}
			bookend = 1;
			if (found_inline && start <= key.offset &&
			    inline_end < extent_end)
			    inline_limit < extent_end)
				keep = 1;
		}
		/* truncate existing extent */
@@ -526,12 +526,12 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
				btrfs_set_file_extent_num_bytes(leaf, extent,
								new_num);
				btrfs_mark_buffer_dirty(leaf);
			} else if (end > extent_end &&
				   key.offset < inline_end &&
				   inline_end < extent_end) {
			} else if (key.offset < inline_limit &&
				   (end > extent_end) &&
				   (inline_limit < extent_end)) {
				u32 new_size;
				new_size = btrfs_file_extent_calc_inline_size(
						   inline_end - key.offset);
						   inline_limit - key.offset);
				btrfs_truncate_item(trans, root, path,
						    new_size, 1);
			}
@@ -575,10 +575,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans,
				continue;
		}
		if (bookend && found_inline && start <= key.offset &&
		    inline_end < extent_end) {
		    inline_limit < extent_end && key.offset <= inline_limit) {
			u32 new_size;
			new_size = btrfs_file_extent_calc_inline_size(
						   extent_end - inline_end);
						   extent_end - inline_limit);
			btrfs_truncate_item(trans, root, path, new_size, 0);
		}
		/* create bookend, splitting the extent in two */