aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-06-09 20:28:34 -0400
committerChris Mason <chris.mason@oracle.com>2009-06-10 11:29:52 -0400
commit451d7585a8bb1b9bec0d676ce3dece1923164e55 (patch)
treeb4e9103b7010e45e02deff9ae4470df71475f8de
parentc604480171c510c1beeb81b82418e5bc4de8f1ae (diff)
Btrfs: add mount -o ssd_spread to spread allocations out
Some SSDs perform best when reusing block numbers often, while others perform much better when clustering strictly allocates big chunks of unused space. The default mount -o ssd will find rough groupings of blocks where there are a bunch of free blocks that might have some allocated blocks mixed in. mount -o ssd_spread will make sure there are no allocated blocks mixed in. It should perform better on lower end SSDs. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/free-space-cache.c5
-rw-r--r--fs/btrfs/free-space-cache.h1
-rw-r--r--fs/btrfs/super.c19
5 files changed, 22 insertions, 6 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ce3ab4e13064..b9d8788b299e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1100,6 +1100,7 @@ struct btrfs_root {
1100#define BTRFS_MOUNT_COMPRESS (1 << 5) 1100#define BTRFS_MOUNT_COMPRESS (1 << 5)
1101#define BTRFS_MOUNT_NOTREELOG (1 << 6) 1101#define BTRFS_MOUNT_NOTREELOG (1 << 6)
1102#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7) 1102#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7)
1103#define BTRFS_MOUNT_SSD_SPREAD (1 << 8)
1103 1104
1104#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) 1105#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1105#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) 1106#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a42419c276e2..3355d7ea8308 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3607,7 +3607,7 @@ refill_cluster:
3607 last_ptr_loop = 0; 3607 last_ptr_loop = 0;
3608 3608
3609 /* allocate a cluster in this block group */ 3609 /* allocate a cluster in this block group */
3610 ret = btrfs_find_space_cluster(trans, 3610 ret = btrfs_find_space_cluster(trans, root,
3611 block_group, last_ptr, 3611 block_group, last_ptr,
3612 offset, num_bytes, 3612 offset, num_bytes,
3613 empty_cluster + empty_size); 3613 empty_cluster + empty_size);
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index ac23476beb6e..4538e48581a5 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -579,6 +579,7 @@ out:
579 * it returns -enospc 579 * it returns -enospc
580 */ 580 */
581int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, 581int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
582 struct btrfs_root *root,
582 struct btrfs_block_group_cache *block_group, 583 struct btrfs_block_group_cache *block_group,
583 struct btrfs_free_cluster *cluster, 584 struct btrfs_free_cluster *cluster,
584 u64 offset, u64 bytes, u64 empty_size) 585 u64 offset, u64 bytes, u64 empty_size)
@@ -595,7 +596,9 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
595 int ret; 596 int ret;
596 597
597 /* for metadata, allow allocates with more holes */ 598 /* for metadata, allow allocates with more holes */
598 if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) { 599 if (btrfs_test_opt(root, SSD_SPREAD)) {
600 min_bytes = bytes + empty_size;
601 } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
599 /* 602 /*
600 * we want to do larger allocations when we are 603 * we want to do larger allocations when we are
601 * flushing out the delayed refs, it helps prevent 604 * flushing out the delayed refs, it helps prevent
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
index ab0bdc0a63ce..266fb8764054 100644
--- a/fs/btrfs/free-space-cache.h
+++ b/fs/btrfs/free-space-cache.h
@@ -31,6 +31,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
31 u64 bytes); 31 u64 bytes);
32u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group); 32u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
33int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, 33int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
34 struct btrfs_root *root,
34 struct btrfs_block_group_cache *block_group, 35 struct btrfs_block_group_cache *block_group,
35 struct btrfs_free_cluster *cluster, 36 struct btrfs_free_cluster *cluster,
36 u64 offset, u64 bytes, u64 empty_size); 37 u64 offset, u64 bytes, u64 empty_size);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 22855a18eb48..7f5b2889949a 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -66,8 +66,8 @@ static void btrfs_put_super(struct super_block *sb)
66enum { 66enum {
67 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, 67 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
68 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, 68 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
69 Opt_ssd, Opt_nossd, Opt_thread_pool, Opt_noacl, Opt_compress, 69 Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
70 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err, 70 Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err,
71}; 71};
72 72
73static match_table_t tokens = { 73static match_table_t tokens = {
@@ -83,6 +83,7 @@ static match_table_t tokens = {
83 {Opt_thread_pool, "thread_pool=%d"}, 83 {Opt_thread_pool, "thread_pool=%d"},
84 {Opt_compress, "compress"}, 84 {Opt_compress, "compress"},
85 {Opt_ssd, "ssd"}, 85 {Opt_ssd, "ssd"},
86 {Opt_ssd_spread, "ssd_spread"},
86 {Opt_nossd, "nossd"}, 87 {Opt_nossd, "nossd"},
87 {Opt_noacl, "noacl"}, 88 {Opt_noacl, "noacl"},
88 {Opt_notreelog, "notreelog"}, 89 {Opt_notreelog, "notreelog"},
@@ -174,9 +175,17 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
174 printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); 175 printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
175 btrfs_set_opt(info->mount_opt, SSD); 176 btrfs_set_opt(info->mount_opt, SSD);
176 break; 177 break;
178 case Opt_ssd_spread:
179 printk(KERN_INFO "btrfs: use spread ssd "
180 "allocation scheme\n");
181 btrfs_set_opt(info->mount_opt, SSD);
182 btrfs_set_opt(info->mount_opt, SSD_SPREAD);
183 break;
177 case Opt_nossd: 184 case Opt_nossd:
178 printk(KERN_INFO "btrfs: not using ssd allocation scheme\n"); 185 printk(KERN_INFO "btrfs: not using ssd allocation "
186 "scheme\n");
179 btrfs_clear_opt(info->mount_opt, SSD); 187 btrfs_clear_opt(info->mount_opt, SSD);
188 btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
180 break; 189 break;
181 case Opt_nobarrier: 190 case Opt_nobarrier:
182 printk(KERN_INFO "btrfs: turning off barriers\n"); 191 printk(KERN_INFO "btrfs: turning off barriers\n");
@@ -429,7 +438,9 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
429 seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); 438 seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
430 if (btrfs_test_opt(root, COMPRESS)) 439 if (btrfs_test_opt(root, COMPRESS))
431 seq_puts(seq, ",compress"); 440 seq_puts(seq, ",compress");
432 if (btrfs_test_opt(root, SSD)) 441 if (btrfs_test_opt(root, SSD_SPREAD))
442 seq_puts(seq, ",ssd_spread");
443 else if (btrfs_test_opt(root, SSD))
433 seq_puts(seq, ",ssd"); 444 seq_puts(seq, ",ssd");
434 if (btrfs_test_opt(root, NOTREELOG)) 445 if (btrfs_test_opt(root, NOTREELOG))
435 seq_puts(seq, ",notreelog"); 446 seq_puts(seq, ",notreelog");