]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/btrfs/block-group.c
Merge tag 'for-linus-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / fs / btrfs / block-group.c
index 14851584e2454d316265d657b36b602c2fbddcf9..404e050ce8eee36c0142706975b5648dd2af72c9 100644 (file)
@@ -1191,7 +1191,6 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force)
 {
        struct btrfs_space_info *sinfo = cache->space_info;
        u64 num_bytes;
-       u64 sinfo_used;
        int ret = -ENOSPC;
 
        spin_lock(&sinfo->lock);
@@ -1205,19 +1204,38 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force)
 
        num_bytes = cache->length - cache->reserved - cache->pinned -
                    cache->bytes_super - cache->used;
-       sinfo_used = btrfs_space_info_used(sinfo, true);
 
        /*
-        * sinfo_used + num_bytes should always <= sinfo->total_bytes.
-        *
-        * Here we make sure if we mark this bg RO, we still have enough
-        * free space as buffer.
+        * Data never overcommits, even in mixed mode, so do just the straight
+        * check of left over space in how much we have allocated.
         */
-       if (sinfo_used + num_bytes <= sinfo->total_bytes) {
+       if (force) {
+               ret = 0;
+       } else if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA) {
+               u64 sinfo_used = btrfs_space_info_used(sinfo, true);
+
+               /*
+                * Here we make sure if we mark this bg RO, we still have enough
+                * free space as buffer.
+                */
+               if (sinfo_used + num_bytes <= sinfo->total_bytes)
+                       ret = 0;
+       } else {
+               /*
+                * We overcommit metadata, so we need to do the
+                * btrfs_can_overcommit check here, and we need to pass in
+                * BTRFS_RESERVE_NO_FLUSH to give ourselves the most amount of
+                * leeway to allow us to mark this block group as read only.
+                */
+               if (btrfs_can_overcommit(cache->fs_info, sinfo, num_bytes,
+                                        BTRFS_RESERVE_NO_FLUSH))
+                       ret = 0;
+       }
+
+       if (!ret) {
                sinfo->bytes_readonly += num_bytes;
                cache->ro++;
                list_add_tail(&cache->ro_list, &sinfo->ro_bgs);
-               ret = 0;
        }
 out:
        spin_unlock(&cache->lock);
@@ -1225,9 +1243,6 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force)
        if (ret == -ENOSPC && btrfs_test_opt(cache->fs_info, ENOSPC_DEBUG)) {
                btrfs_info(cache->fs_info,
                        "unable to make block group %llu ro", cache->start);
-               btrfs_info(cache->fs_info,
-                       "sinfo_used=%llu bg_num_bytes=%llu",
-                       sinfo_used, num_bytes);
                btrfs_dump_space_info(cache->fs_info, cache->space_info, 0, 0);
        }
        return ret;
@@ -2225,7 +2240,7 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache,
                }
        }
 
-       ret = inc_block_group_ro(cache, !do_chunk_alloc);
+       ret = inc_block_group_ro(cache, 0);
        if (!do_chunk_alloc)
                goto unlock_out;
        if (!ret)