btrfs: move the space_info handling code to space-info.c
authorJosef Bacik <josef@toxicpanda.com>
Tue, 18 Jun 2019 20:09:19 +0000 (16:09 -0400)
committerDavid Sterba <dsterba@suse.com>
Tue, 2 Jul 2019 10:30:52 +0000 (12:30 +0200)
These are the basic init and lookup functions and some helper functions,
fairly straightforward before the bad stuff starts.

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/Makefile
fs/btrfs/extent-tree.c
fs/btrfs/space-info.c [new file with mode: 0644]
fs/btrfs/space-info.h

index ca693dd..ae5fad5 100644 (file)
@@ -10,7 +10,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
           export.o tree-log.o free-space-cache.o zlib.o lzo.o zstd.o \
           compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
           reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \
-          uuid-tree.o props.o free-space-tree.o tree-checker.o
+          uuid-tree.o props.o free-space-tree.o tree-checker.o space-info.o
 
 btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
 btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o
index 34d08fc..2ec0409 100644 (file)
@@ -713,25 +713,6 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(
        return block_group_cache_tree_search(info, bytenr, 1);
 }
 
-static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
-                                                 u64 flags)
-{
-       struct list_head *head = &info->space_info;
-       struct btrfs_space_info *found;
-
-       flags &= BTRFS_BLOCK_GROUP_TYPE_MASK;
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(found, head, list) {
-               if (found->flags & flags) {
-                       rcu_read_unlock();
-                       return found;
-               }
-       }
-       rcu_read_unlock();
-       return NULL;
-}
-
 static u64 generic_ref_to_space_flags(struct btrfs_ref *ref)
 {
        if (ref->type == BTRFS_REF_METADATA) {
@@ -749,7 +730,7 @@ static void add_pinned_bytes(struct btrfs_fs_info *fs_info,
        struct btrfs_space_info *space_info;
        u64 flags = generic_ref_to_space_flags(ref);
 
-       space_info = __find_space_info(fs_info, flags);
+       space_info = btrfs_find_space_info(fs_info, flags);
        ASSERT(space_info);
        percpu_counter_add_batch(&space_info->total_bytes_pinned, ref->len,
                    BTRFS_TOTAL_BYTES_PINNED_BATCH);
@@ -761,27 +742,12 @@ static void sub_pinned_bytes(struct btrfs_fs_info *fs_info,
        struct btrfs_space_info *space_info;
        u64 flags = generic_ref_to_space_flags(ref);
 
-       space_info = __find_space_info(fs_info, flags);
+       space_info = btrfs_find_space_info(fs_info, flags);
        ASSERT(space_info);
        percpu_counter_add_batch(&space_info->total_bytes_pinned, -ref->len,
                    BTRFS_TOTAL_BYTES_PINNED_BATCH);
 }
 
-/*
- * after adding space to the filesystem, we need to clear the full flags
- * on all the space infos.
- */
-void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
-{
-       struct list_head *head = &info->space_info;
-       struct btrfs_space_info *found;
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(found, head, list)
-               found->full = 0;
-       rcu_read_unlock();
-}
-
 /* simple helper to search for an existing data extent at a given offset */
 int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len)
 {
@@ -2449,7 +2415,7 @@ void btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
                        flags = BTRFS_BLOCK_GROUP_SYSTEM;
                else
                        flags = BTRFS_BLOCK_GROUP_METADATA;
-               space_info = __find_space_info(fs_info, flags);
+               space_info = btrfs_find_space_info(fs_info, flags);
                ASSERT(space_info);
                percpu_counter_add_batch(&space_info->total_bytes_pinned,
                                   -head->num_bytes,
@@ -3821,93 +3787,6 @@ void btrfs_wait_nocow_writers(struct btrfs_block_group_cache *bg)
        wait_var_event(&bg->nocow_writers, !atomic_read(&bg->nocow_writers));
 }
 
-static const char *alloc_name(u64 flags)
-{
-       switch (flags) {
-       case BTRFS_BLOCK_GROUP_METADATA|BTRFS_BLOCK_GROUP_DATA:
-               return "mixed";
-       case BTRFS_BLOCK_GROUP_METADATA:
-               return "metadata";
-       case BTRFS_BLOCK_GROUP_DATA:
-               return "data";
-       case BTRFS_BLOCK_GROUP_SYSTEM:
-               return "system";
-       default:
-               WARN_ON(1);
-               return "invalid-combination";
-       };
-}
-
-static int create_space_info(struct btrfs_fs_info *info, u64 flags)
-{
-
-       struct btrfs_space_info *space_info;
-       int i;
-       int ret;
-
-       space_info = kzalloc(sizeof(*space_info), GFP_NOFS);
-       if (!space_info)
-               return -ENOMEM;
-
-       ret = percpu_counter_init(&space_info->total_bytes_pinned, 0,
-                                GFP_KERNEL);
-       if (ret) {
-               kfree(space_info);
-               return ret;
-       }
-
-       for (i = 0; i < BTRFS_NR_RAID_TYPES; i++)
-               INIT_LIST_HEAD(&space_info->block_groups[i]);
-       init_rwsem(&space_info->groups_sem);
-       spin_lock_init(&space_info->lock);
-       space_info->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
-       space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
-       init_waitqueue_head(&space_info->wait);
-       INIT_LIST_HEAD(&space_info->ro_bgs);
-       INIT_LIST_HEAD(&space_info->tickets);
-       INIT_LIST_HEAD(&space_info->priority_tickets);
-
-       ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
-                                   info->space_info_kobj, "%s",
-                                   alloc_name(space_info->flags));
-       if (ret) {
-               kobject_put(&space_info->kobj);
-               return ret;
-       }
-
-       list_add_rcu(&space_info->list, &info->space_info);
-       if (flags & BTRFS_BLOCK_GROUP_DATA)
-               info->data_sinfo = space_info;
-
-       return ret;
-}
-
-static void update_space_info(struct btrfs_fs_info *info, u64 flags,
-                            u64 total_bytes, u64 bytes_used,
-                            u64 bytes_readonly,
-                            struct btrfs_space_info **space_info)
-{
-       struct btrfs_space_info *found;
-       int factor;
-
-       factor = btrfs_bg_type_to_factor(flags);
-
-       found = __find_space_info(info, flags);
-       ASSERT(found);
-       spin_lock(&found->lock);
-       found->total_bytes += total_bytes;
-       found->disk_total += total_bytes * factor;
-       found->bytes_used += bytes_used;
-       found->disk_used += bytes_used * factor;
-       found->bytes_readonly += bytes_readonly;
-       if (total_bytes > 0)
-               found->full = 0;
-       btrfs_space_info_add_new_bytes(info, found, total_bytes -
-                                      bytes_used - bytes_readonly);
-       spin_unlock(&found->lock);
-       *space_info = found;
-}
-
 static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
 {
        u64 extra_flags = chunk_to_extended(flags) &
@@ -4055,15 +3934,6 @@ u64 btrfs_system_alloc_profile(struct btrfs_fs_info *fs_info)
        return get_alloc_profile(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
 }
 
-static u64 btrfs_space_info_used(struct btrfs_space_info *s_info,
-                                bool may_use_included)
-{
-       ASSERT(s_info);
-       return s_info->bytes_used + s_info->bytes_reserved +
-               s_info->bytes_pinned + s_info->bytes_readonly +
-               (may_use_included ? s_info->bytes_may_use : 0);
-}
-
 int btrfs_alloc_data_chunk_ondemand(struct btrfs_inode *inode, u64 bytes)
 {
        struct btrfs_root *root = inode->root;
@@ -4339,7 +4209,7 @@ void check_system_chunk(struct btrfs_trans_handle *trans, u64 type)
         */
        lockdep_assert_held(&fs_info->chunk_mutex);
 
-       info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
+       info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
        spin_lock(&info->lock);
        left = info->total_bytes - btrfs_space_info_used(info, true);
        spin_unlock(&info->lock);
@@ -4399,7 +4269,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, u64 flags,
        if (trans->allocating_chunk)
                return -ENOSPC;
 
-       space_info = __find_space_info(fs_info, flags);
+       space_info = btrfs_find_space_info(fs_info, flags);
        ASSERT(space_info);
 
        do {
@@ -4627,7 +4497,7 @@ static void shrink_delalloc(struct btrfs_fs_info *fs_info, u64 to_reclaim,
        to_reclaim = items * EXTENT_SIZE_PER_ITEM;
 
        trans = (struct btrfs_trans_handle *)current->journal_info;
-       space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
+       space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
 
        delalloc_bytes = percpu_counter_sum_positive(
                                                &fs_info->delalloc_bytes);
@@ -4965,7 +4835,7 @@ static void btrfs_async_reclaim_metadata_space(struct work_struct *work)
        u64 last_tickets_id;
 
        fs_info = container_of(work, struct btrfs_fs_info, async_reclaim_work);
-       space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
+       space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
 
        spin_lock(&space_info->lock);
        to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info,
@@ -5611,7 +5481,7 @@ void btrfs_init_metadata_block_rsv(struct btrfs_fs_info *fs_info,
                                   unsigned short type)
 {
        btrfs_init_block_rsv(rsv, type);
-       rsv->space_info = __find_space_info(fs_info,
+       rsv->space_info = btrfs_find_space_info(fs_info,
                                            BTRFS_BLOCK_GROUP_METADATA);
 }
 
@@ -5836,10 +5706,10 @@ static void init_global_block_rsv(struct btrfs_fs_info *fs_info)
 {
        struct btrfs_space_info *space_info;
 
-       space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
+       space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
        fs_info->chunk_block_rsv.space_info = space_info;
 
-       space_info = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
+       space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
        fs_info->global_block_rsv.space_info = space_info;
        fs_info->trans_block_rsv.space_info = space_info;
        fs_info->empty_block_rsv.space_info = space_info;
@@ -5948,7 +5818,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
        }
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, items);
-       rsv->space_info = __find_space_info(fs_info,
+       rsv->space_info = btrfs_find_space_info(fs_info,
                                            BTRFS_BLOCK_GROUP_METADATA);
        ret = btrfs_block_rsv_add(root, rsv, num_bytes,
                                  BTRFS_RESERVE_FLUSH_ALL);
@@ -7743,7 +7613,7 @@ static noinline int find_free_extent(struct btrfs_fs_info *fs_info,
 
        trace_find_free_extent(fs_info, num_bytes, empty_size, flags);
 
-       space_info = __find_space_info(fs_info, flags);
+       space_info = btrfs_find_space_info(fs_info, flags);
        if (!space_info) {
                btrfs_err(fs_info, "No space info for %llu", flags);
                return -ENOSPC;
@@ -8097,7 +7967,7 @@ again:
                } else if (btrfs_test_opt(fs_info, ENOSPC_DEBUG)) {
                        struct btrfs_space_info *sinfo;
 
-                       sinfo = __find_space_info(fs_info, flags);
+                       sinfo = btrfs_find_space_info(fs_info, flags);
                        btrfs_err(fs_info,
                                  "allocation failed flags %llu, wanted %llu",
                                  flags, num_bytes);
@@ -10130,7 +10000,7 @@ void btrfs_add_raid_kobjects(struct btrfs_fs_info *fs_info)
        spin_unlock(&fs_info->pending_raid_kobjs_lock);
 
        list_for_each_entry(rkobj, &list, list) {
-               space_info = __find_space_info(fs_info, rkobj->flags);
+               space_info = btrfs_find_space_info(fs_info, rkobj->flags);
 
                ret = kobject_add(&rkobj->kobj, &space_info->kobj,
                                "%s", btrfs_bg_type_to_raid_name(rkobj->flags));
@@ -10397,9 +10267,9 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
                }
 
                trace_btrfs_add_block_group(info, cache, 0);
-               update_space_info(info, cache->flags, found_key.offset,
-                                 btrfs_block_group_used(&cache->item),
-                                 cache->bytes_super, &space_info);
+               btrfs_update_space_info(info, cache->flags, found_key.offset,
+                                       btrfs_block_group_used(&cache->item),
+                                       cache->bytes_super, &space_info);
 
                cache->space_info = space_info;
 
@@ -10533,7 +10403,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
         * assigned to our block group. We want our bg to be added to the rbtree
         * with its ->space_info set.
         */
-       cache->space_info = __find_space_info(fs_info, cache->flags);
+       cache->space_info = btrfs_find_space_info(fs_info, cache->flags);
        ASSERT(cache->space_info);
 
        ret = btrfs_add_block_group_cache(fs_info, cache);
@@ -10548,7 +10418,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
         * the rbtree, update the space info's counters.
         */
        trace_btrfs_add_block_group(fs_info, cache, 1);
-       update_space_info(fs_info, cache->flags, size, bytes_used,
+       btrfs_update_space_info(fs_info, cache->flags, size, bytes_used,
                                cache->bytes_super, &cache->space_info);
        update_global_block_rsv(fs_info);
 
@@ -11085,43 +10955,6 @@ next:
        spin_unlock(&fs_info->unused_bgs_lock);
 }
 
-int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
-{
-       struct btrfs_super_block *disk_super;
-       u64 features;
-       u64 flags;
-       int mixed = 0;
-       int ret;
-
-       disk_super = fs_info->super_copy;
-       if (!btrfs_super_root(disk_super))
-               return -EINVAL;
-
-       features = btrfs_super_incompat_flags(disk_super);
-       if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
-               mixed = 1;
-
-       flags = BTRFS_BLOCK_GROUP_SYSTEM;
-       ret = create_space_info(fs_info, flags);
-       if (ret)
-               goto out;
-
-       if (mixed) {
-               flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA;
-               ret = create_space_info(fs_info, flags);
-       } else {
-               flags = BTRFS_BLOCK_GROUP_METADATA;
-               ret = create_space_info(fs_info, flags);
-               if (ret)
-                       goto out;
-
-               flags = BTRFS_BLOCK_GROUP_DATA;
-               ret = create_space_info(fs_info, flags);
-       }
-out:
-       return ret;
-}
-
 int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
                                   u64 start, u64 end)
 {
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c
new file mode 100644 (file)
index 0000000..6edcd9b
--- /dev/null
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "ctree.h"
+#include "space-info.h"
+#include "sysfs.h"
+#include "volumes.h"
+
+u64 btrfs_space_info_used(struct btrfs_space_info *s_info,
+                         bool may_use_included)
+{
+       ASSERT(s_info);
+       return s_info->bytes_used + s_info->bytes_reserved +
+               s_info->bytes_pinned + s_info->bytes_readonly +
+               (may_use_included ? s_info->bytes_may_use : 0);
+}
+
+/*
+ * after adding space to the filesystem, we need to clear the full flags
+ * on all the space infos.
+ */
+void btrfs_clear_space_info_full(struct btrfs_fs_info *info)
+{
+       struct list_head *head = &info->space_info;
+       struct btrfs_space_info *found;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(found, head, list)
+               found->full = 0;
+       rcu_read_unlock();
+}
+
+static const char *alloc_name(u64 flags)
+{
+       switch (flags) {
+       case BTRFS_BLOCK_GROUP_METADATA|BTRFS_BLOCK_GROUP_DATA:
+               return "mixed";
+       case BTRFS_BLOCK_GROUP_METADATA:
+               return "metadata";
+       case BTRFS_BLOCK_GROUP_DATA:
+               return "data";
+       case BTRFS_BLOCK_GROUP_SYSTEM:
+               return "system";
+       default:
+               WARN_ON(1);
+               return "invalid-combination";
+       };
+}
+
+static int create_space_info(struct btrfs_fs_info *info, u64 flags)
+{
+
+       struct btrfs_space_info *space_info;
+       int i;
+       int ret;
+
+       space_info = kzalloc(sizeof(*space_info), GFP_NOFS);
+       if (!space_info)
+               return -ENOMEM;
+
+       ret = percpu_counter_init(&space_info->total_bytes_pinned, 0,
+                                GFP_KERNEL);
+       if (ret) {
+               kfree(space_info);
+               return ret;
+       }
+
+       for (i = 0; i < BTRFS_NR_RAID_TYPES; i++)
+               INIT_LIST_HEAD(&space_info->block_groups[i]);
+       init_rwsem(&space_info->groups_sem);
+       spin_lock_init(&space_info->lock);
+       space_info->flags = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
+       space_info->force_alloc = CHUNK_ALLOC_NO_FORCE;
+       init_waitqueue_head(&space_info->wait);
+       INIT_LIST_HEAD(&space_info->ro_bgs);
+       INIT_LIST_HEAD(&space_info->tickets);
+       INIT_LIST_HEAD(&space_info->priority_tickets);
+
+       ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
+                                   info->space_info_kobj, "%s",
+                                   alloc_name(space_info->flags));
+       if (ret) {
+               kobject_put(&space_info->kobj);
+               return ret;
+       }
+
+       list_add_rcu(&space_info->list, &info->space_info);
+       if (flags & BTRFS_BLOCK_GROUP_DATA)
+               info->data_sinfo = space_info;
+
+       return ret;
+}
+
+int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_super_block *disk_super;
+       u64 features;
+       u64 flags;
+       int mixed = 0;
+       int ret;
+
+       disk_super = fs_info->super_copy;
+       if (!btrfs_super_root(disk_super))
+               return -EINVAL;
+
+       features = btrfs_super_incompat_flags(disk_super);
+       if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
+               mixed = 1;
+
+       flags = BTRFS_BLOCK_GROUP_SYSTEM;
+       ret = create_space_info(fs_info, flags);
+       if (ret)
+               goto out;
+
+       if (mixed) {
+               flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA;
+               ret = create_space_info(fs_info, flags);
+       } else {
+               flags = BTRFS_BLOCK_GROUP_METADATA;
+               ret = create_space_info(fs_info, flags);
+               if (ret)
+                       goto out;
+
+               flags = BTRFS_BLOCK_GROUP_DATA;
+               ret = create_space_info(fs_info, flags);
+       }
+out:
+       return ret;
+}
+
+void btrfs_update_space_info(struct btrfs_fs_info *info, u64 flags,
+                            u64 total_bytes, u64 bytes_used,
+                            u64 bytes_readonly,
+                            struct btrfs_space_info **space_info)
+{
+       struct btrfs_space_info *found;
+       int factor;
+
+       factor = btrfs_bg_type_to_factor(flags);
+
+       found = btrfs_find_space_info(info, flags);
+       ASSERT(found);
+       spin_lock(&found->lock);
+       found->total_bytes += total_bytes;
+       found->disk_total += total_bytes * factor;
+       found->bytes_used += bytes_used;
+       found->disk_used += bytes_used * factor;
+       found->bytes_readonly += bytes_readonly;
+       if (total_bytes > 0)
+               found->full = 0;
+       btrfs_space_info_add_new_bytes(info, found,
+                                      total_bytes - bytes_used -
+                                      bytes_readonly);
+       spin_unlock(&found->lock);
+       *space_info = found;
+}
+
+struct btrfs_space_info *btrfs_find_space_info(struct btrfs_fs_info *info,
+                                              u64 flags)
+{
+       struct list_head *head = &info->space_info;
+       struct btrfs_space_info *found;
+
+       flags &= BTRFS_BLOCK_GROUP_TYPE_MASK;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(found, head, list) {
+               if (found->flags & flags) {
+                       rcu_read_unlock();
+                       return found;
+               }
+       }
+       rcu_read_unlock();
+       return NULL;
+}
index 46f15b8..d1264d9 100644 (file)
@@ -81,5 +81,15 @@ void btrfs_space_info_add_new_bytes(struct btrfs_fs_info *fs_info,
 void btrfs_space_info_add_old_bytes(struct btrfs_fs_info *fs_info,
                                    struct btrfs_space_info *space_info,
                                    u64 num_bytes);
+int btrfs_init_space_info(struct btrfs_fs_info *fs_info);
+void btrfs_update_space_info(struct btrfs_fs_info *info, u64 flags,
+                            u64 total_bytes, u64 bytes_used,
+                            u64 bytes_readonly,
+                            struct btrfs_space_info **space_info);
+struct btrfs_space_info *btrfs_find_space_info(struct btrfs_fs_info *info,
+                                              u64 flags);
+u64 btrfs_space_info_used(struct btrfs_space_info *s_info,
+                         bool may_use_included);
+void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
 
 #endif /* BTRFS_SPACE_INFO_H */