btrfs_drop_extents: make sure the item is getting smaller before truncate
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
ca6646264b
commit
00f5c795fc
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
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 extent_buffer *leaf;
|
||||
struct btrfs_file_extent_item *extent;
|
||||
struct btrfs_path *path;
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user