aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.h
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2009-07-13 21:29:25 -0400
committerChris Mason <chris.mason@oracle.com>2009-07-24 09:23:39 -0400
commit817d52f8dba26d0295c26035531c30ce5f1e3c3e (patch)
tree5230153e86323de48e7e1440352d1b74d2d9961d /fs/btrfs/ctree.h
parent963030817060e4f109be1993b9ae8f81dbf5e11a (diff)
Btrfs: async block group caching
This patch moves the caching of the block group off to a kthread in order to allow people to allocate sooner. Instead of blocking up behind the caching mutex, we instead kick of the caching kthread, and then attempt to make an allocation. If we cannot, we wait on the block groups caching waitqueue, which the caching kthread will wake the waiting threads up everytime it finds 2 meg worth of space, and then again when its finished caching. This is how I tested the speedup from this mkfs the disk mount the disk fill the disk up with fs_mark unmount the disk mount the disk time touch /mnt/foo Without my changes this took 11 seconds on my box, with these changes it now takes 1 second. Another change thats been put in place is we lock the super mirror's in the pinned extent map in order to keep us from adding that stuff as free space when caching the block group. This doesn't really change anything else as far as the pinned extent map is concerned, since for actual pinned extents we use EXTENT_DIRTY, but it does mean that when we unmount we have to go in and unlock those extents to keep from leaking memory. I've also added a check where when we are reading block groups from disk, if the amount of space used == the size of the block group, we go ahead and mark the block group as cached. This drastically reduces the amount of time it takes to cache the block groups. Using the same test as above, except doing a dd to a file and then unmounting, it used to take 33 seconds to umount, now it takes 3 seconds. This version uses the commit_root in the caching kthread, and then keeps track of how many async caching threads are running at any given time so if one of the async threads is still running as we cross transactions we can wait until its finished before handling the pinned extents. Thank you, Signed-off-by: Josef Bacik <jbacik@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.h')
-rw-r--r--fs/btrfs/ctree.h22
1 files changed, 19 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 0cbf3491bb7c..42b03c4ee494 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -691,6 +691,7 @@ struct btrfs_space_info {
691 struct list_head block_groups; 691 struct list_head block_groups;
692 spinlock_t lock; 692 spinlock_t lock;
693 struct rw_semaphore groups_sem; 693 struct rw_semaphore groups_sem;
694 atomic_t caching_threads;
694}; 695};
695 696
696/* 697/*
@@ -721,11 +722,17 @@ struct btrfs_free_cluster {
721 struct list_head block_group_list; 722 struct list_head block_group_list;
722}; 723};
723 724
725enum btrfs_caching_type {
726 BTRFS_CACHE_NO = 0,
727 BTRFS_CACHE_STARTED = 1,
728 BTRFS_CACHE_FINISHED = 2,
729};
730
724struct btrfs_block_group_cache { 731struct btrfs_block_group_cache {
725 struct btrfs_key key; 732 struct btrfs_key key;
726 struct btrfs_block_group_item item; 733 struct btrfs_block_group_item item;
734 struct btrfs_fs_info *fs_info;
727 spinlock_t lock; 735 spinlock_t lock;
728 struct mutex cache_mutex;
729 u64 pinned; 736 u64 pinned;
730 u64 reserved; 737 u64 reserved;
731 u64 flags; 738 u64 flags;
@@ -733,15 +740,19 @@ struct btrfs_block_group_cache {
733 int extents_thresh; 740 int extents_thresh;
734 int free_extents; 741 int free_extents;
735 int total_bitmaps; 742 int total_bitmaps;
736 int cached;
737 int ro; 743 int ro;
738 int dirty; 744 int dirty;
739 745
746 /* cache tracking stuff */
747 wait_queue_head_t caching_q;
748 int cached;
749
740 struct btrfs_space_info *space_info; 750 struct btrfs_space_info *space_info;
741 751
742 /* free space cache stuff */ 752 /* free space cache stuff */
743 spinlock_t tree_lock; 753 spinlock_t tree_lock;
744 struct rb_root free_space_offset; 754 struct rb_root free_space_offset;
755 u64 free_space;
745 756
746 /* block group cache stuff */ 757 /* block group cache stuff */
747 struct rb_node cache_node; 758 struct rb_node cache_node;
@@ -834,6 +845,7 @@ struct btrfs_fs_info {
834 atomic_t async_submit_draining; 845 atomic_t async_submit_draining;
835 atomic_t nr_async_bios; 846 atomic_t nr_async_bios;
836 atomic_t async_delalloc_pages; 847 atomic_t async_delalloc_pages;
848 atomic_t async_caching_threads;
837 849
838 /* 850 /*
839 * this is used by the balancing code to wait for all the pending 851 * this is used by the balancing code to wait for all the pending
@@ -950,6 +962,9 @@ struct btrfs_root {
950 /* the node lock is held while changing the node pointer */ 962 /* the node lock is held while changing the node pointer */
951 spinlock_t node_lock; 963 spinlock_t node_lock;
952 964
965 /* taken when updating the commit root */
966 struct rw_semaphore commit_root_sem;
967
953 struct extent_buffer *commit_root; 968 struct extent_buffer *commit_root;
954 struct btrfs_root *log_root; 969 struct btrfs_root *log_root;
955 struct btrfs_root *reloc_root; 970 struct btrfs_root *reloc_root;
@@ -1911,7 +1926,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
1911 struct btrfs_root *root, unsigned long count); 1926 struct btrfs_root *root, unsigned long count);
1912int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); 1927int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
1913int btrfs_update_pinned_extents(struct btrfs_root *root, 1928int btrfs_update_pinned_extents(struct btrfs_root *root,
1914 u64 bytenr, u64 num, int pin); 1929 u64 bytenr, u64 num, int pin, int mark_free);
1915int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, 1930int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
1916 struct btrfs_root *root, struct extent_buffer *leaf); 1931 struct btrfs_root *root, struct extent_buffer *leaf);
1917int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans, 1932int btrfs_cross_ref_exist(struct btrfs_trans_handle *trans,
@@ -1996,6 +2011,7 @@ void btrfs_delalloc_reserve_space(struct btrfs_root *root, struct inode *inode,
1996 u64 bytes); 2011 u64 bytes);
1997void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode, 2012void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
1998 u64 bytes); 2013 u64 bytes);
2014void btrfs_free_super_mirror_extents(struct btrfs_fs_info *info);
1999/* ctree.c */ 2015/* ctree.c */
2000int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, 2016int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
2001 int level, int *slot); 2017 int level, int *slot);