| // SPDX-License-Identifier: GPL-2.0+ | |
| #include "ctree.h" | |
| int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, | |
| struct btrfs_root_item *item, struct btrfs_key *key) | |
| { | |
| struct btrfs_path *path; | |
| struct btrfs_key search_key; | |
| struct btrfs_key found_key; | |
| struct extent_buffer *l; | |
| int ret; | |
| int slot; | |
| path = btrfs_alloc_path(); | |
| if (!path) | |
| return -ENOMEM; | |
| search_key.objectid = objectid; | |
| search_key.type = BTRFS_ROOT_ITEM_KEY; | |
| search_key.offset = (u64)-1; | |
| ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0); | |
| if (ret < 0) | |
| goto out; | |
| if (path->slots[0] == 0) { | |
| ret = -ENOENT; | |
| goto out; | |
| } | |
| BUG_ON(ret == 0); | |
| l = path->nodes[0]; | |
| slot = path->slots[0] - 1; | |
| btrfs_item_key_to_cpu(l, &found_key, slot); | |
| if (found_key.type != BTRFS_ROOT_ITEM_KEY || | |
| found_key.objectid != objectid) { | |
| ret = -ENOENT; | |
| goto out; | |
| } | |
| read_extent_buffer(l, item, btrfs_item_ptr_offset(l, slot), | |
| sizeof(*item)); | |
| memcpy(key, &found_key, sizeof(found_key)); | |
| ret = 0; | |
| out: | |
| btrfs_free_path(path); | |
| return ret; | |
| } |