[Btrfs-devel][PATCH]Add block group pinned accounting back

Yan Zheng yanzheng at 21cn.com
Sun Nov 11 17:30:29 PST 2007


Hello,

This patch adds a helper function 'update_pinned_extents' to
extent-tree.c. The usage of the helper function is similar to
'update_block_group',  the last parameter of the function indicates
pin vs unpin.

Regards
YZ

---
diff -r dc03d8df4762 ctree.h
--- a/ctree.h	Wed Nov 07 21:08:16 2007 -0500
+++ b/ctree.h	Mon Nov 12 09:06:10 2007 +0800
@@ -291,6 +291,7 @@ struct btrfs_block_group_cache {
 	struct btrfs_block_group_item item;
 	int data;
 	int cached;
+	u64 pinned;
 };

 struct btrfs_fs_info {
@@ -323,6 +324,8 @@ struct btrfs_fs_info {
 	struct completion kobj_unregister;
 	int do_barriers;
 	int closing;
+
+	u64 total_pinned;
 };

 /*
diff -r dc03d8df4762 disk-io.c
--- a/disk-io.c	Wed Nov 07 21:08:16 2007 -0500
+++ b/disk-io.c	Mon Nov 12 09:06:10 2007 +0800
@@ -570,6 +570,8 @@ struct btrfs_root *open_ctree(struct sup
 	fs_info->do_barriers = 1;
 	fs_info->closing = 0;

+	fs_info->total_pinned = 0;
+
 	INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner);
 	BTRFS_I(fs_info->btree_inode)->root = tree_root;
 	memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
diff -r dc03d8df4762 extent-tree.c
--- a/extent-tree.c	Wed Nov 07 21:08:16 2007 -0500
+++ b/extent-tree.c	Mon Nov 12 09:06:10 2007 +0800
@@ -277,7 +277,8 @@ struct btrfs_block_group_cache *btrfs_fi
 		if (shint && (shint->data == data ||
 			      shint->data == BTRFS_BLOCK_GROUP_MIXED)) {
 			used = btrfs_block_group_used(&shint->item);
-			if (used < div_factor(shint->key.offset, factor)) {
+			if (used + shint->pinned <
+			    div_factor(shint->key.offset, factor)) {
 				return shint;
 			}
 		}
@@ -285,7 +286,8 @@ struct btrfs_block_group_cache *btrfs_fi
 	if (hint && (hint->data == data ||
 		     hint->data == BTRFS_BLOCK_GROUP_MIXED)) {
 		used = btrfs_block_group_used(&hint->item);
-		if (used < div_factor(hint->key.offset, factor)) {
+		if (used + hint->pinned <
+		    div_factor(hint->key.offset, factor)) {
 			return hint;
 		}
 		last = hint->key.objectid + hint->key.offset;
@@ -318,7 +320,7 @@ again:
 		else
 			free_check = div_factor(cache->key.offset, factor);

-		if (used < free_check) {
+		if (used + cache->pinned < free_check) {
 			found_group = cache;
 			goto found;
 		}
@@ -665,6 +667,38 @@ static int update_block_group(struct btr
 	return 0;
 }

+static int update_pinned_extents(struct btrfs_root *root,
+				u64 bytenr, u64 num, int pin)
+{
+	u64 len;
+	struct btrfs_block_group_cache *cache;
+	struct btrfs_fs_info *fs_info = root->fs_info;
+
+	if (pin) {
+		set_extent_dirty(&fs_info->pinned_extents,
+				bytenr, bytenr + num - 1, GFP_NOFS);
+	} else {
+		clear_extent_dirty(&fs_info->pinned_extents,
+				bytenr, bytenr + num - 1, GFP_NOFS);
+	}
+	while (num > 0) {
+		cache = btrfs_lookup_block_group(fs_info, bytenr);
+		WARN_ON(!cache);
+		len = min(num, cache->key.offset -
+			  (bytenr - cache->key.objectid));
+		if (pin) {
+			cache->pinned += len;
+			fs_info->total_pinned += len;
+		} else {
+			cache->pinned -= len;
+			fs_info->total_pinned -= len;
+		}
+		bytenr += len;
+		num -= len;
+	}
+	return 0;
+}
+
 int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy)
 {
 	u64 last = 0;
@@ -691,7 +725,6 @@ int btrfs_finish_extent_commit(struct bt
 	u64 start;
 	u64 end;
 	int ret;
-	struct extent_map_tree *pinned_extents = &root->fs_info->pinned_extents;
 	struct extent_map_tree *free_space_cache;

 	free_space_cache = &root->fs_info->free_space_cache;
@@ -702,8 +735,7 @@ int btrfs_finish_extent_commit(struct bt
 		if (ret)
 			break;

-		clear_extent_dirty(pinned_extents, start, end,
-				   GFP_NOFS);
+		update_pinned_extents(root, start, end + 1 - start, 0);
 		clear_extent_dirty(unpin, start, end, GFP_NOFS);
 		set_extent_dirty(free_space_cache, start, end, GFP_NOFS);
 	}
@@ -761,8 +793,7 @@ static int pin_down_bytes(struct btrfs_r
 			}
 			free_extent_buffer(buf);
 		}
-		set_extent_dirty(&root->fs_info->pinned_extents,
-				 bytenr, bytenr + num_bytes - 1, GFP_NOFS);
+		update_pinned_extents(root, bytenr, num_bytes, 1);
 	} else {
 		set_extent_bits(&root->fs_info->pending_del,
 				bytenr, bytenr + num_bytes - 1,
@@ -867,7 +898,7 @@ static int del_pending_extents(struct bt
 		if (ret)
 			break;

-		set_extent_dirty(pinned_extents, start, end, GFP_NOFS);
+		update_pinned_extents(extent_root, start, end + 1 - start, 1);
 		clear_extent_bits(pending_del, start, end, EXTENT_LOCKED,
 				  GFP_NOFS);
 		ret = __free_extent(trans, extent_root,
@@ -1579,6 +1610,7 @@ int btrfs_read_block_groups(struct btrfs
 				   sizeof(cache->item));
 		memcpy(&cache->key, &found_key, sizeof(found_key));
 		cache->cached = 0;
+		cache->pinned = 0;

 		key.objectid = found_key.objectid + found_key.offset;
 		btrfs_release_path(root, path);



More information about the Btrfs-devel mailing list