]> git.hungrycats.org Git - linux/commitdiff
Btrfs: don't continue setting up space cache when enospc
authorJosef Bacik <jbacik@fb.com>
Thu, 1 Oct 2015 16:55:18 +0000 (12:55 -0400)
committerZygo Blaxell <zblaxell@thirteen.furryterror.org>
Thu, 22 Oct 2015 03:13:29 +0000 (23:13 -0400)
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>
(cherry picked from commit ba3b76af51515dbc94a2b7b3b07294d69f7ae7dd)

fs/btrfs/extent-tree.c
fs/btrfs/transaction.h

index ff144fc25b0bd578c4746d38c3547138384b3ce9..1f037a9aaf57b8e832f7c81f7a933eb2789054d1 100644 (file)
@@ -3388,6 +3388,15 @@ again:
        }
        spin_unlock(&block_group->lock);
 
+       /*
+        * We hit an ENOSPC when setting up the cache in this transaction, just
+        * skip doing the setup, we've already cleared the cache so we're safe.
+        */
+       if (test_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags)) {
+               ret = -ENOSPC;
+               goto out_put;
+       }
+
        /*
         * Try to preallocate enough space based on how big the block group is.
         * Keep in mind this has to include any pinned space which could end up
@@ -3408,8 +3417,18 @@ again:
        ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages,
                                              num_pages, num_pages,
                                              &alloc_hint);
+       /*
+        * Our cache requires contiguous chunks so that we don't modify a bunch
+        * of metadata or split extents when writing the cache out, which means
+        * we can enospc if we are heavily fragmented in addition to just normal
+        * out of space conditions.  So if we hit this just skip setting up any
+        * other block groups for this transaction, maybe we'll unpin enough
+        * space the next time around.
+        */
        if (!ret)
                dcs = BTRFS_DC_SETUP;
+       else if (ret == -ENOSPC)
+               set_bit(BTRFS_TRANS_CACHE_ENOSPC, &trans->transaction->flags);
        btrfs_free_reserved_data_space(inode, num_pages);
 
 out_put:
index cacd5b622a5ebb0995965d8758355c435d503451..d713d3205649cb909315a3c2fae5c88a4f6c3294 100644 (file)
@@ -34,6 +34,7 @@ enum btrfs_trans_state {
 
 #define BTRFS_TRANS_HAVE_FREE_BGS      0
 #define BTRFS_TRANS_DIRTY_BG_RUN       1
+#define BTRFS_TRANS_CACHE_ENOSPC       2
 
 struct btrfs_transaction {
        u64 transid;