root.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * BTRFS filesystem implementation for U-Boot
  3. *
  4. * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include "btrfs.h"
  9. static void read_root_item(struct btrfs_path *p, struct btrfs_root_item *item)
  10. {
  11. u32 len;
  12. int reset = 0;
  13. len = btrfs_path_item_size(p);
  14. memcpy(item, btrfs_path_item_ptr(p, struct btrfs_root_item), len);
  15. btrfs_root_item_to_cpu(item);
  16. if (len < sizeof(*item))
  17. reset = 1;
  18. if (!reset && item->generation != item->generation_v2) {
  19. if (item->generation_v2 != 0)
  20. printf("%s: generation != generation_v2 in root item",
  21. __func__);
  22. reset = 1;
  23. }
  24. if (reset) {
  25. memset(&item->generation_v2, 0,
  26. sizeof(*item) - offsetof(struct btrfs_root_item,
  27. generation_v2));
  28. }
  29. }
  30. int btrfs_find_root(u64 objectid, struct btrfs_root *root,
  31. struct btrfs_root_item *root_item)
  32. {
  33. struct btrfs_path path;
  34. struct btrfs_root_item my_root_item;
  35. if (!btrfs_search_tree_key_type(&btrfs_info.tree_root, objectid,
  36. BTRFS_ROOT_ITEM_KEY, &path))
  37. return -1;
  38. if (!root_item)
  39. root_item = &my_root_item;
  40. read_root_item(&path, root_item);
  41. if (root) {
  42. root->objectid = objectid;
  43. root->bytenr = root_item->bytenr;
  44. root->root_dirid = root_item->root_dirid;
  45. }
  46. btrfs_free_path(&path);
  47. return 0;
  48. }
  49. u64 btrfs_lookup_root_ref(u64 subvolid, struct btrfs_root_ref *refp, char *name)
  50. {
  51. struct btrfs_path path;
  52. struct btrfs_key *key;
  53. struct btrfs_root_ref *ref;
  54. u64 res = -1ULL;
  55. key = btrfs_search_tree_key_type(&btrfs_info.tree_root, subvolid,
  56. BTRFS_ROOT_BACKREF_KEY, &path);
  57. if (!key)
  58. return -1ULL;
  59. ref = btrfs_path_item_ptr(&path, struct btrfs_root_ref);
  60. btrfs_root_ref_to_cpu(ref);
  61. if (refp)
  62. *refp = *ref;
  63. if (name) {
  64. if (ref->name_len > BTRFS_VOL_NAME_MAX) {
  65. printf("%s: volume name too long: %u\n", __func__,
  66. ref->name_len);
  67. goto out;
  68. }
  69. memcpy(name, ref + 1, ref->name_len);
  70. }
  71. res = key->offset;
  72. out:
  73. btrfs_free_path(&path);
  74. return res;
  75. }