]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: move uuid tree related code to uuid-tree.[ch]
authorQu Wenruo <wqu@suse.com>
Wed, 24 Jul 2024 04:59:02 +0000 (14:29 +0930)
committerDavid Sterba <dsterba@suse.com>
Tue, 10 Sep 2024 14:51:12 +0000 (16:51 +0200)
Functions btrfs_uuid_scan_kthread() and btrfs_create_uuid_tree() are for
UUID tree rescan and creation, it's not suitable for volumes.[ch].

Move them to uuid-tree.[ch] instead.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/uuid-tree.c
fs/btrfs/uuid-tree.h
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index eae75bb572b99ec635f3b07f29cf59ee0c801100..c6399513c66fff62ccf1838d1c21e153e2964837 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) STRATO AG 2013.  All rights reserved.
  */
 
+#include <linux/kthread.h>
 #include <linux/uuid.h>
 #include <asm/unaligned.h>
 #include "messages.h"
@@ -12,6 +13,7 @@
 #include "fs.h"
 #include "accessors.h"
 #include "uuid-tree.h"
+#include "ioctl.h"
 
 static void btrfs_uuid_to_key(const u8 *uuid, u8 type, struct btrfs_key *key)
 {
@@ -390,3 +392,180 @@ out:
        btrfs_free_path(path);
        return ret;
 }
+
+int btrfs_uuid_scan_kthread(void *data)
+{
+       struct btrfs_fs_info *fs_info = data;
+       struct btrfs_root *root = fs_info->tree_root;
+       struct btrfs_key key;
+       struct btrfs_path *path = NULL;
+       int ret = 0;
+       struct extent_buffer *eb;
+       int slot;
+       struct btrfs_root_item root_item;
+       u32 item_size;
+       struct btrfs_trans_handle *trans = NULL;
+       bool closing = false;
+
+       path = btrfs_alloc_path();
+       if (!path) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       key.objectid = 0;
+       key.type = BTRFS_ROOT_ITEM_KEY;
+       key.offset = 0;
+
+       while (1) {
+               if (btrfs_fs_closing(fs_info)) {
+                       closing = true;
+                       break;
+               }
+               ret = btrfs_search_forward(root, &key, path,
+                               BTRFS_OLDEST_GENERATION);
+               if (ret) {
+                       if (ret > 0)
+                               ret = 0;
+                       break;
+               }
+
+               if (key.type != BTRFS_ROOT_ITEM_KEY ||
+                   (key.objectid < BTRFS_FIRST_FREE_OBJECTID &&
+                    key.objectid != BTRFS_FS_TREE_OBJECTID) ||
+                   key.objectid > BTRFS_LAST_FREE_OBJECTID)
+                       goto skip;
+
+               eb = path->nodes[0];
+               slot = path->slots[0];
+               item_size = btrfs_item_size(eb, slot);
+               if (item_size < sizeof(root_item))
+                       goto skip;
+
+               read_extent_buffer(eb, &root_item,
+                                  btrfs_item_ptr_offset(eb, slot),
+                                  (int)sizeof(root_item));
+               if (btrfs_root_refs(&root_item) == 0)
+                       goto skip;
+
+               if (!btrfs_is_empty_uuid(root_item.uuid) ||
+                   !btrfs_is_empty_uuid(root_item.received_uuid)) {
+                       if (trans)
+                               goto update_tree;
+
+                       btrfs_release_path(path);
+                       /*
+                        * 1 - subvol uuid item
+                        * 1 - received_subvol uuid item
+                        */
+                       trans = btrfs_start_transaction(fs_info->uuid_root, 2);
+                       if (IS_ERR(trans)) {
+                               ret = PTR_ERR(trans);
+                               break;
+                       }
+                       continue;
+               } else {
+                       goto skip;
+               }
+update_tree:
+               btrfs_release_path(path);
+               if (!btrfs_is_empty_uuid(root_item.uuid)) {
+                       ret = btrfs_uuid_tree_add(trans, root_item.uuid,
+                                                 BTRFS_UUID_KEY_SUBVOL,
+                                                 key.objectid);
+                       if (ret < 0) {
+                               btrfs_warn(fs_info, "uuid_tree_add failed %d",
+                                       ret);
+                               break;
+                       }
+               }
+
+               if (!btrfs_is_empty_uuid(root_item.received_uuid)) {
+                       ret = btrfs_uuid_tree_add(trans,
+                                                 root_item.received_uuid,
+                                                BTRFS_UUID_KEY_RECEIVED_SUBVOL,
+                                                 key.objectid);
+                       if (ret < 0) {
+                               btrfs_warn(fs_info, "uuid_tree_add failed %d",
+                                       ret);
+                               break;
+                       }
+               }
+
+skip:
+               btrfs_release_path(path);
+               if (trans) {
+                       ret = btrfs_end_transaction(trans);
+                       trans = NULL;
+                       if (ret)
+                               break;
+               }
+
+               if (key.offset < (u64)-1) {
+                       key.offset++;
+               } else if (key.type < BTRFS_ROOT_ITEM_KEY) {
+                       key.offset = 0;
+                       key.type = BTRFS_ROOT_ITEM_KEY;
+               } else if (key.objectid < (u64)-1) {
+                       key.offset = 0;
+                       key.type = BTRFS_ROOT_ITEM_KEY;
+                       key.objectid++;
+               } else {
+                       break;
+               }
+               cond_resched();
+       }
+
+out:
+       btrfs_free_path(path);
+       if (trans && !IS_ERR(trans))
+               btrfs_end_transaction(trans);
+       if (ret)
+               btrfs_warn(fs_info, "btrfs_uuid_scan_kthread failed %d", ret);
+       else if (!closing)
+               set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
+       up(&fs_info->uuid_tree_rescan_sem);
+       return 0;
+}
+
+int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info)
+{
+       struct btrfs_trans_handle *trans;
+       struct btrfs_root *tree_root = fs_info->tree_root;
+       struct btrfs_root *uuid_root;
+       struct task_struct *task;
+       int ret;
+
+       /*
+        * 1 - root node
+        * 1 - root item
+        */
+       trans = btrfs_start_transaction(tree_root, 2);
+       if (IS_ERR(trans))
+               return PTR_ERR(trans);
+
+       uuid_root = btrfs_create_tree(trans, BTRFS_UUID_TREE_OBJECTID);
+       if (IS_ERR(uuid_root)) {
+               ret = PTR_ERR(uuid_root);
+               btrfs_abort_transaction(trans, ret);
+               btrfs_end_transaction(trans);
+               return ret;
+       }
+
+       fs_info->uuid_root = uuid_root;
+
+       ret = btrfs_commit_transaction(trans);
+       if (ret)
+               return ret;
+
+       down(&fs_info->uuid_tree_rescan_sem);
+       task = kthread_run(btrfs_uuid_scan_kthread, fs_info, "btrfs-uuid");
+       if (IS_ERR(task)) {
+               /* fs_info->update_uuid_tree_gen remains 0 in all error case */
+               btrfs_warn(fs_info, "failed to start uuid_scan task");
+               up(&fs_info->uuid_tree_rescan_sem);
+               return PTR_ERR(task);
+       }
+
+       return 0;
+}
index a3f5757cc7cffc54e83676fb5ee7e57d1ebaf875..c60ad20325cce03450b8abc029468f6f79670aa4 100644 (file)
@@ -13,5 +13,7 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, const u8 *uuid, u8 typ
 int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, const u8 *uuid, u8 type,
                        u64 subid);
 int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info);
+int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info);
+int btrfs_uuid_scan_kthread(void *data);
 
 #endif
index fcedc43ef291a208128da00409219faf0e390984..ff7c7194f5f732aa31a8bd5601a81186fa68b26a 100644 (file)
@@ -4784,183 +4784,6 @@ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info)
        return 0;
 }
 
-int btrfs_uuid_scan_kthread(void *data)
-{
-       struct btrfs_fs_info *fs_info = data;
-       struct btrfs_root *root = fs_info->tree_root;
-       struct btrfs_key key;
-       struct btrfs_path *path = NULL;
-       int ret = 0;
-       struct extent_buffer *eb;
-       int slot;
-       struct btrfs_root_item root_item;
-       u32 item_size;
-       struct btrfs_trans_handle *trans = NULL;
-       bool closing = false;
-
-       path = btrfs_alloc_path();
-       if (!path) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       key.objectid = 0;
-       key.type = BTRFS_ROOT_ITEM_KEY;
-       key.offset = 0;
-
-       while (1) {
-               if (btrfs_fs_closing(fs_info)) {
-                       closing = true;
-                       break;
-               }
-               ret = btrfs_search_forward(root, &key, path,
-                               BTRFS_OLDEST_GENERATION);
-               if (ret) {
-                       if (ret > 0)
-                               ret = 0;
-                       break;
-               }
-
-               if (key.type != BTRFS_ROOT_ITEM_KEY ||
-                   (key.objectid < BTRFS_FIRST_FREE_OBJECTID &&
-                    key.objectid != BTRFS_FS_TREE_OBJECTID) ||
-                   key.objectid > BTRFS_LAST_FREE_OBJECTID)
-                       goto skip;
-
-               eb = path->nodes[0];
-               slot = path->slots[0];
-               item_size = btrfs_item_size(eb, slot);
-               if (item_size < sizeof(root_item))
-                       goto skip;
-
-               read_extent_buffer(eb, &root_item,
-                                  btrfs_item_ptr_offset(eb, slot),
-                                  (int)sizeof(root_item));
-               if (btrfs_root_refs(&root_item) == 0)
-                       goto skip;
-
-               if (!btrfs_is_empty_uuid(root_item.uuid) ||
-                   !btrfs_is_empty_uuid(root_item.received_uuid)) {
-                       if (trans)
-                               goto update_tree;
-
-                       btrfs_release_path(path);
-                       /*
-                        * 1 - subvol uuid item
-                        * 1 - received_subvol uuid item
-                        */
-                       trans = btrfs_start_transaction(fs_info->uuid_root, 2);
-                       if (IS_ERR(trans)) {
-                               ret = PTR_ERR(trans);
-                               break;
-                       }
-                       continue;
-               } else {
-                       goto skip;
-               }
-update_tree:
-               btrfs_release_path(path);
-               if (!btrfs_is_empty_uuid(root_item.uuid)) {
-                       ret = btrfs_uuid_tree_add(trans, root_item.uuid,
-                                                 BTRFS_UUID_KEY_SUBVOL,
-                                                 key.objectid);
-                       if (ret < 0) {
-                               btrfs_warn(fs_info, "uuid_tree_add failed %d",
-                                       ret);
-                               break;
-                       }
-               }
-
-               if (!btrfs_is_empty_uuid(root_item.received_uuid)) {
-                       ret = btrfs_uuid_tree_add(trans,
-                                                 root_item.received_uuid,
-                                                BTRFS_UUID_KEY_RECEIVED_SUBVOL,
-                                                 key.objectid);
-                       if (ret < 0) {
-                               btrfs_warn(fs_info, "uuid_tree_add failed %d",
-                                       ret);
-                               break;
-                       }
-               }
-
-skip:
-               btrfs_release_path(path);
-               if (trans) {
-                       ret = btrfs_end_transaction(trans);
-                       trans = NULL;
-                       if (ret)
-                               break;
-               }
-
-               if (key.offset < (u64)-1) {
-                       key.offset++;
-               } else if (key.type < BTRFS_ROOT_ITEM_KEY) {
-                       key.offset = 0;
-                       key.type = BTRFS_ROOT_ITEM_KEY;
-               } else if (key.objectid < (u64)-1) {
-                       key.offset = 0;
-                       key.type = BTRFS_ROOT_ITEM_KEY;
-                       key.objectid++;
-               } else {
-                       break;
-               }
-               cond_resched();
-       }
-
-out:
-       btrfs_free_path(path);
-       if (trans && !IS_ERR(trans))
-               btrfs_end_transaction(trans);
-       if (ret)
-               btrfs_warn(fs_info, "btrfs_uuid_scan_kthread failed %d", ret);
-       else if (!closing)
-               set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
-       up(&fs_info->uuid_tree_rescan_sem);
-       return 0;
-}
-
-int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info)
-{
-       struct btrfs_trans_handle *trans;
-       struct btrfs_root *tree_root = fs_info->tree_root;
-       struct btrfs_root *uuid_root;
-       struct task_struct *task;
-       int ret;
-
-       /*
-        * 1 - root node
-        * 1 - root item
-        */
-       trans = btrfs_start_transaction(tree_root, 2);
-       if (IS_ERR(trans))
-               return PTR_ERR(trans);
-
-       uuid_root = btrfs_create_tree(trans, BTRFS_UUID_TREE_OBJECTID);
-       if (IS_ERR(uuid_root)) {
-               ret = PTR_ERR(uuid_root);
-               btrfs_abort_transaction(trans, ret);
-               btrfs_end_transaction(trans);
-               return ret;
-       }
-
-       fs_info->uuid_root = uuid_root;
-
-       ret = btrfs_commit_transaction(trans);
-       if (ret)
-               return ret;
-
-       down(&fs_info->uuid_tree_rescan_sem);
-       task = kthread_run(btrfs_uuid_scan_kthread, fs_info, "btrfs-uuid");
-       if (IS_ERR(task)) {
-               /* fs_info->update_uuid_tree_gen remains 0 in all error case */
-               btrfs_warn(fs_info, "failed to start uuid_scan task");
-               up(&fs_info->uuid_tree_rescan_sem);
-               return PTR_ERR(task);
-       }
-
-       return 0;
-}
-
 /*
  * shrinking a device means finding all of the device extents past
  * the new size, and then following the back refs to the chunks.
index 37a09ebb34dd88d4e9e376f196b7a1377da8a250..c947187539ddbd4cc024f906c3b4ce9d3bffa140 100644 (file)
@@ -725,8 +725,6 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
 int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
 int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset);
 int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
-int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info);
-int btrfs_uuid_scan_kthread(void *data);
 bool btrfs_chunk_writeable(struct btrfs_fs_info *fs_info, u64 chunk_offset);
 void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
 int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,