Linux Kernels

btrfs_drop_extents: make sure the item is getting smaller before truncate

This change “btrfs_drop_extents: make sure the item is getting smaller before truncate” (commit 00f5c79) in Linux kernel is authored by Chris Mason <chris.mason [at] oracle.com> on Fri Nov 30 10:09:33 2007 -0500.

Description of "btrfs_drop_extents: make sure the item is getting smaller before truncate"

The change “btrfs_drop_extents: make sure the item is getting smaller before truncate” introduces changes as follows.

btrfs_drop_extents: make sure the item is getting smaller before truncate

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Linux kernel releases containing commit 00f5c79

The Linux kernel releases containing this commit are as follows.

Linux kernel code changes from "btrfs_drop_extents: make sure the item is getting smaller before truncate"

There are 40 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 fs/btrfs/ctree.h       |  2 +-
 fs/btrfs/extent-tree.c |  8 ++++++++
 fs/btrfs/file.c        | 30 +++++++++++++++---------------
 3 files changed, 24 insertions(+), 16 deletions(-)
 
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 56b977ffe918..b29b911dd825 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -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);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3c00f967eccb..55abdf997ca5 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -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)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index ba624ae16e61..b0d637787264 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -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 */

The commit for this change in Linux stable tree is 00f5c79 (patch).

Last modified: 2020/01/11 09:26