Commit 451d7585a8bb1b9bec0d676ce3dece1923164e55
1 parent
c604480171
Exists in
master
and in
7 other branches
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>
Showing 5 changed files with 22 additions and 6 deletions Side-by-side Diff
fs/btrfs/ctree.h
... | ... | @@ -1100,6 +1100,7 @@ |
1100 | 1100 | #define BTRFS_MOUNT_COMPRESS (1 << 5) |
1101 | 1101 | #define BTRFS_MOUNT_NOTREELOG (1 << 6) |
1102 | 1102 | #define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7) |
1103 | +#define BTRFS_MOUNT_SSD_SPREAD (1 << 8) | |
1103 | 1104 | |
1104 | 1105 | #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) |
1105 | 1106 | #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) |
fs/btrfs/extent-tree.c
... | ... | @@ -3607,7 +3607,7 @@ |
3607 | 3607 | last_ptr_loop = 0; |
3608 | 3608 | |
3609 | 3609 | /* allocate a cluster in this block group */ |
3610 | - ret = btrfs_find_space_cluster(trans, | |
3610 | + ret = btrfs_find_space_cluster(trans, root, | |
3611 | 3611 | block_group, last_ptr, |
3612 | 3612 | offset, num_bytes, |
3613 | 3613 | empty_cluster + empty_size); |
fs/btrfs/free-space-cache.c
... | ... | @@ -579,6 +579,7 @@ |
579 | 579 | * it returns -enospc |
580 | 580 | */ |
581 | 581 | int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, |
582 | + struct btrfs_root *root, | |
582 | 583 | struct btrfs_block_group_cache *block_group, |
583 | 584 | struct btrfs_free_cluster *cluster, |
584 | 585 | u64 offset, u64 bytes, u64 empty_size) |
... | ... | @@ -595,7 +596,9 @@ |
595 | 596 | int ret; |
596 | 597 | |
597 | 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 | 603 | * we want to do larger allocations when we are |
601 | 604 | * flushing out the delayed refs, it helps prevent |
fs/btrfs/free-space-cache.h
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | u64 bytes); |
32 | 32 | u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group); |
33 | 33 | int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, |
34 | + struct btrfs_root *root, | |
34 | 35 | struct btrfs_block_group_cache *block_group, |
35 | 36 | struct btrfs_free_cluster *cluster, |
36 | 37 | u64 offset, u64 bytes, u64 empty_size); |
fs/btrfs/super.c
... | ... | @@ -66,8 +66,8 @@ |
66 | 66 | enum { |
67 | 67 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, |
68 | 68 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, |
69 | - Opt_ssd, Opt_nossd, Opt_thread_pool, Opt_noacl, Opt_compress, | |
70 | - Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err, | |
69 | + Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, | |
70 | + Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err, | |
71 | 71 | }; |
72 | 72 | |
73 | 73 | static match_table_t tokens = { |
... | ... | @@ -83,6 +83,7 @@ |
83 | 83 | {Opt_thread_pool, "thread_pool=%d"}, |
84 | 84 | {Opt_compress, "compress"}, |
85 | 85 | {Opt_ssd, "ssd"}, |
86 | + {Opt_ssd_spread, "ssd_spread"}, | |
86 | 87 | {Opt_nossd, "nossd"}, |
87 | 88 | {Opt_noacl, "noacl"}, |
88 | 89 | {Opt_notreelog, "notreelog"}, |
89 | 90 | |
90 | 91 | |
... | ... | @@ -174,9 +175,17 @@ |
174 | 175 | printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); |
175 | 176 | btrfs_set_opt(info->mount_opt, SSD); |
176 | 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 | 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 | 187 | btrfs_clear_opt(info->mount_opt, SSD); |
188 | + btrfs_clear_opt(info->mount_opt, SSD_SPREAD); | |
180 | 189 | break; |
181 | 190 | case Opt_nobarrier: |
182 | 191 | printk(KERN_INFO "btrfs: turning off barriers\n"); |
... | ... | @@ -429,7 +438,9 @@ |
429 | 438 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); |
430 | 439 | if (btrfs_test_opt(root, COMPRESS)) |
431 | 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 | 444 | seq_puts(seq, ",ssd"); |
434 | 445 | if (btrfs_test_opt(root, NOTREELOG)) |
435 | 446 | seq_puts(seq, ",notreelog"); |