aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.h
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@redhat.com>2008-09-23 13:14:11 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:07 -0400
commit0f9dd46cda36b8de3b9f48bc42bd09d20b9c3b52 (patch)
tree2dcba11fd2fb5a4227fd8f8d2d076641f115a7b4 /fs/btrfs/ctree.h
parentef8bbdfe7e12dc9b4e80756f6d606c4639c65851 (diff)
Btrfs: free space accounting redo
1) replace the per fs_info extent_io_tree that tracked free space with two rb-trees per block group to track free space areas via offset and size. The reason to do this is because most allocations come with a hint byte where to start, so we can usually find a chunk of free space at that hint byte to satisfy the allocation and get good space packing. If we cannot find free space at or after the given offset we fall back on looking for a chunk of the given size as close to that given offset as possible. When we fall back on the size search we also try to find a slot as close to the size we want as possible, to avoid breaking small chunks off of huge areas if possible. 2) remove the extent_io_tree that tracked the block group cache from fs_info and replaced it with an rb-tree thats tracks block group cache via offset. also added a per space_info list that tracks the block group cache for the particular space so we can lookup related block groups easily. 3) cleaned up the allocation code to make it a little easier to read and a little less complicated. Basically there are 3 steps, first look from our provided hint. If we couldn't find from that given hint, start back at our original search start and look for space from there. If that fails try to allocate space if we can and start looking again. If not we're screwed and need to start over again. 4) small fixes. there were some issues in volumes.c where we wouldn't allocate the rest of the disk. fixed cow_file_range to actually pass the alloc_hint, which has helped a good bit in making the fs_mark test I run have semi-normal results as we run out of space. Generally with data allocations we don't track where we last allocated from, so everytime we did a data allocation we'd search through every block group that we have looking for free space. Now searching a block group with no free space isn't terribly time consuming, it was causing a slight degradation as we got more data block groups. The alloc_hint has fixed this slight degredation and made things semi-normal. There is still one nagging problem I'm working on where we will get ENOSPC when there is definitely plenty of space. This only happens with metadata allocations, and only when we are almost full. So you generally hit the 85% mark first, but sometimes you'll hit the BUG before you hit the 85% wall. I'm still tracking it down, but until then this seems to be pretty stable and make a significant performance gain. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r--fs/btrfs/ctree.h46
1 files changed, 42 insertions, 4 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index eb65fd808883..730aae3bc181 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -483,7 +483,6 @@ struct btrfs_csum_item {
483#define BTRFS_BLOCK_GROUP_DUP (1 << 5) 483#define BTRFS_BLOCK_GROUP_DUP (1 << 5)
484#define BTRFS_BLOCK_GROUP_RAID10 (1 << 6) 484#define BTRFS_BLOCK_GROUP_RAID10 (1 << 6)
485 485
486
487struct btrfs_block_group_item { 486struct btrfs_block_group_item {
488 __le64 used; 487 __le64 used;
489 __le64 chunk_objectid; 488 __le64 chunk_objectid;
@@ -498,17 +497,40 @@ struct btrfs_space_info {
498 int full; 497 int full;
499 int force_alloc; 498 int force_alloc;
500 struct list_head list; 499 struct list_head list;
500
501 /* for block groups in our same type */
502 struct list_head block_groups;
503 spinlock_t lock;
504};
505
506struct btrfs_free_space {
507 struct rb_node bytes_index;
508 struct rb_node offset_index;
509 u64 offset;
510 u64 bytes;
501}; 511};
502 512
503struct btrfs_block_group_cache { 513struct btrfs_block_group_cache {
504 struct btrfs_key key; 514 struct btrfs_key key;
505 struct btrfs_block_group_item item; 515 struct btrfs_block_group_item item;
506 struct btrfs_space_info *space_info;
507 spinlock_t lock; 516 spinlock_t lock;
508 u64 pinned; 517 u64 pinned;
509 u64 flags; 518 u64 flags;
510 int cached; 519 int cached;
511 int ro; 520 int ro;
521 int dirty;
522
523 struct btrfs_space_info *space_info;
524
525 /* free space cache stuff */
526 struct rb_root free_space_bytes;
527 struct rb_root free_space_offset;
528
529 /* block group cache stuff */
530 struct rb_node cache_node;
531
532 /* for block groups in the same raid type */
533 struct list_head list;
512}; 534};
513 535
514struct btrfs_device; 536struct btrfs_device;
@@ -525,8 +547,10 @@ struct btrfs_fs_info {
525 struct btrfs_root *log_root_tree; 547 struct btrfs_root *log_root_tree;
526 struct radix_tree_root fs_roots_radix; 548 struct radix_tree_root fs_roots_radix;
527 549
528 struct extent_io_tree free_space_cache; 550 /* block group cache stuff */
529 struct extent_io_tree block_group_cache; 551 spinlock_t block_group_cache_lock;
552 struct rb_root block_group_cache_tree;
553
530 struct extent_io_tree pinned_extents; 554 struct extent_io_tree pinned_extents;
531 struct extent_io_tree pending_del; 555 struct extent_io_tree pending_del;
532 struct extent_io_tree extent_ins; 556 struct extent_io_tree extent_ins;
@@ -1814,4 +1838,18 @@ int btrfs_sync_fs(struct super_block *sb, int wait);
1814int btrfs_check_acl(struct inode *inode, int mask); 1838int btrfs_check_acl(struct inode *inode, int mask);
1815int btrfs_init_acl(struct inode *inode, struct inode *dir); 1839int btrfs_init_acl(struct inode *inode, struct inode *dir);
1816int btrfs_acl_chmod(struct inode *inode); 1840int btrfs_acl_chmod(struct inode *inode);
1841
1842/* free-space-cache.c */
1843int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
1844 u64 bytenr, u64 size);
1845int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
1846 u64 bytenr, u64 size);
1847void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
1848 *block_group);
1849struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
1850 *block_group, u64 offset,
1851 u64 bytes);
1852void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
1853 u64 bytes);
1854u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
1817#endif 1855#endif