diff options
author | Josef Bacik <jbacik@fb.com> | 2015-10-01 12:55:18 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-10-21 21:55:36 -0400 |
commit | 2968b1f48bd7366dd7310acde1ee6d1bf7791142 (patch) | |
tree | 77ba00b44557b8183168286752bda5f2175dac46 | |
parent | 4f4db2174d8d6cdc093cbb79d17fbfe0f4d9fbde (diff) |
Btrfs: don't continue setting up space cache when enospc
If we hit ENOSPC when setting up a space cache don't bother setting up any of
the other space cache's in this transaction, it'll just induce unnecessary
latency. Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 19 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 1 |
2 files changed, 20 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index febb5bc35a64..3185c457f025 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3403,6 +3403,15 @@ again: | |||
3403 | spin_unlock(&block_group->lock); | 3403 | spin_unlock(&block_group->lock); |
3404 | 3404 | ||
3405 | /* | 3405 | /* |
3406 | * We hit an ENOSPC when setting up the cache in this transaction, just | ||
3407 | * skip doing the setup, we've already cleared the cache so we're safe. | ||
3408 | */ | ||
3409 | if (test_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags)) { | ||
3410 | ret = -ENOSPC; | ||
3411 | goto out_put; | ||
3412 | } | ||
3413 | |||
3414 | /* | ||
3406 | * Try to preallocate enough space based on how big the block group is. | 3415 | * Try to preallocate enough space based on how big the block group is. |
3407 | * Keep in mind this has to include any pinned space which could end up | 3416 | * Keep in mind this has to include any pinned space which could end up |
3408 | * taking up quite a bit since it's not folded into the other space | 3417 | * taking up quite a bit since it's not folded into the other space |
@@ -3422,8 +3431,18 @@ again: | |||
3422 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, | 3431 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, |
3423 | num_pages, num_pages, | 3432 | num_pages, num_pages, |
3424 | &alloc_hint); | 3433 | &alloc_hint); |
3434 | /* | ||
3435 | * Our cache requires contiguous chunks so that we don't modify a bunch | ||
3436 | * of metadata or split extents when writing the cache out, which means | ||
3437 | * we can enospc if we are heavily fragmented in addition to just normal | ||
3438 | * out of space conditions. So if we hit this just skip setting up any | ||
3439 | * other block groups for this transaction, maybe we'll unpin enough | ||
3440 | * space the next time around. | ||
3441 | */ | ||
3425 | if (!ret) | 3442 | if (!ret) |
3426 | dcs = BTRFS_DC_SETUP; | 3443 | dcs = BTRFS_DC_SETUP; |
3444 | else if (ret == -ENOSPC) | ||
3445 | set_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags); | ||
3427 | btrfs_free_reserved_data_space(inode, num_pages); | 3446 | btrfs_free_reserved_data_space(inode, num_pages); |
3428 | 3447 | ||
3429 | out_put: | 3448 | out_put: |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 109b8b7fb48e..30ae75074ca4 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -34,6 +34,7 @@ enum btrfs_trans_state { | |||
34 | 34 | ||
35 | #define BTRFS_TRANS_HAVE_FREE_BGS 0 | 35 | #define BTRFS_TRANS_HAVE_FREE_BGS 0 |
36 | #define BTRFS_TRANS_DIRTY_BG_RUN 1 | 36 | #define BTRFS_TRANS_DIRTY_BG_RUN 1 |
37 | #define BTRFS_TRANS_CACHE_ENOSPC 2 | ||
37 | 38 | ||
38 | struct btrfs_transaction { | 39 | struct btrfs_transaction { |
39 | u64 transid; | 40 | u64 transid; |