ret = btrfs_uuid_tree_lookup(uuid_root, uuid, type, subid_cpu); if (ret != -ENOENT) return ret;
if (WARN_ON_ONCE(!uuid_root)) {
ret = -EINVAL; goto out;
}
btrfs_uuid_to_key(uuid, type, &key);
path = btrfs_alloc_path(); if (!path) {
ret = -ENOMEM; goto out;
}
ret = btrfs_insert_empty_item(trans, uuid_root, path, &key, sizeof(subid_le)); if (ret == 0) { /* Add an item for the type for the first time */
eb = path->nodes[0];
slot = path->slots[0];
offset = btrfs_item_ptr_offset(eb, slot);
} elseif (ret == -EEXIST) { /* * An item with that type already exists. * Extend the item and store the new subid at the end.
*/
btrfs_extend_item(trans, path, sizeof(subid_le));
eb = path->nodes[0];
slot = path->slots[0];
offset = btrfs_item_ptr_offset(eb, slot);
offset += btrfs_item_size(eb, slot) - sizeof(subid_le);
} else {
btrfs_warn(fs_info, "insert uuid item failed %d (0x%016llx, 0x%016llx) type %u!",
ret, key.objectid, key.offset, type); goto out;
}
/* 1 - for the uuid item */
trans = btrfs_start_transaction(uuid_root, 1); if (IS_ERR(trans)) {
ret = PTR_ERR(trans); goto out;
}
ret = btrfs_uuid_tree_remove(trans, uuid, type, subid);
btrfs_end_transaction(trans);
out: return ret;
}
/* * Check if there's an matching subvolume for given UUID * * Return: * 0 check succeeded, the entry is not outdated * > 0 if the check failed, the caller should remove the entry * < 0 if an error occurred
*/ staticint btrfs_check_uuid_tree_entry(struct btrfs_fs_info *fs_info, const u8 *uuid, u8 type, u64 subvolid)
{ int ret = 0; struct btrfs_root *subvol_root;
if (type != BTRFS_UUID_KEY_SUBVOL &&
type != BTRFS_UUID_KEY_RECEIVED_SUBVOL) goto out;
subvol_root = btrfs_get_fs_root(fs_info, subvolid, true); if (IS_ERR(subvol_root)) {
ret = PTR_ERR(subvol_root); if (ret == -ENOENT)
ret = 1; goto out;
}
switch (type) { case BTRFS_UUID_KEY_SUBVOL: if (memcmp(uuid, subvol_root->root_item.uuid, BTRFS_UUID_SIZE))
ret = 1; break; case BTRFS_UUID_KEY_RECEIVED_SUBVOL: if (memcmp(uuid, subvol_root->root_item.received_uuid,
BTRFS_UUID_SIZE))
ret = 1; break;
}
btrfs_put_root(subvol_root);
out: return ret;
}
int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info)
{ struct btrfs_root *root = fs_info->uuid_root; struct btrfs_key key; struct btrfs_path *path; int ret = 0; struct extent_buffer *leaf; int slot;
u32 item_size; unsignedlong offset;
path = btrfs_alloc_path(); if (!path) {
ret = -ENOMEM; goto out;
}
key.objectid = 0;
key.type = 0;
key.offset = 0;
again_search_slot:
ret = btrfs_search_forward(root, &key, path, BTRFS_OLDEST_GENERATION); if (ret) { if (ret > 0)
ret = 0; goto out;
}
while (1) { if (btrfs_fs_closing(fs_info)) {
ret = -EINTR; goto out;
}
cond_resched();
leaf = path->nodes[0];
slot = path->slots[0];
btrfs_item_key_to_cpu(leaf, &key, slot);
if (key.type != BTRFS_UUID_KEY_SUBVOL &&
key.type != BTRFS_UUID_KEY_RECEIVED_SUBVOL) goto skip;
put_unaligned_le64(key.objectid, uuid);
put_unaligned_le64(key.offset, uuid + sizeof(u64));
read_extent_buffer(leaf, &subid_le, offset, sizeof(subid_le));
subid_cpu = le64_to_cpu(subid_le);
ret = btrfs_check_uuid_tree_entry(fs_info, uuid,
key.type, subid_cpu); if (ret < 0) goto out; if (ret > 0) {
btrfs_release_path(path);
ret = btrfs_uuid_iter_rem(root, uuid, key.type,
subid_cpu); if (ret == 0) { /* * this might look inefficient, but the * justification is that it is an * exception that check_func returns 1, * and that in the regular case only one * entry per UUID exists.
*/ goto again_search_slot;
} if (ret < 0 && ret != -ENOENT) goto out;
key.offset++; goto again_search_slot;
}
item_size -= sizeof(subid_le);
offset += sizeof(subid_le);
}
skip:
ret = btrfs_next_item(root, path); if (ret == 0) continue; elseif (ret > 0)
ret = 0; break;
}
while (1) { if (btrfs_fs_closing(fs_info)) {
closing = true; break;
}
ret = btrfs_search_forward(root, &key, path,
BTRFS_OLDEST_GENERATION); if (ret) { if (ret > 0)
ret = 0; break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.