tree-defrag.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2007 Oracle. All rights reserved.
  4. */
  5. #include <linux/sched.h>
  6. #include "ctree.h"
  7. #include "disk-io.h"
  8. #include "print-tree.h"
  9. #include "transaction.h"
  10. #include "locking.h"
  11. /*
  12. * Defrag all the leaves in a given btree.
  13. * Read all the leaves and try to get key order to
  14. * better reflect disk order
  15. */
  16. int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
  17. struct btrfs_root *root)
  18. {
  19. struct btrfs_path *path = NULL;
  20. struct btrfs_key key;
  21. int ret = 0;
  22. int wret;
  23. int level;
  24. int next_key_ret = 0;
  25. u64 last_ret = 0;
  26. if (root->fs_info->extent_root == root) {
  27. /*
  28. * there's recursion here right now in the tree locking,
  29. * we can't defrag the extent root without deadlock
  30. */
  31. goto out;
  32. }
  33. if (!test_bit(BTRFS_ROOT_REF_COWS, &root->state))
  34. goto out;
  35. path = btrfs_alloc_path();
  36. if (!path)
  37. return -ENOMEM;
  38. level = btrfs_header_level(root->node);
  39. if (level == 0)
  40. goto out;
  41. if (root->defrag_progress.objectid == 0) {
  42. struct extent_buffer *root_node;
  43. u32 nritems;
  44. root_node = btrfs_lock_root_node(root);
  45. btrfs_set_lock_blocking_write(root_node);
  46. nritems = btrfs_header_nritems(root_node);
  47. root->defrag_max.objectid = 0;
  48. /* from above we know this is not a leaf */
  49. btrfs_node_key_to_cpu(root_node, &root->defrag_max,
  50. nritems - 1);
  51. btrfs_tree_unlock(root_node);
  52. free_extent_buffer(root_node);
  53. memset(&key, 0, sizeof(key));
  54. } else {
  55. memcpy(&key, &root->defrag_progress, sizeof(key));
  56. }
  57. path->keep_locks = 1;
  58. ret = btrfs_search_forward(root, &key, path, BTRFS_OLDEST_GENERATION);
  59. if (ret < 0)
  60. goto out;
  61. if (ret > 0) {
  62. ret = 0;
  63. goto out;
  64. }
  65. btrfs_release_path(path);
  66. /*
  67. * We don't need a lock on a leaf. btrfs_realloc_node() will lock all
  68. * leafs from path->nodes[1], so set lowest_level to 1 to avoid later
  69. * a deadlock (attempting to write lock an already write locked leaf).
  70. */
  71. path->lowest_level = 1;
  72. wret = btrfs_search_slot(trans, root, &key, path, 0, 1);
  73. if (wret < 0) {
  74. ret = wret;
  75. goto out;
  76. }
  77. if (!path->nodes[1]) {
  78. ret = 0;
  79. goto out;
  80. }
  81. /*
  82. * The node at level 1 must always be locked when our path has
  83. * keep_locks set and lowest_level is 1, regardless of the value of
  84. * path->slots[1].
  85. */
  86. BUG_ON(path->locks[1] == 0);
  87. ret = btrfs_realloc_node(trans, root,
  88. path->nodes[1], 0,
  89. &last_ret,
  90. &root->defrag_progress);
  91. if (ret) {
  92. WARN_ON(ret == -EAGAIN);
  93. goto out;
  94. }
  95. /*
  96. * Now that we reallocated the node we can find the next key. Note that
  97. * btrfs_find_next_key() can release our path and do another search
  98. * without COWing, this is because even with path->keep_locks = 1,
  99. * btrfs_search_slot() / ctree.c:unlock_up() does not keeps a lock on a
  100. * node when path->slots[node_level - 1] does not point to the last
  101. * item or a slot beyond the last item (ctree.c:unlock_up()). Therefore
  102. * we search for the next key after reallocating our node.
  103. */
  104. path->slots[1] = btrfs_header_nritems(path->nodes[1]);
  105. next_key_ret = btrfs_find_next_key(root, path, &key, 1,
  106. BTRFS_OLDEST_GENERATION);
  107. if (next_key_ret == 0) {
  108. memcpy(&root->defrag_progress, &key, sizeof(key));
  109. ret = -EAGAIN;
  110. }
  111. out:
  112. btrfs_free_path(path);
  113. if (ret == -EAGAIN) {
  114. if (root->defrag_max.objectid > root->defrag_progress.objectid)
  115. goto done;
  116. if (root->defrag_max.type > root->defrag_progress.type)
  117. goto done;
  118. if (root->defrag_max.offset > root->defrag_progress.offset)
  119. goto done;
  120. ret = 0;
  121. }
  122. done:
  123. if (ret != -EAGAIN) {
  124. memset(&root->defrag_progress, 0,
  125. sizeof(root->defrag_progress));
  126. root->defrag_trans_start = trans->transid;
  127. }
  128. return ret;
  129. }