diff options
author | Yan <yanzheng@21cn.com> | 2007-11-16 14:57:08 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:57 -0400 |
commit | 324ae4df00fdc1a6a179bf584d8addf027bb75fb (patch) | |
tree | 81d6fd1c3605f998051c46596b64da431b706e89 /fs/btrfs | |
parent | 5103e947b9b7ac18ddb21a04ee3486e94c6504d7 (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.h | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 54 |
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 | |||
297 | struct btrfs_fs_info { | 297 | struct 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 | } |
668 | static 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 | ||
668 | int btrfs_copy_pinned(struct btrfs_root *root, struct extent_map_tree *copy) | 700 | int 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 | ||