2 * BTRFS filesystem implementation for U-Boot
4 * 2017 Marek Behun, CZ.NIC, marek.behun@nic.cz
6 * SPDX-License-Identifier: GPL-2.0+
11 static int verify_dir_item(struct btrfs_dir_item *item, u32 start, u32 total)
13 u16 max_len = BTRFS_NAME_LEN;
16 if (item->type >= BTRFS_FT_MAX) {
17 printf("%s: invalid dir item type: %i\n", __func__, item->type);
21 if (item->type == BTRFS_FT_XATTR)
22 max_len = 255; /* XATTR_NAME_MAX */
24 end = start + sizeof(*item) + item->name_len;
25 if (item->name_len > max_len || end > total) {
26 printf("%s: invalid dir item name len: %u\n", __func__,
34 static struct btrfs_dir_item *
35 btrfs_match_dir_item_name(struct btrfs_path *path, const char *name,
38 struct btrfs_dir_item *item;
39 u32 total_len, cur = 0, this_len;
42 item = btrfs_path_item_ptr(path, struct btrfs_dir_item);
44 total_len = btrfs_path_item_size(path);
46 while (cur < total_len) {
47 btrfs_dir_item_to_cpu(item);
48 this_len = sizeof(*item) + item->name_len + item->data_len;
49 name_ptr = (const char *) (item + 1);
51 if (verify_dir_item(item, cur, total_len))
53 if (item->name_len == name_len && !memcmp(name_ptr, name,
58 item = (struct btrfs_dir_item *) ((u8 *) item + this_len);
64 int btrfs_lookup_dir_item(const struct btrfs_root *root, u64 dir,
65 const char *name, int name_len,
66 struct btrfs_dir_item *item)
68 struct btrfs_path path;
70 struct btrfs_dir_item *res = NULL;
73 key.type = BTRFS_DIR_ITEM_KEY;
74 key.offset = btrfs_name_hash(name, name_len);
76 if (btrfs_search_tree(root, &key, &path))
79 if (btrfs_comp_keys_type(&key, btrfs_path_leaf_key(&path)))
82 res = btrfs_match_dir_item_name(&path, name, name_len);
86 btrfs_free_path(&path);
90 int btrfs_readdir(const struct btrfs_root *root, u64 dir,
91 btrfs_readdir_callback_t callback)
93 struct btrfs_path path;
94 struct btrfs_key key, *found_key;
95 struct btrfs_dir_item *item;
99 key.type = BTRFS_DIR_INDEX_KEY;
102 if (btrfs_search_tree(root, &key, &path))
106 found_key = btrfs_path_leaf_key(&path);
107 if (btrfs_comp_keys_type(&key, found_key))
110 item = btrfs_path_item_ptr(&path, struct btrfs_dir_item);
111 btrfs_dir_item_to_cpu(item);
113 if (verify_dir_item(item, 0, sizeof(*item) + item->name_len))
115 if (item->type == BTRFS_FT_XATTR)
118 if (callback(root, item))
120 } while (!(res = btrfs_next_slot(&path)));
122 btrfs_free_path(&path);
124 return res < 0 ? -1 : 0;