Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

btrfs: move uuid tree related code to uuid-tree.[ch]

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>

authored by

Qu Wenruo and committed by
David Sterba
c92bf5df ab094670

+181 -179
+179
fs/btrfs/uuid-tree.c
··· 3 3 * Copyright (C) STRATO AG 2013. All rights reserved. 4 4 */ 5 5 6 + #include <linux/kthread.h> 6 7 #include <linux/uuid.h> 7 8 #include <asm/unaligned.h> 8 9 #include "messages.h" ··· 13 12 #include "fs.h" 14 13 #include "accessors.h" 15 14 #include "uuid-tree.h" 15 + #include "ioctl.h" 16 16 17 17 static void btrfs_uuid_to_key(const u8 *uuid, u8 type, struct btrfs_key *key) 18 18 { ··· 391 389 out: 392 390 btrfs_free_path(path); 393 391 return ret; 392 + } 393 + 394 + int btrfs_uuid_scan_kthread(void *data) 395 + { 396 + struct btrfs_fs_info *fs_info = data; 397 + struct btrfs_root *root = fs_info->tree_root; 398 + struct btrfs_key key; 399 + struct btrfs_path *path = NULL; 400 + int ret = 0; 401 + struct extent_buffer *eb; 402 + int slot; 403 + struct btrfs_root_item root_item; 404 + u32 item_size; 405 + struct btrfs_trans_handle *trans = NULL; 406 + bool closing = false; 407 + 408 + path = btrfs_alloc_path(); 409 + if (!path) { 410 + ret = -ENOMEM; 411 + goto out; 412 + } 413 + 414 + key.objectid = 0; 415 + key.type = BTRFS_ROOT_ITEM_KEY; 416 + key.offset = 0; 417 + 418 + while (1) { 419 + if (btrfs_fs_closing(fs_info)) { 420 + closing = true; 421 + break; 422 + } 423 + ret = btrfs_search_forward(root, &key, path, 424 + BTRFS_OLDEST_GENERATION); 425 + if (ret) { 426 + if (ret > 0) 427 + ret = 0; 428 + break; 429 + } 430 + 431 + if (key.type != BTRFS_ROOT_ITEM_KEY || 432 + (key.objectid < BTRFS_FIRST_FREE_OBJECTID && 433 + key.objectid != BTRFS_FS_TREE_OBJECTID) || 434 + key.objectid > BTRFS_LAST_FREE_OBJECTID) 435 + goto skip; 436 + 437 + eb = path->nodes[0]; 438 + slot = path->slots[0]; 439 + item_size = btrfs_item_size(eb, slot); 440 + if (item_size < sizeof(root_item)) 441 + goto skip; 442 + 443 + read_extent_buffer(eb, &root_item, 444 + btrfs_item_ptr_offset(eb, slot), 445 + (int)sizeof(root_item)); 446 + if (btrfs_root_refs(&root_item) == 0) 447 + goto skip; 448 + 449 + if (!btrfs_is_empty_uuid(root_item.uuid) || 450 + !btrfs_is_empty_uuid(root_item.received_uuid)) { 451 + if (trans) 452 + goto update_tree; 453 + 454 + btrfs_release_path(path); 455 + /* 456 + * 1 - subvol uuid item 457 + * 1 - received_subvol uuid item 458 + */ 459 + trans = btrfs_start_transaction(fs_info->uuid_root, 2); 460 + if (IS_ERR(trans)) { 461 + ret = PTR_ERR(trans); 462 + break; 463 + } 464 + continue; 465 + } else { 466 + goto skip; 467 + } 468 + update_tree: 469 + btrfs_release_path(path); 470 + if (!btrfs_is_empty_uuid(root_item.uuid)) { 471 + ret = btrfs_uuid_tree_add(trans, root_item.uuid, 472 + BTRFS_UUID_KEY_SUBVOL, 473 + key.objectid); 474 + if (ret < 0) { 475 + btrfs_warn(fs_info, "uuid_tree_add failed %d", 476 + ret); 477 + break; 478 + } 479 + } 480 + 481 + if (!btrfs_is_empty_uuid(root_item.received_uuid)) { 482 + ret = btrfs_uuid_tree_add(trans, 483 + root_item.received_uuid, 484 + BTRFS_UUID_KEY_RECEIVED_SUBVOL, 485 + key.objectid); 486 + if (ret < 0) { 487 + btrfs_warn(fs_info, "uuid_tree_add failed %d", 488 + ret); 489 + break; 490 + } 491 + } 492 + 493 + skip: 494 + btrfs_release_path(path); 495 + if (trans) { 496 + ret = btrfs_end_transaction(trans); 497 + trans = NULL; 498 + if (ret) 499 + break; 500 + } 501 + 502 + if (key.offset < (u64)-1) { 503 + key.offset++; 504 + } else if (key.type < BTRFS_ROOT_ITEM_KEY) { 505 + key.offset = 0; 506 + key.type = BTRFS_ROOT_ITEM_KEY; 507 + } else if (key.objectid < (u64)-1) { 508 + key.offset = 0; 509 + key.type = BTRFS_ROOT_ITEM_KEY; 510 + key.objectid++; 511 + } else { 512 + break; 513 + } 514 + cond_resched(); 515 + } 516 + 517 + out: 518 + btrfs_free_path(path); 519 + if (trans && !IS_ERR(trans)) 520 + btrfs_end_transaction(trans); 521 + if (ret) 522 + btrfs_warn(fs_info, "btrfs_uuid_scan_kthread failed %d", ret); 523 + else if (!closing) 524 + set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags); 525 + up(&fs_info->uuid_tree_rescan_sem); 526 + return 0; 527 + } 528 + 529 + int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info) 530 + { 531 + struct btrfs_trans_handle *trans; 532 + struct btrfs_root *tree_root = fs_info->tree_root; 533 + struct btrfs_root *uuid_root; 534 + struct task_struct *task; 535 + int ret; 536 + 537 + /* 538 + * 1 - root node 539 + * 1 - root item 540 + */ 541 + trans = btrfs_start_transaction(tree_root, 2); 542 + if (IS_ERR(trans)) 543 + return PTR_ERR(trans); 544 + 545 + uuid_root = btrfs_create_tree(trans, BTRFS_UUID_TREE_OBJECTID); 546 + if (IS_ERR(uuid_root)) { 547 + ret = PTR_ERR(uuid_root); 548 + btrfs_abort_transaction(trans, ret); 549 + btrfs_end_transaction(trans); 550 + return ret; 551 + } 552 + 553 + fs_info->uuid_root = uuid_root; 554 + 555 + ret = btrfs_commit_transaction(trans); 556 + if (ret) 557 + return ret; 558 + 559 + down(&fs_info->uuid_tree_rescan_sem); 560 + task = kthread_run(btrfs_uuid_scan_kthread, fs_info, "btrfs-uuid"); 561 + if (IS_ERR(task)) { 562 + /* fs_info->update_uuid_tree_gen remains 0 in all error case */ 563 + btrfs_warn(fs_info, "failed to start uuid_scan task"); 564 + up(&fs_info->uuid_tree_rescan_sem); 565 + return PTR_ERR(task); 566 + } 567 + 568 + return 0; 394 569 }
+2
fs/btrfs/uuid-tree.h
··· 13 13 int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, const u8 *uuid, u8 type, 14 14 u64 subid); 15 15 int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info); 16 + int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info); 17 + int btrfs_uuid_scan_kthread(void *data); 16 18 17 19 #endif
-177
fs/btrfs/volumes.c
··· 4784 4784 return 0; 4785 4785 } 4786 4786 4787 - int btrfs_uuid_scan_kthread(void *data) 4788 - { 4789 - struct btrfs_fs_info *fs_info = data; 4790 - struct btrfs_root *root = fs_info->tree_root; 4791 - struct btrfs_key key; 4792 - struct btrfs_path *path = NULL; 4793 - int ret = 0; 4794 - struct extent_buffer *eb; 4795 - int slot; 4796 - struct btrfs_root_item root_item; 4797 - u32 item_size; 4798 - struct btrfs_trans_handle *trans = NULL; 4799 - bool closing = false; 4800 - 4801 - path = btrfs_alloc_path(); 4802 - if (!path) { 4803 - ret = -ENOMEM; 4804 - goto out; 4805 - } 4806 - 4807 - key.objectid = 0; 4808 - key.type = BTRFS_ROOT_ITEM_KEY; 4809 - key.offset = 0; 4810 - 4811 - while (1) { 4812 - if (btrfs_fs_closing(fs_info)) { 4813 - closing = true; 4814 - break; 4815 - } 4816 - ret = btrfs_search_forward(root, &key, path, 4817 - BTRFS_OLDEST_GENERATION); 4818 - if (ret) { 4819 - if (ret > 0) 4820 - ret = 0; 4821 - break; 4822 - } 4823 - 4824 - if (key.type != BTRFS_ROOT_ITEM_KEY || 4825 - (key.objectid < BTRFS_FIRST_FREE_OBJECTID && 4826 - key.objectid != BTRFS_FS_TREE_OBJECTID) || 4827 - key.objectid > BTRFS_LAST_FREE_OBJECTID) 4828 - goto skip; 4829 - 4830 - eb = path->nodes[0]; 4831 - slot = path->slots[0]; 4832 - item_size = btrfs_item_size(eb, slot); 4833 - if (item_size < sizeof(root_item)) 4834 - goto skip; 4835 - 4836 - read_extent_buffer(eb, &root_item, 4837 - btrfs_item_ptr_offset(eb, slot), 4838 - (int)sizeof(root_item)); 4839 - if (btrfs_root_refs(&root_item) == 0) 4840 - goto skip; 4841 - 4842 - if (!btrfs_is_empty_uuid(root_item.uuid) || 4843 - !btrfs_is_empty_uuid(root_item.received_uuid)) { 4844 - if (trans) 4845 - goto update_tree; 4846 - 4847 - btrfs_release_path(path); 4848 - /* 4849 - * 1 - subvol uuid item 4850 - * 1 - received_subvol uuid item 4851 - */ 4852 - trans = btrfs_start_transaction(fs_info->uuid_root, 2); 4853 - if (IS_ERR(trans)) { 4854 - ret = PTR_ERR(trans); 4855 - break; 4856 - } 4857 - continue; 4858 - } else { 4859 - goto skip; 4860 - } 4861 - update_tree: 4862 - btrfs_release_path(path); 4863 - if (!btrfs_is_empty_uuid(root_item.uuid)) { 4864 - ret = btrfs_uuid_tree_add(trans, root_item.uuid, 4865 - BTRFS_UUID_KEY_SUBVOL, 4866 - key.objectid); 4867 - if (ret < 0) { 4868 - btrfs_warn(fs_info, "uuid_tree_add failed %d", 4869 - ret); 4870 - break; 4871 - } 4872 - } 4873 - 4874 - if (!btrfs_is_empty_uuid(root_item.received_uuid)) { 4875 - ret = btrfs_uuid_tree_add(trans, 4876 - root_item.received_uuid, 4877 - BTRFS_UUID_KEY_RECEIVED_SUBVOL, 4878 - key.objectid); 4879 - if (ret < 0) { 4880 - btrfs_warn(fs_info, "uuid_tree_add failed %d", 4881 - ret); 4882 - break; 4883 - } 4884 - } 4885 - 4886 - skip: 4887 - btrfs_release_path(path); 4888 - if (trans) { 4889 - ret = btrfs_end_transaction(trans); 4890 - trans = NULL; 4891 - if (ret) 4892 - break; 4893 - } 4894 - 4895 - if (key.offset < (u64)-1) { 4896 - key.offset++; 4897 - } else if (key.type < BTRFS_ROOT_ITEM_KEY) { 4898 - key.offset = 0; 4899 - key.type = BTRFS_ROOT_ITEM_KEY; 4900 - } else if (key.objectid < (u64)-1) { 4901 - key.offset = 0; 4902 - key.type = BTRFS_ROOT_ITEM_KEY; 4903 - key.objectid++; 4904 - } else { 4905 - break; 4906 - } 4907 - cond_resched(); 4908 - } 4909 - 4910 - out: 4911 - btrfs_free_path(path); 4912 - if (trans && !IS_ERR(trans)) 4913 - btrfs_end_transaction(trans); 4914 - if (ret) 4915 - btrfs_warn(fs_info, "btrfs_uuid_scan_kthread failed %d", ret); 4916 - else if (!closing) 4917 - set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags); 4918 - up(&fs_info->uuid_tree_rescan_sem); 4919 - return 0; 4920 - } 4921 - 4922 - int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info) 4923 - { 4924 - struct btrfs_trans_handle *trans; 4925 - struct btrfs_root *tree_root = fs_info->tree_root; 4926 - struct btrfs_root *uuid_root; 4927 - struct task_struct *task; 4928 - int ret; 4929 - 4930 - /* 4931 - * 1 - root node 4932 - * 1 - root item 4933 - */ 4934 - trans = btrfs_start_transaction(tree_root, 2); 4935 - if (IS_ERR(trans)) 4936 - return PTR_ERR(trans); 4937 - 4938 - uuid_root = btrfs_create_tree(trans, BTRFS_UUID_TREE_OBJECTID); 4939 - if (IS_ERR(uuid_root)) { 4940 - ret = PTR_ERR(uuid_root); 4941 - btrfs_abort_transaction(trans, ret); 4942 - btrfs_end_transaction(trans); 4943 - return ret; 4944 - } 4945 - 4946 - fs_info->uuid_root = uuid_root; 4947 - 4948 - ret = btrfs_commit_transaction(trans); 4949 - if (ret) 4950 - return ret; 4951 - 4952 - down(&fs_info->uuid_tree_rescan_sem); 4953 - task = kthread_run(btrfs_uuid_scan_kthread, fs_info, "btrfs-uuid"); 4954 - if (IS_ERR(task)) { 4955 - /* fs_info->update_uuid_tree_gen remains 0 in all error case */ 4956 - btrfs_warn(fs_info, "failed to start uuid_scan task"); 4957 - up(&fs_info->uuid_tree_rescan_sem); 4958 - return PTR_ERR(task); 4959 - } 4960 - 4961 - return 0; 4962 - } 4963 - 4964 4787 /* 4965 4788 * shrinking a device means finding all of the device extents past 4966 4789 * the new size, and then following the back refs to the chunks.
-2
fs/btrfs/volumes.h
··· 725 725 int btrfs_pause_balance(struct btrfs_fs_info *fs_info); 726 726 int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset); 727 727 int btrfs_cancel_balance(struct btrfs_fs_info *fs_info); 728 - int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info); 729 - int btrfs_uuid_scan_kthread(void *data); 730 728 bool btrfs_chunk_writeable(struct btrfs_fs_info *fs_info, u64 chunk_offset); 731 729 void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); 732 730 int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,