aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-04-03 09:47:43 -0400
committerChris Mason <chris.mason@oracle.com>2009-04-03 09:47:43 -0400
commitfa9c0d795f7b57c76560b7fac703f5d341210e28 (patch)
tree74d9d9846e21ce5b99738f3cc13b855fb63d1eba /fs/btrfs/disk-io.c
parent8e73f275011b3264a87339fd9f1690e944e381c9 (diff)
Btrfs: rework allocation clustering
Because btrfs is copy-on-write, we end up picking new locations for blocks very often. This makes it fairly difficult to maintain perfect read patterns over time, but we can at least do some optimizations for writes. This is done today by remembering the last place we allocated and trying to find a free space hole big enough to hold more than just one allocation. The end result is that we tend to write sequentially to the drive. This happens all the time for metadata and it happens for data when mounted -o ssd. But, the way we record it is fairly racey and it tends to fragment the free space over time because we are trying to allocate fairly large areas at once. This commit gets rid of the races by adding a free space cluster object with dedicated locking to make sure that only one process at a time is out replacing the cluster. The free space fragmentation is somewhat solved by allowing a cluster to be comprised of smaller free space extents. This part definitely adds some CPU time to the cluster allocations, but it allows the allocator to consume the small holes left behind by cow. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index ea59ebfa505d..e68ef7b456b0 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -38,6 +38,7 @@
38#include "locking.h" 38#include "locking.h"
39#include "ref-cache.h" 39#include "ref-cache.h"
40#include "tree-log.h" 40#include "tree-log.h"
41#include "free-space-cache.h"
41 42
42static struct extent_io_ops btree_extent_io_ops; 43static struct extent_io_ops btree_extent_io_ops;
43static void end_workqueue_fn(struct btrfs_work *work); 44static void end_workqueue_fn(struct btrfs_work *work);
@@ -1652,6 +1653,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1652 mutex_init(&fs_info->cleaner_mutex); 1653 mutex_init(&fs_info->cleaner_mutex);
1653 mutex_init(&fs_info->volume_mutex); 1654 mutex_init(&fs_info->volume_mutex);
1654 mutex_init(&fs_info->tree_reloc_mutex); 1655 mutex_init(&fs_info->tree_reloc_mutex);
1656
1657 btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
1658 btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
1659
1655 init_waitqueue_head(&fs_info->transaction_throttle); 1660 init_waitqueue_head(&fs_info->transaction_throttle);
1656 init_waitqueue_head(&fs_info->transaction_wait); 1661 init_waitqueue_head(&fs_info->transaction_wait);
1657 init_waitqueue_head(&fs_info->async_submit_wait); 1662 init_waitqueue_head(&fs_info->async_submit_wait);