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>
This commit is contained in:
@@ -707,6 +707,20 @@ struct btrfs_space_info {
|
||||
atomic_t caching_threads;
|
||||
};
|
||||
|
||||
struct btrfs_block_rsv {
|
||||
u64 size;
|
||||
u64 reserved;
|
||||
u64 freed[2];
|
||||
struct btrfs_space_info *space_info;
|
||||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
atomic_t usage;
|
||||
unsigned int priority:8;
|
||||
unsigned int durable:1;
|
||||
unsigned int refill_used:1;
|
||||
unsigned int full:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* free clusters are used to claim free space in relatively large chunks,
|
||||
* allowing us to do less seeky writes. They are used for all metadata
|
||||
@@ -757,6 +771,7 @@ struct btrfs_block_group_cache {
|
||||
spinlock_t lock;
|
||||
u64 pinned;
|
||||
u64 reserved;
|
||||
u64 reserved_pinned;
|
||||
u64 bytes_super;
|
||||
u64 flags;
|
||||
u64 sectorsize;
|
||||
@@ -822,6 +837,22 @@ struct btrfs_fs_info {
|
||||
/* logical->physical extent mapping */
|
||||
struct btrfs_mapping_tree mapping_tree;
|
||||
|
||||
/* block reservation for extent, checksum and root tree */
|
||||
struct btrfs_block_rsv global_block_rsv;
|
||||
/* block reservation for delay allocation */
|
||||
struct btrfs_block_rsv delalloc_block_rsv;
|
||||
/* block reservation for metadata operations */
|
||||
struct btrfs_block_rsv trans_block_rsv;
|
||||
/* block reservation for chunk tree */
|
||||
struct btrfs_block_rsv chunk_block_rsv;
|
||||
|
||||
struct btrfs_block_rsv empty_block_rsv;
|
||||
|
||||
/* list of block reservations that cross multiple transactions */
|
||||
struct list_head durable_block_rsv_list;
|
||||
|
||||
struct mutex durable_block_rsv_mutex;
|
||||
|
||||
u64 generation;
|
||||
u64 last_trans_committed;
|
||||
|
||||
@@ -1008,6 +1039,9 @@ struct btrfs_root {
|
||||
struct completion kobj_unregister;
|
||||
struct mutex objectid_mutex;
|
||||
|
||||
spinlock_t accounting_lock;
|
||||
struct btrfs_block_rsv *block_rsv;
|
||||
|
||||
struct mutex log_mutex;
|
||||
wait_queue_head_t log_writer_wait;
|
||||
wait_queue_head_t log_commit_wait[2];
|
||||
@@ -1980,10 +2014,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
|
||||
u64 parent, u64 root_objectid,
|
||||
struct btrfs_disk_key *key, int level,
|
||||
u64 hint, u64 empty_size);
|
||||
int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 bytenr, u32 blocksize,
|
||||
u64 parent, u64 root_objectid, int level);
|
||||
void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct extent_buffer *buf,
|
||||
u64 parent, int last_ref);
|
||||
struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
u64 bytenr, u32 blocksize,
|
||||
@@ -2037,9 +2071,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
|
||||
u64 size);
|
||||
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, u64 group_start);
|
||||
int btrfs_prepare_block_group_relocation(struct btrfs_root *root,
|
||||
struct btrfs_block_group_cache *group);
|
||||
|
||||
u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
|
||||
void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
|
||||
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,
|
||||
u64 bytes);
|
||||
void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
|
||||
u64 bytes);
|
||||
void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv);
|
||||
struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root);
|
||||
void btrfs_free_block_rsv(struct btrfs_root *root,
|
||||
struct btrfs_block_rsv *rsv);
|
||||
void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_block_rsv *rsv);
|
||||
int btrfs_block_rsv_add(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_block_rsv *block_rsv,
|
||||
u64 num_bytes, int *retries);
|
||||
int btrfs_block_rsv_check(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root,
|
||||
struct btrfs_block_rsv *block_rsv,
|
||||
u64 min_reserved, int min_factor);
|
||||
int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
|
||||
struct btrfs_block_rsv *dst_rsv,
|
||||
u64 num_bytes);
|
||||
void btrfs_block_rsv_release(struct btrfs_root *root,
|
||||
struct btrfs_block_rsv *block_rsv,
|
||||
u64 num_bytes);
|
||||
int btrfs_set_block_group_ro(struct btrfs_root *root,
|
||||
struct btrfs_block_group_cache *cache);
|
||||
int btrfs_set_block_group_rw(struct btrfs_root *root,
|
||||
struct btrfs_block_group_cache *cache);
|
||||
/* ctree.c */
|
||||
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
|
||||
int level, int *slot);
|
||||
|
Reference in New Issue
Block a user