root-tree.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include <linux/module.h>
  2. #include "ctree.h"
  3. #include "disk-io.h"
  4. #include "print-tree.h"
  5. int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
  6. struct btrfs_root_item *item, struct btrfs_key *key)
  7. {
  8. struct btrfs_path *path;
  9. struct btrfs_key search_key;
  10. struct btrfs_leaf *l;
  11. int ret;
  12. int slot;
  13. search_key.objectid = objectid;
  14. search_key.flags = (u32)-1;
  15. search_key.offset = (u32)-1;
  16. path = btrfs_alloc_path();
  17. BUG_ON(!path);
  18. btrfs_init_path(path);
  19. ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
  20. if (ret < 0)
  21. goto out;
  22. BUG_ON(ret == 0);
  23. l = btrfs_buffer_leaf(path->nodes[0]);
  24. BUG_ON(path->slots[0] == 0);
  25. slot = path->slots[0] - 1;
  26. if (btrfs_disk_key_objectid(&l->items[slot].key) != objectid) {
  27. ret = 1;
  28. goto out;
  29. }
  30. memcpy(item, btrfs_item_ptr(l, slot, struct btrfs_root_item),
  31. sizeof(*item));
  32. btrfs_disk_key_to_cpu(key, &l->items[slot].key);
  33. ret = 0;
  34. out:
  35. btrfs_release_path(root, path);
  36. btrfs_free_path(path);
  37. return ret;
  38. }
  39. int btrfs_update_root(struct btrfs_trans_handle *trans, struct btrfs_root
  40. *root, struct btrfs_key *key, struct btrfs_root_item
  41. *item)
  42. {
  43. struct btrfs_path *path;
  44. struct btrfs_leaf *l;
  45. int ret;
  46. int slot;
  47. struct btrfs_root_item *update_item;
  48. path = btrfs_alloc_path();
  49. BUG_ON(!path);
  50. btrfs_init_path(path);
  51. ret = btrfs_search_slot(trans, root, key, path, 0, 1);
  52. if (ret < 0)
  53. goto out;
  54. BUG_ON(ret != 0);
  55. l = btrfs_buffer_leaf(path->nodes[0]);
  56. slot = path->slots[0];
  57. update_item = btrfs_item_ptr(l, slot, struct btrfs_root_item);
  58. btrfs_memcpy(root, l, update_item, item, sizeof(*item));
  59. btrfs_mark_buffer_dirty(path->nodes[0]);
  60. out:
  61. btrfs_release_path(root, path);
  62. btrfs_free_path(path);
  63. return ret;
  64. }
  65. int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root
  66. *root, struct btrfs_key *key, struct btrfs_root_item
  67. *item)
  68. {
  69. int ret;
  70. ret = btrfs_insert_item(trans, root, key, item, sizeof(*item));
  71. BUG_ON(ret);
  72. return ret;
  73. }
  74. int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
  75. struct btrfs_key *key)
  76. {
  77. struct btrfs_path *path;
  78. int ret;
  79. u32 refs;
  80. struct btrfs_root_item *ri;
  81. path = btrfs_alloc_path();
  82. BUG_ON(!path);
  83. btrfs_init_path(path);
  84. ret = btrfs_search_slot(trans, root, key, path, -1, 1);
  85. if (ret < 0)
  86. goto out;
  87. BUG_ON(ret != 0);
  88. ri = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
  89. path->slots[0], struct btrfs_root_item);
  90. refs = btrfs_root_refs(ri);
  91. BUG_ON(refs == 0);
  92. if (refs == 1) {
  93. ret = btrfs_del_item(trans, root, path);
  94. printk("deleting root %Lu %Lu %u\n", key->objectid, key->offset, key->flags);
  95. } else {
  96. btrfs_set_root_refs(ri, refs - 1);
  97. printk("ref now %u root %Lu %Lu %u\n", refs -1, key->objectid, key->offset, key->flags);
  98. mark_buffer_dirty(path->nodes[0]);
  99. }
  100. out:
  101. btrfs_release_path(root, path);
  102. btrfs_free_path(path);
  103. return ret;
  104. }