aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorYan <yanzheng@21cn.com>2007-11-16 14:57:08 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:57 -0400
commit324ae4df00fdc1a6a179bf584d8addf027bb75fb (patch)
tree81d6fd1c3605f998051c46596b64da431b706e89 /fs/btrfs
parent5103e947b9b7ac18ddb21a04ee3486e94c6504d7 (diff)
Btrfs: Add block group pinned accounting back
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. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/extent-tree.c54
3 files changed, 44 insertions, 16 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 27cadae1af63..56b977ffe918 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -292,8 +292,8 @@ struct btrfs_block_group_cache {
292 struct btrfs_block_group_item item; 292 struct btrfs_block_group_item item;
293 int data; 293 int data;
294 int cached; 294 int cached;
295 u64 pinned;
295}; 296};
296
297struct btrfs_fs_info { 297struct btrfs_fs_info {
298 u8 fsid[BTRFS_FSID_SIZE]; 298 u8 fsid[BTRFS_FSID_SIZE];
299 struct btrfs_root *extent_root; 299 struct btrfs_root *extent_root;
@@ -324,8 +324,9 @@ struct btrfs_fs_info {
324 struct completion kobj_unregister; 324 struct completion kobj_unregister;
325 int do_barriers; 325 int do_barriers;
326 int closing; 326 int closing;
327};
328 327
328 u64 total_pinned;
329};
329/* 330/*
330 * in ram representation of the tree. extent_root is used for all allocations 331 * in ram representation of the tree. extent_root is used for all allocations
331 * and for the extent tree extent_root root. 332 * and for the extent tree extent_root root.
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6c8533fba7c9..3e16cca72b49 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -569,6 +569,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
569 fs_info->btree_inode->i_mapping, GFP_NOFS); 569 fs_info->btree_inode->i_mapping, GFP_NOFS);
570 fs_info->do_barriers = 1; 570 fs_info->do_barriers = 1;
571 fs_info->closing = 0; 571 fs_info->closing = 0;
572 fs_info->total_pinned = 0;
572 573
573 INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner); 574 INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner);
574 BTRFS_I(fs_info->btree_inode)->root = tree_root; 575 BTRFS_I(fs_info->btree_inode)->root = tree_root;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7405bd5301af..4ef6dc3d7d32 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -277,7 +277,8 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
277 if (shint && (shint->data == data || 277 if (shint && (shint->data == data ||
278 shint->data == BTRFS_BLOCK_GROUP_MIXED)) { 278 shint->data == BTRFS_BLOCK_GROUP_MIXED)) {
279 used = btrfs_block_group_used(&shint->item); 279 used = btrfs_block_group_used(&shint->item);
280 if (used < div_factor(shint->key.offset, factor)) { 280 if (used + shint->pinned <
281 div_factor(shint->key.offset, factor)) {
281 return shint; 282 return shint;
282 } 283 }
283 } 284 }
@@ -285,7 +286,8 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
285 if (hint && (hint->data == data || 286 if (hint && (hint->data == data ||
286 hint->data == BTRFS_BLOCK_GROUP_MIXED)) { 287 hint->data == BTRFS_BLOCK_GROUP_MIXED)) {
287 used = btrfs_block_group_used(&hint->item); 288 used = btrfs_block_group_used(&hint->item);
288 if (used < div_factor(hint->key.offset, factor)) { 289 if (used + hint->pinned <
290 div_factor(hint->key.offset, factor)) {
289 return hint; 291 return hint;
290 } 292 }
291 last = hint->key.objectid + hint->key.offset; 293 last = hint->key.objectid + hint->key.offset;
@@ -317,8 +319,7 @@ again:
317 free_check = cache->key.offset; 319 free_check = cache->key.offset;
318 else 320 else
319 free_check = div_factor(cache->key.offset, factor); 321 free_check = div_factor(cache->key.offset, factor);
320 322 if (used + cache->pinned < free_check) {
321 if (used < free_check) {
322 found_group = cache; 323 found_group = cache;
323 goto found; 324 goto found;
324 } 325 }
@@ -664,6 +665,37 @@ static int update_block_group(struct btrfs_trans_handle *trans,
664 } 665 }
665 return 0; 666 return 0;
666} 667}
668static int update_pinned_extents(struct btrfs_root *root,
669 u64 bytenr, u64 num, int pin)
670{
671 u64 len;
672 struct btrfs_block_group_cache *cache;
673 struct btrfs_fs_info *fs_info = root->fs_info;
674
675 if (pin) {
676 set_extent_dirty(&fs_info->pinned_extents,
677 bytenr, bytenr + num - 1, GFP_NOFS);
678 } else {
679 clear_extent_dirty(&fs_info->pinned_extents,
680 bytenr, bytenr + num - 1, GFP_NOFS);
681 }
682 while (num > 0) {
683 cache = btrfs_lookup_block_group(fs_info, bytenr);
684 WARN_ON(!cache);
685 len = min(num, cache->key.offset -
686 (bytenr - cache->key.objectid));
687 if (pin) {
688 cache->pinned += len;
689 fs_info->total_pinned += len;
690 } else {
691 cache->pinned -= len;
692 fs_info->total_pinned -= len;
693 }
694 bytenr += len;
695 num -= len;
696 }
697 return 0;
698}
667 699
668int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy) 700int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy)
669{ 701{
@@ -691,9 +723,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
691 u64 start; 723 u64 start;
692 u64 end; 724 u64 end;
693 int ret; 725 int ret;
694 struct extent_map_tree *pinned_extents = &root->fs_info->pinned_extents;
695 struct extent_map_tree *free_space_cache; 726 struct extent_map_tree *free_space_cache;
696
697 free_space_cache = &root->fs_info->free_space_cache; 727 free_space_cache = &root->fs_info->free_space_cache;
698 728
699 while(1) { 729 while(1) {
@@ -701,9 +731,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
701 EXTENT_DIRTY); 731 EXTENT_DIRTY);
702 if (ret) 732 if (ret)
703 break; 733 break;
704 734 update_pinned_extents(root, start, end + 1 - start, 0);
705 clear_extent_dirty(pinned_extents, start, end,
706 GFP_NOFS);
707 clear_extent_dirty(unpin, start, end, GFP_NOFS); 735 clear_extent_dirty(unpin, start, end, GFP_NOFS);
708 set_extent_dirty(free_space_cache, start, end, GFP_NOFS); 736 set_extent_dirty(free_space_cache, start, end, GFP_NOFS);
709 } 737 }
@@ -761,8 +789,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
761 } 789 }
762 free_extent_buffer(buf); 790 free_extent_buffer(buf);
763 } 791 }
764 set_extent_dirty(&root->fs_info->pinned_extents, 792 update_pinned_extents(root, bytenr, num_bytes, 1);
765 bytenr, bytenr + num_bytes - 1, GFP_NOFS);
766 } else { 793 } else {
767 set_extent_bits(&root->fs_info->pending_del, 794 set_extent_bits(&root->fs_info->pending_del,
768 bytenr, bytenr + num_bytes - 1, 795 bytenr, bytenr + num_bytes - 1,
@@ -866,8 +893,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
866 EXTENT_LOCKED); 893 EXTENT_LOCKED);
867 if (ret) 894 if (ret)
868 break; 895 break;
869 896 update_pinned_extents(extent_root, start, end + 1 - start, 1);
870 set_extent_dirty(pinned_extents, start, end, GFP_NOFS);
871 clear_extent_bits(pending_del, start, end, EXTENT_LOCKED, 897 clear_extent_bits(pending_del, start, end, EXTENT_LOCKED,
872 GFP_NOFS); 898 GFP_NOFS);
873 ret = __free_extent(trans, extent_root, 899 ret = __free_extent(trans, extent_root,
@@ -1579,7 +1605,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1579 sizeof(cache->item)); 1605 sizeof(cache->item));
1580 memcpy(&cache->key, &found_key, sizeof(found_key)); 1606 memcpy(&cache->key, &found_key, sizeof(found_key));
1581 cache->cached = 0; 1607 cache->cached = 0;
1582 1608 cache->pinned = 0;
1583 key.objectid = found_key.objectid + found_key.offset; 1609 key.objectid = found_key.objectid + found_key.offset;
1584 btrfs_release_path(root, path); 1610 btrfs_release_path(root, path);
1585 1611