root.c 1.9 KB

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