Commit 451d7585a8bb1b9bec0d676ce3dece1923164e55

Authored by Chris Mason
1 parent c604480171

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

... ... @@ -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);
... ... @@ -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");