libbtrfsutil: don't return free space cache inodes from deleted_subvolumes()
Deleted free space cache inodes also get an orphan item in the root tree, but we shouldn't report those as deleted subvolumes. Deleted subvolumes will still have the root item, so we can just do an extra tree search. Reported-by: Tomohiro Misono <misono.tomohiro@jp.fujitsu.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
2a496a5b8b
commit
c41c5b1562
|
@ -1339,21 +1339,31 @@ PUBLIC enum btrfs_util_error btrfs_util_deleted_subvolumes_fd(int fd,
|
|||
}
|
||||
|
||||
header = (struct btrfs_ioctl_search_header *)(search.buf + buf_off);
|
||||
if (*n >= capacity) {
|
||||
size_t new_capacity = capacity ? capacity * 2 : 1;
|
||||
uint64_t *new_ids;
|
||||
|
||||
new_ids = reallocarray(*ids, new_capacity,
|
||||
sizeof(**ids));
|
||||
if (!new_ids)
|
||||
return BTRFS_UTIL_ERROR_NO_MEMORY;
|
||||
/*
|
||||
* The orphan item might be for a free space cache inode, so
|
||||
* check if there's a matching root item.
|
||||
*/
|
||||
err = btrfs_util_subvolume_info_fd(fd, header->offset, NULL);
|
||||
if (!err) {
|
||||
if (*n >= capacity) {
|
||||
size_t new_capacity;
|
||||
uint64_t *new_ids;
|
||||
|
||||
*ids = new_ids;
|
||||
capacity = new_capacity;
|
||||
new_capacity = capacity ? capacity * 2 : 1;
|
||||
new_ids = reallocarray(*ids, new_capacity,
|
||||
sizeof(**ids));
|
||||
if (!new_ids)
|
||||
return BTRFS_UTIL_ERROR_NO_MEMORY;
|
||||
|
||||
*ids = new_ids;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
(*ids)[(*n)++] = header->offset;
|
||||
} else if (err != BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
(*ids)[(*n)++] = header->offset;
|
||||
|
||||
items_pos++;
|
||||
buf_off += sizeof(*header) + header->len;
|
||||
search.key.min_offset = header->offset + 1;
|
||||
|
|
Loading…
Reference in a new issue