diff options
author | Yan, Zheng <zheng.yan@oracle.com> | 2010-05-16 10:46:25 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-05-25 10:34:50 -0400 |
commit | f0486c68e4bd9a06a5904d3eeb3a0d73a83befb8 (patch) | |
tree | 509428ef400ef45e875a3c448b63b86cbea36aea /fs/btrfs/ctree.h | |
parent | 2ead6ae770d9f9dec9f4286bf0fd9001b4388c4b (diff) |
Btrfs: Introduce contexts for metadata reservation
Introducing metadata reseravtion contexts has two major advantages.
First, it makes metadata reseravtion more traceable. Second, it can
reclaim freed space and re-add them to the itself after transaction
committed.
Besides add btrfs_block_rsv structure and related helper functions,
This patch contains following changes:
Move code that decides if freed tree block should be pinned into
btrfs_free_tree_block().
Make space accounting more accurate, mainly for handling read only
block groups.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r-- | fs/btrfs/ctree.h | 69 |
1 files changed, 62 insertions, 7 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 85c7b95dd2fe..7d2479694a58 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -707,6 +707,20 @@ struct btrfs_space_info { | |||
707 | atomic_t caching_threads; | 707 | atomic_t caching_threads; |
708 | }; | 708 | }; |
709 | 709 | ||
710 | struct btrfs_block_rsv { | ||
711 | u64 size; | ||
712 | u64 reserved; | ||
713 | u64 freed[2]; | ||
714 | struct btrfs_space_info *space_info; | ||
715 | struct list_head list; | ||
716 | spinlock_t lock; | ||
717 | atomic_t usage; | ||
718 | unsigned int priority:8; | ||
719 | unsigned int durable:1; | ||
720 | unsigned int refill_used:1; | ||
721 | unsigned int full:1; | ||
722 | }; | ||
723 | |||
710 | /* | 724 | /* |
711 | * free clusters are used to claim free space in relatively large chunks, | 725 | * free clusters are used to claim free space in relatively large chunks, |
712 | * allowing us to do less seeky writes. They are used for all metadata | 726 | * allowing us to do less seeky writes. They are used for all metadata |
@@ -757,6 +771,7 @@ struct btrfs_block_group_cache { | |||
757 | spinlock_t lock; | 771 | spinlock_t lock; |
758 | u64 pinned; | 772 | u64 pinned; |
759 | u64 reserved; | 773 | u64 reserved; |
774 | u64 reserved_pinned; | ||
760 | u64 bytes_super; | 775 | u64 bytes_super; |
761 | u64 flags; | 776 | u64 flags; |
762 | u64 sectorsize; | 777 | u64 sectorsize; |
@@ -822,6 +837,22 @@ struct btrfs_fs_info { | |||
822 | /* logical->physical extent mapping */ | 837 | /* logical->physical extent mapping */ |
823 | struct btrfs_mapping_tree mapping_tree; | 838 | struct btrfs_mapping_tree mapping_tree; |
824 | 839 | ||
840 | /* block reservation for extent, checksum and root tree */ | ||
841 | struct btrfs_block_rsv global_block_rsv; | ||
842 | /* block reservation for delay allocation */ | ||
843 | struct btrfs_block_rsv delalloc_block_rsv; | ||
844 | /* block reservation for metadata operations */ | ||
845 | struct btrfs_block_rsv trans_block_rsv; | ||
846 | /* block reservation for chunk tree */ | ||
847 | struct btrfs_block_rsv chunk_block_rsv; | ||
848 | |||
849 | struct btrfs_block_rsv empty_block_rsv; | ||
850 | |||
851 | /* list of block reservations that cross multiple transactions */ | ||
852 | struct list_head durable_block_rsv_list; | ||
853 | |||
854 | struct mutex durable_block_rsv_mutex; | ||
855 | |||
825 | u64 generation; | 856 | u64 generation; |
826 | u64 last_trans_committed; | 857 | u64 last_trans_committed; |
827 | 858 | ||
@@ -1008,6 +1039,9 @@ struct btrfs_root { | |||
1008 | struct completion kobj_unregister; | 1039 | struct completion kobj_unregister; |
1009 | struct mutex objectid_mutex; | 1040 | struct mutex objectid_mutex; |
1010 | 1041 | ||
1042 | spinlock_t accounting_lock; | ||
1043 | struct btrfs_block_rsv *block_rsv; | ||
1044 | |||
1011 | struct mutex log_mutex; | 1045 | struct mutex log_mutex; |
1012 | wait_queue_head_t log_writer_wait; | 1046 | wait_queue_head_t log_writer_wait; |
1013 | wait_queue_head_t log_commit_wait[2]; | 1047 | wait_queue_head_t log_commit_wait[2]; |
@@ -1980,10 +2014,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
1980 | u64 parent, u64 root_objectid, | 2014 | u64 parent, u64 root_objectid, |
1981 | struct btrfs_disk_key *key, int level, | 2015 | struct btrfs_disk_key *key, int level, |
1982 | u64 hint, u64 empty_size); | 2016 | u64 hint, u64 empty_size); |
1983 | int btrfs_free_tree_block(struct btrfs_trans_handle *trans, | 2017 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, |
1984 | struct btrfs_root *root, | 2018 | struct btrfs_root *root, |
1985 | u64 bytenr, u32 blocksize, | 2019 | struct extent_buffer *buf, |
1986 | u64 parent, u64 root_objectid, int level); | 2020 | u64 parent, int last_ref); |
1987 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 2021 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
1988 | struct btrfs_root *root, | 2022 | struct btrfs_root *root, |
1989 | u64 bytenr, u32 blocksize, | 2023 | u64 bytenr, u32 blocksize, |
@@ -2037,9 +2071,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
2037 | u64 size); | 2071 | u64 size); |
2038 | int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | 2072 | int btrfs_remove_block_group(struct btrfs_trans_handle *trans, |
2039 | struct btrfs_root *root, u64 group_start); | 2073 | struct btrfs_root *root, u64 group_start); |
2040 | int btrfs_prepare_block_group_relocation(struct btrfs_root *root, | ||
2041 | struct btrfs_block_group_cache *group); | ||
2042 | |||
2043 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); | 2074 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); |
2044 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); | 2075 | void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); |
2045 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); | 2076 | void btrfs_clear_space_info_full(struct btrfs_fs_info *info); |
@@ -2058,6 +2089,30 @@ void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode, | |||
2058 | u64 bytes); | 2089 | u64 bytes); |
2059 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, | 2090 | void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, |
2060 | u64 bytes); | 2091 | u64 bytes); |
2092 | void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv); | ||
2093 | struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root); | ||
2094 | void btrfs_free_block_rsv(struct btrfs_root *root, | ||
2095 | struct btrfs_block_rsv *rsv); | ||
2096 | void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info, | ||
2097 | struct btrfs_block_rsv *rsv); | ||
2098 | int btrfs_block_rsv_add(struct btrfs_trans_handle *trans, | ||
2099 | struct btrfs_root *root, | ||
2100 | struct btrfs_block_rsv *block_rsv, | ||
2101 | u64 num_bytes, int *retries); | ||
2102 | int btrfs_block_rsv_check(struct btrfs_trans_handle *trans, | ||
2103 | struct btrfs_root *root, | ||
2104 | struct btrfs_block_rsv *block_rsv, | ||
2105 | u64 min_reserved, int min_factor); | ||
2106 | int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, | ||
2107 | struct btrfs_block_rsv *dst_rsv, | ||
2108 | u64 num_bytes); | ||
2109 | void btrfs_block_rsv_release(struct btrfs_root *root, | ||
2110 | struct btrfs_block_rsv *block_rsv, | ||
2111 | u64 num_bytes); | ||
2112 | int btrfs_set_block_group_ro(struct btrfs_root *root, | ||
2113 | struct btrfs_block_group_cache *cache); | ||
2114 | int btrfs_set_block_group_rw(struct btrfs_root *root, | ||
2115 | struct btrfs_block_group_cache *cache); | ||
2061 | /* ctree.c */ | 2116 | /* ctree.c */ |
2062 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, | 2117 | int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, |
2063 | int level, int *slot); | 2118 | int level, int *slot); |