diff options
author | Yan <zheng.yan@oracle.com> | 2008-07-30 16:29:20 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:05 -0400 |
commit | bcc63abbf3e9bf948a1b0129b3e6120ec7d7f698 (patch) | |
tree | 1c66dc210f948f79c86786368d2c75b57482875d /fs/btrfs/extent-tree.c | |
parent | 33958dc6d38fb4ca7e62273855fcb2db7e616263 (diff) |
Btrfs: implement memory reclaim for leaf reference cache
The memory reclaiming issue happens when snapshot exists. In that
case, some cache entries may not be used during old snapshot dropping,
so they will remain in the cache until umount.
The patch adds a field to struct btrfs_leaf_ref to record create time. Besides,
the patch makes all dead roots of a given snapshot linked together in order of
create time. After a old snapshot was completely dropped, we check the dead
root list and remove all cache entries created before the oldest dead root in
the list.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index fe1ddbd2bfd6..37ca8df30c30 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -867,8 +867,8 @@ static int get_reference_status(struct btrfs_root *root, u64 bytenr, | |||
867 | /* | 867 | /* |
868 | * For (parent_gen > 0 && parent_gen > ref_gen): | 868 | * For (parent_gen > 0 && parent_gen > ref_gen): |
869 | * | 869 | * |
870 | * we reach here through the oldest root, therefore | 870 | * we reach here through the oldest root, therefore |
871 | * all other reference from same snapshot should have | 871 | * all other reference from same snapshot should have |
872 | * a larger generation. | 872 | * a larger generation. |
873 | */ | 873 | */ |
874 | if ((root_objectid != btrfs_ref_root(leaf, ref_item)) || | 874 | if ((root_objectid != btrfs_ref_root(leaf, ref_item)) || |
@@ -954,7 +954,7 @@ int btrfs_cross_ref_exists(struct btrfs_root *root, | |||
954 | if (!eb) | 954 | if (!eb) |
955 | continue; | 955 | continue; |
956 | extent_start = eb->start; | 956 | extent_start = eb->start; |
957 | } else | 957 | } else |
958 | extent_start = bytenr; | 958 | extent_start = bytenr; |
959 | 959 | ||
960 | ret = get_reference_status(root, extent_start, ref_generation, | 960 | ret = get_reference_status(root, extent_start, ref_generation, |
@@ -1048,7 +1048,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1048 | struct btrfs_leaf_ref *ref; | 1048 | struct btrfs_leaf_ref *ref; |
1049 | struct btrfs_extent_info *info; | 1049 | struct btrfs_extent_info *info; |
1050 | 1050 | ||
1051 | ref = btrfs_alloc_leaf_ref(nr_file_extents); | 1051 | ref = btrfs_alloc_leaf_ref(root, nr_file_extents); |
1052 | if (!ref) { | 1052 | if (!ref) { |
1053 | WARN_ON(1); | 1053 | WARN_ON(1); |
1054 | goto out; | 1054 | goto out; |
@@ -1059,7 +1059,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1059 | ref->generation = btrfs_header_generation(buf); | 1059 | ref->generation = btrfs_header_generation(buf); |
1060 | ref->nritems = nr_file_extents; | 1060 | ref->nritems = nr_file_extents; |
1061 | info = ref->extents; | 1061 | info = ref->extents; |
1062 | 1062 | ||
1063 | for (i = 0; nr_file_extents > 0 && i < nritems; i++) { | 1063 | for (i = 0; nr_file_extents > 0 && i < nritems; i++) { |
1064 | u64 disk_bytenr; | 1064 | u64 disk_bytenr; |
1065 | btrfs_item_key_to_cpu(buf, &key, i); | 1065 | btrfs_item_key_to_cpu(buf, &key, i); |
@@ -1085,7 +1085,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1085 | BUG_ON(!root->ref_tree); | 1085 | BUG_ON(!root->ref_tree); |
1086 | ret = btrfs_add_leaf_ref(root, ref); | 1086 | ret = btrfs_add_leaf_ref(root, ref); |
1087 | WARN_ON(ret); | 1087 | WARN_ON(ret); |
1088 | btrfs_free_leaf_ref(ref); | 1088 | btrfs_free_leaf_ref(root, ref); |
1089 | } | 1089 | } |
1090 | out: | 1090 | out: |
1091 | return 0; | 1091 | return 0; |
@@ -2316,7 +2316,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2316 | } | 2316 | } |
2317 | 2317 | ||
2318 | static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans, | 2318 | static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans, |
2319 | struct btrfs_root *root, | 2319 | struct btrfs_root *root, |
2320 | struct extent_buffer *leaf) | 2320 | struct extent_buffer *leaf) |
2321 | { | 2321 | { |
2322 | u64 leaf_owner; | 2322 | u64 leaf_owner; |
@@ -2367,7 +2367,7 @@ static int noinline drop_leaf_ref_no_cache(struct btrfs_trans_handle *trans, | |||
2367 | } | 2367 | } |
2368 | 2368 | ||
2369 | static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans, | 2369 | static int noinline drop_leaf_ref(struct btrfs_trans_handle *trans, |
2370 | struct btrfs_root *root, | 2370 | struct btrfs_root *root, |
2371 | struct btrfs_leaf_ref *ref) | 2371 | struct btrfs_leaf_ref *ref) |
2372 | { | 2372 | { |
2373 | int i; | 2373 | int i; |
@@ -2521,7 +2521,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2521 | ret = drop_leaf_ref(trans, root, ref); | 2521 | ret = drop_leaf_ref(trans, root, ref); |
2522 | BUG_ON(ret); | 2522 | BUG_ON(ret); |
2523 | btrfs_remove_leaf_ref(root, ref); | 2523 | btrfs_remove_leaf_ref(root, ref); |
2524 | btrfs_free_leaf_ref(ref); | 2524 | btrfs_free_leaf_ref(root, ref); |
2525 | *level = 0; | 2525 | *level = 0; |
2526 | break; | 2526 | break; |
2527 | } | 2527 | } |