^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) Qu Wenruo 2017. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The module is used to catch unexpected/corrupted tree block data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Such behavior can be caused either by a fuzzed image or bugs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * The objective is to do leaf/node validation checks when tree block is read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * from disk, and check *every* possible member, so other code won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * need to checking them again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Due to the potential and unwanted damage, every checker needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * carefully reviewed otherwise so it does not prevent mount of valid images.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/error-injection.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "ctree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "tree-checker.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "disk-io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "compression.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "volumes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "misc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Error message should follow the following format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * corrupt <type>: <identifier>, <reason>[, <bad_value>]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * @type: leaf or node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @identifier: the necessary info to locate the leaf/node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * It's recommended to decode key.objecitd/offset if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * meaningful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * @reason: describe the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @bad_value: optional, it's recommended to output bad value and its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * expected value (range).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Since comma is used to separate the components, only space is allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * inside each component.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Append generic "corrupt leaf/node root=%llu block=%llu slot=%d: " to @fmt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Allows callers to customize the output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static void generic_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const struct btrfs_fs_info *fs_info = eb->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "corrupt %s: root=%llu block=%llu slot=%d, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * Customized reporter for extent data item, since its key objectid and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * offset has its own meaning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void file_extent_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) const struct btrfs_fs_info *fs_info = eb->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) btrfs_item_key_to_cpu(eb, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) "corrupt %s: root=%llu block=%llu slot=%d ino=%llu file_offset=%llu, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) key.objectid, key.offset, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Return 0 if the btrfs_file_extent_##name is aligned to @alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Else return 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CHECK_FE_ALIGNED(leaf, slot, fi, name, alignment) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) file_extent_err((leaf), (slot), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "invalid %s for file extent, have %llu, should be aligned to %u", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) (#name), btrfs_file_extent_##name((leaf), (fi)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (alignment)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static u64 file_extent_end(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct btrfs_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct btrfs_file_extent_item *extent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (btrfs_file_extent_type(leaf, extent) == BTRFS_FILE_EXTENT_INLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) len = btrfs_file_extent_ram_bytes(leaf, extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) end = ALIGN(key->offset + len, leaf->fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) len = btrfs_file_extent_num_bytes(leaf, extent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) end = key->offset + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Customized report for dir_item, the only new important information is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * key->objectid, which represents inode number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void dir_item_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) const struct btrfs_fs_info *fs_info = eb->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) btrfs_item_key_to_cpu(eb, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) "corrupt %s: root=%llu block=%llu slot=%d ino=%llu, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) key.objectid, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * This functions checks prev_key->objectid, to ensure current key and prev_key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * share the same objectid as inode number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * This is to detect missing INODE_ITEM in subvolume trees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Return true if everything is OK or we don't need to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Return false if anything is wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static bool check_prev_ino(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct btrfs_key *key, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct btrfs_key *prev_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* No prev key, skip check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (slot == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* Only these key->types needs to be checked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ASSERT(key->type == BTRFS_XATTR_ITEM_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) key->type == BTRFS_INODE_REF_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) key->type == BTRFS_DIR_INDEX_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) key->type == BTRFS_DIR_ITEM_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) key->type == BTRFS_EXTENT_DATA_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Only subvolume trees along with their reloc trees need this check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * Things like log tree doesn't follow this ino requirement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!is_fstree(btrfs_header_owner(leaf)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (key->objectid == prev_key->objectid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Error found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "invalid previous key objectid, have %llu expect %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) prev_key->objectid, key->objectid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int check_extent_data_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct btrfs_key *key, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct btrfs_key *prev_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct btrfs_file_extent_item *fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u32 sectorsize = fs_info->sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) u64 extent_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (!IS_ALIGNED(key->offset, sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "unaligned file_offset for file extent, have %llu should be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) key->offset, sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Previous key must have the same key->objectid (ino).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * It can be XATTR_ITEM, INODE_ITEM or just another EXTENT_DATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * But if objectids mismatch, it means we have a missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * INODE_ITEM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!check_prev_ino(leaf, key, slot, prev_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Make sure the item contains at least inline header, so the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * extent type is not some garbage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (item_size < BTRFS_FILE_EXTENT_INLINE_DATA_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) "invalid item size, have %u expect [%zu, %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) item_size, BTRFS_FILE_EXTENT_INLINE_DATA_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) SZ_4K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (btrfs_file_extent_type(leaf, fi) >= BTRFS_NR_FILE_EXTENT_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) "invalid type for file extent, have %u expect range [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) btrfs_file_extent_type(leaf, fi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) BTRFS_NR_FILE_EXTENT_TYPES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Support for new compression/encryption must introduce incompat flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * and must be caught in open_ctree().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (btrfs_file_extent_compression(leaf, fi) >= BTRFS_NR_COMPRESS_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) "invalid compression for file extent, have %u expect range [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) btrfs_file_extent_compression(leaf, fi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) BTRFS_NR_COMPRESS_TYPES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (btrfs_file_extent_encryption(leaf, fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) "invalid encryption for file extent, have %u expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) btrfs_file_extent_encryption(leaf, fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* Inline extent must have 0 as key offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (key->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) "invalid file_offset for inline file extent, have %llu expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Compressed inline extent has no on-disk size, skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (btrfs_file_extent_compression(leaf, fi) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) BTRFS_COMPRESS_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Uncompressed inline extent size must match item size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) btrfs_file_extent_ram_bytes(leaf, fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) "invalid ram_bytes for uncompressed inline extent, have %u expect %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) item_size, BTRFS_FILE_EXTENT_INLINE_DATA_START +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) btrfs_file_extent_ram_bytes(leaf, fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /* Regular or preallocated extent has fixed item size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (item_size != sizeof(*fi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) "invalid item size for reg/prealloc file extent, have %u expect %zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) item_size, sizeof(*fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (CHECK_FE_ALIGNED(leaf, slot, fi, ram_bytes, sectorsize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) CHECK_FE_ALIGNED(leaf, slot, fi, disk_bytenr, sectorsize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) CHECK_FE_ALIGNED(leaf, slot, fi, disk_num_bytes, sectorsize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) CHECK_FE_ALIGNED(leaf, slot, fi, offset, sectorsize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) CHECK_FE_ALIGNED(leaf, slot, fi, num_bytes, sectorsize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* Catch extent end overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (check_add_overflow(btrfs_file_extent_num_bytes(leaf, fi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) key->offset, &extent_end)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) file_extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) "extent end overflow, have file offset %llu extent num bytes %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) key->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) btrfs_file_extent_num_bytes(leaf, fi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Check that no two consecutive file extent items, in the same leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * present ranges that overlap each other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (slot > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) prev_key->objectid == key->objectid &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) prev_key->type == BTRFS_EXTENT_DATA_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct btrfs_file_extent_item *prev_fi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u64 prev_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) prev_fi = btrfs_item_ptr(leaf, slot - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct btrfs_file_extent_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) prev_end = file_extent_end(leaf, prev_key, prev_fi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (prev_end > key->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) file_extent_err(leaf, slot - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) "file extent end range (%llu) goes beyond start offset (%llu) of the next file extent",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) prev_end, key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int check_csum_item(struct extent_buffer *leaf, struct btrfs_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int slot, struct btrfs_key *prev_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 sectorsize = fs_info->sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u32 csumsize = btrfs_super_csum_size(fs_info->super_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) "invalid key objectid for csum item, have %llu expect %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) key->objectid, BTRFS_EXTENT_CSUM_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!IS_ALIGNED(key->offset, sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) "unaligned key offset for csum item, have %llu should be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) key->offset, sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) "unaligned item size for csum item, have %u should be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) btrfs_item_size_nr(leaf, slot), csumsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (slot > 0 && prev_key->type == BTRFS_EXTENT_CSUM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) u64 prev_csum_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u32 prev_item_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) prev_item_size = btrfs_item_size_nr(leaf, slot - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) prev_csum_end = (prev_item_size / csumsize) * sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) prev_csum_end += prev_key->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (prev_csum_end > key->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) generic_err(leaf, slot - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) "csum end range (%llu) goes beyond the start range (%llu) of the next csum item",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) prev_csum_end, key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Inode item error output has the same format as dir_item_err() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #define inode_item_err(eb, slot, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dir_item_err(eb, slot, fmt, __VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int check_inode_key(struct extent_buffer *leaf, struct btrfs_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct btrfs_key item_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) bool is_inode_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) btrfs_item_key_to_cpu(leaf, &item_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) is_inode_item = (item_key.type == BTRFS_INODE_ITEM_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* For XATTR_ITEM, location key should be all 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (item_key.type == BTRFS_XATTR_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (key->type != 0 || key->objectid != 0 || key->offset != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if ((key->objectid < BTRFS_FIRST_FREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) key->objectid > BTRFS_LAST_FREE_OBJECTID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) key->objectid != BTRFS_ROOT_TREE_DIR_OBJECTID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) key->objectid != BTRFS_FREE_INO_OBJECTID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (is_inode_item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) "invalid key objectid: has %llu expect %llu or [%llu, %llu] or %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) key->objectid, BTRFS_ROOT_TREE_DIR_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) BTRFS_FIRST_FREE_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) BTRFS_LAST_FREE_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) BTRFS_FREE_INO_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) "invalid location key objectid: has %llu expect %llu or [%llu, %llu] or %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) key->objectid, BTRFS_ROOT_TREE_DIR_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) BTRFS_FIRST_FREE_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) BTRFS_LAST_FREE_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) BTRFS_FREE_INO_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (key->offset != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (is_inode_item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) "invalid key offset: has %llu expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) "invalid location key offset:has %llu expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static int check_root_key(struct extent_buffer *leaf, struct btrfs_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct btrfs_key item_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) bool is_root_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) btrfs_item_key_to_cpu(leaf, &item_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) is_root_item = (item_key.type == BTRFS_ROOT_ITEM_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* No such tree id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (key->objectid == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (is_root_item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) generic_err(leaf, slot, "invalid root id 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) "invalid location key root id 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* DIR_ITEM/INDEX/INODE_REF is not allowed to point to non-fs trees */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!is_fstree(key->objectid) && !is_root_item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) "invalid location key objectid, have %llu expect [%llu, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) key->objectid, BTRFS_FIRST_FREE_OBJECTID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) BTRFS_LAST_FREE_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * ROOT_ITEM with non-zero offset means this is a snapshot, created at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * @offset transid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * Furthermore, for location key in DIR_ITEM, its offset is always -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * So here we only check offset for reloc tree whose key->offset must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * be a valid tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (key->objectid == BTRFS_TREE_RELOC_OBJECTID && key->offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) generic_err(leaf, slot, "invalid root id 0 for reloc tree");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static int check_dir_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct btrfs_key *key, struct btrfs_key *prev_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct btrfs_dir_item *di;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u32 cur = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (!check_prev_ino(leaf, key, slot, prev_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) while (cur < item_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct btrfs_key location_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u32 name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u32 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u32 max_name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) u32 total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 name_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) u8 dir_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* header itself should not cross item boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (cur + sizeof(*di) > item_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) "dir item header crosses item boundary, have %zu boundary %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) cur + sizeof(*di), item_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Location key check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) btrfs_dir_item_key_to_cpu(leaf, di, &location_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (location_key.type == BTRFS_ROOT_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = check_root_key(leaf, &location_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) } else if (location_key.type == BTRFS_INODE_ITEM_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) location_key.type == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = check_inode_key(leaf, &location_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) "invalid location key type, have %u, expect %u or %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) location_key.type, BTRFS_ROOT_ITEM_KEY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) BTRFS_INODE_ITEM_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* dir type check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dir_type = btrfs_dir_type(leaf, di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (dir_type >= BTRFS_FT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) "invalid dir item type, have %u expect [0, %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dir_type, BTRFS_FT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (key->type == BTRFS_XATTR_ITEM_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dir_type != BTRFS_FT_XATTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) "invalid dir item type for XATTR key, have %u expect %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dir_type, BTRFS_FT_XATTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (dir_type == BTRFS_FT_XATTR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) key->type != BTRFS_XATTR_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) "xattr dir type found for non-XATTR key");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (dir_type == BTRFS_FT_XATTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) max_name_len = XATTR_NAME_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) max_name_len = BTRFS_NAME_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Name/data length check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) name_len = btrfs_dir_name_len(leaf, di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) data_len = btrfs_dir_data_len(leaf, di);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (name_len > max_name_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) "dir item name len too long, have %u max %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) name_len, max_name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(fs_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) "dir item name and data len too long, have %u max %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) name_len + data_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) BTRFS_MAX_XATTR_SIZE(fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (data_len && dir_type != BTRFS_FT_XATTR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) "dir item with invalid data len, have %u expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) total_size = sizeof(*di) + name_len + data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* header and name/data should not cross item boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (cur + total_size > item_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) "dir item data crosses item boundary, have %u boundary %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cur + total_size, item_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * Special check for XATTR/DIR_ITEM, as key->offset is name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * hash, should match its name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (key->type == BTRFS_DIR_ITEM_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) key->type == BTRFS_XATTR_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) read_extent_buffer(leaf, namebuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) (unsigned long)(di + 1), name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) name_hash = btrfs_name_hash(namebuf, name_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (key->offset != name_hash) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) dir_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) "name hash mismatch with key, have 0x%016x expect 0x%016llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) name_hash, key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) cur += total_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) di = (struct btrfs_dir_item *)((void *)di + total_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static void block_group_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) const struct btrfs_fs_info *fs_info = eb->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) btrfs_item_key_to_cpu(eb, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "corrupt %s: root=%llu block=%llu slot=%d bg_start=%llu bg_len=%llu, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) key.objectid, key.offset, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int check_block_group_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct btrfs_block_group_item bgi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) u64 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) u64 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * Here we don't really care about alignment since extent allocator can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * handle it. We care more about the size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (key->offset == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) "invalid block group size 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) if (item_size != sizeof(bgi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) "invalid item size, have %u expect %zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) item_size, sizeof(bgi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) read_extent_buffer(leaf, &bgi, btrfs_item_ptr_offset(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sizeof(bgi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (btrfs_stack_block_group_chunk_objectid(&bgi) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) BTRFS_FIRST_CHUNK_TREE_OBJECTID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) "invalid block group chunk objectid, have %llu expect %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) btrfs_stack_block_group_chunk_objectid(&bgi),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) BTRFS_FIRST_CHUNK_TREE_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (btrfs_stack_block_group_used(&bgi) > key->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) "invalid block group used, have %llu expect [0, %llu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) btrfs_stack_block_group_used(&bgi), key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) flags = btrfs_stack_block_group_flags(&bgi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) "invalid profile flags, have 0x%llx (%lu bits set) expect no more than 1 bit set",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) flags & BTRFS_BLOCK_GROUP_PROFILE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) hweight64(flags & BTRFS_BLOCK_GROUP_PROFILE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) type = flags & BTRFS_BLOCK_GROUP_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (type != BTRFS_BLOCK_GROUP_DATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) type != BTRFS_BLOCK_GROUP_METADATA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) type != BTRFS_BLOCK_GROUP_SYSTEM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) type != (BTRFS_BLOCK_GROUP_METADATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) BTRFS_BLOCK_GROUP_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) block_group_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) "invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llx or 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) type, hweight64(type),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) BTRFS_BLOCK_GROUP_SYSTEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) __printf(4, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void chunk_err(const struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) const struct btrfs_chunk *chunk, u64 logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) const struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) bool is_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) int slot = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* Only superblock eb is able to have such small offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) is_sb = (leaf->start == BTRFS_SUPER_INFO_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (!is_sb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * Get the slot number by iterating through all slots, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * would provide better readability.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) for (i = 0; i < btrfs_header_nritems(leaf); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (btrfs_item_ptr_offset(leaf, i) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) (unsigned long)chunk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) slot = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (is_sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) "corrupt superblock syschunk array: chunk_start=%llu, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) logical, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) "corrupt leaf: root=%llu block=%llu slot=%d chunk_start=%llu, %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) BTRFS_CHUNK_TREE_OBJECTID, leaf->start, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) logical, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * The common chunk check which could also work on super block sys chunk array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Return -EUCLEAN if anything is corrupted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * Return 0 if everything is OK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int btrfs_check_chunk_valid(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct btrfs_chunk *chunk, u64 logical)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u64 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u64 chunk_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u64 stripe_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u16 num_stripes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u16 sub_stripes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) u64 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) u64 features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) bool mixed = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) int raid_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) int nparity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) int ncopies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) length = btrfs_chunk_length(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) type = btrfs_chunk_type(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) raid_index = btrfs_bg_flags_to_raid_index(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ncopies = btrfs_raid_array[raid_index].ncopies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) nparity = btrfs_raid_array[raid_index].nparity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (!num_stripes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) "invalid chunk num_stripes, have %u", num_stripes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (num_stripes < ncopies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) "invalid chunk num_stripes < ncopies, have %u < %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) num_stripes, ncopies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (nparity && num_stripes == nparity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) "invalid chunk num_stripes == nparity, have %u == %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) num_stripes, nparity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (!IS_ALIGNED(logical, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) "invalid chunk logical, have %llu should aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) logical, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (btrfs_chunk_sector_size(leaf, chunk) != fs_info->sectorsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) "invalid chunk sectorsize, have %u expect %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) btrfs_chunk_sector_size(leaf, chunk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!length || !IS_ALIGNED(length, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) "invalid chunk length, have %llu", length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (unlikely(check_add_overflow(logical, length, &chunk_end))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) "invalid chunk logical start and length, have logical start %llu length %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) logical, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (!is_power_of_2(stripe_len) || stripe_len != BTRFS_STRIPE_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) "invalid chunk stripe length: %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) stripe_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) "unrecognized chunk type: 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) BTRFS_BLOCK_GROUP_PROFILE_MASK) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) btrfs_chunk_type(leaf, chunk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (!has_single_bit_set(type & BTRFS_BLOCK_GROUP_PROFILE_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) (type & BTRFS_BLOCK_GROUP_PROFILE_MASK) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) "invalid chunk profile flag: 0x%llx, expect 0 or 1 bit set",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) "missing chunk type flag, have 0x%llx one bit must be set in 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) type, BTRFS_BLOCK_GROUP_TYPE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if ((type & BTRFS_BLOCK_GROUP_SYSTEM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) "system chunk with data or metadata type: 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) features = btrfs_super_incompat_flags(fs_info->super_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) mixed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!mixed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if ((type & BTRFS_BLOCK_GROUP_METADATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) (type & BTRFS_BLOCK_GROUP_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) "mixed chunk type in non-mixed mode: 0x%llx", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes != 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) (type & BTRFS_BLOCK_GROUP_DUP && num_stripes != 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 && num_stripes != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) chunk_err(leaf, chunk, logical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) "invalid num_stripes:sub_stripes %u:%u for profile %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) num_stripes, sub_stripes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * Enhanced version of chunk item checker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * The common btrfs_check_chunk_valid() doesn't check item size since it needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * to work on super block sys_chunk_array which doesn't have full item ptr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static int check_leaf_chunk_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct btrfs_chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int num_stripes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (btrfs_item_size_nr(leaf, slot) < sizeof(struct btrfs_chunk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) chunk_err(leaf, chunk, key->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) "invalid chunk item size: have %u expect [%zu, %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) btrfs_item_size_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) sizeof(struct btrfs_chunk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) BTRFS_LEAF_DATA_SIZE(leaf->fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Let btrfs_check_chunk_valid() handle this error type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (num_stripes == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (btrfs_chunk_item_size(num_stripes) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) btrfs_item_size_nr(leaf, slot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) chunk_err(leaf, chunk, key->offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) "invalid chunk item size: have %u expect %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) btrfs_item_size_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) btrfs_chunk_item_size(num_stripes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return btrfs_check_chunk_valid(leaf, chunk, key->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) __printf(3, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) static void dev_item_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) btrfs_item_key_to_cpu(eb, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) btrfs_crit(eb->fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) "corrupt %s: root=%llu block=%llu slot=%d devid=%llu %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) key.objectid, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int check_dev_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) struct btrfs_dev_item *ditem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) const u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (key->objectid != BTRFS_DEV_ITEMS_OBJECTID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) "invalid objectid: has=%llu expect=%llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) key->objectid, BTRFS_DEV_ITEMS_OBJECTID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (unlikely(item_size != sizeof(*ditem))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dev_item_err(leaf, slot, "invalid item size: has %u expect %zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) item_size, sizeof(*ditem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ditem = btrfs_item_ptr(leaf, slot, struct btrfs_dev_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (btrfs_device_id(leaf, ditem) != key->offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) dev_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) "devid mismatch: key has=%llu item has=%llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) key->offset, btrfs_device_id(leaf, ditem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * For device total_bytes, we don't have reliable way to check it, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * it can be 0 for device removal. Device size check can only be done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * by dev extents check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (btrfs_device_bytes_used(leaf, ditem) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) btrfs_device_total_bytes(leaf, ditem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) dev_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) "invalid bytes used: have %llu expect [0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) btrfs_device_bytes_used(leaf, ditem),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) btrfs_device_total_bytes(leaf, ditem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * Remaining members like io_align/type/gen/dev_group aren't really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * utilized. Skip them to make later usage of them easier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static int check_inode_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct btrfs_inode_item *iitem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) u64 super_gen = btrfs_super_generation(fs_info->super_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) u32 valid_mask = (S_IFMT | S_ISUID | S_ISGID | S_ISVTX | 0777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) const u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) u32 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ret = check_inode_key(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (unlikely(item_size != sizeof(*iitem))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) generic_err(leaf, slot, "invalid item size: has %u expect %zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) item_size, sizeof(*iitem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) iitem = btrfs_item_ptr(leaf, slot, struct btrfs_inode_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Here we use super block generation + 1 to handle log tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (btrfs_inode_generation(leaf, iitem) > super_gen + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) "invalid inode generation: has %llu expect (0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) btrfs_inode_generation(leaf, iitem),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) super_gen + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* Note for ROOT_TREE_DIR_ITEM, mkfs could set its transid 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (btrfs_inode_transid(leaf, iitem) > super_gen + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) "invalid inode transid: has %llu expect [0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) btrfs_inode_transid(leaf, iitem), super_gen + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * For size and nbytes it's better not to be too strict, as for dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * item its size/nbytes can easily get wrong, but doesn't affect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * anything in the fs. So here we skip the check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) mode = btrfs_inode_mode(leaf, iitem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (mode & ~valid_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) "unknown mode bit detected: 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) mode & ~valid_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * S_IFMT is not bit mapped so we can't completely rely on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * is_power_of_2/has_single_bit_set, but it can save us from checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * FIFO/CHR/DIR/REG. Only needs to check BLK, LNK and SOCKS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (!has_single_bit_set(mode & S_IFMT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (!S_ISLNK(mode) && !S_ISBLK(mode) && !S_ISSOCK(mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) "invalid mode: has 0%o expect valid S_IF* bit(s)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) mode & S_IFMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (S_ISDIR(mode) && btrfs_inode_nlink(leaf, iitem) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) "invalid nlink: has %u expect no more than 1 for dir",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) btrfs_inode_nlink(leaf, iitem));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (btrfs_inode_flags(leaf, iitem) & ~BTRFS_INODE_FLAG_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) inode_item_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) "unknown flags detected: 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) btrfs_inode_flags(leaf, iitem) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) ~BTRFS_INODE_FLAG_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static int check_root_item(struct extent_buffer *leaf, struct btrfs_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct btrfs_root_item ri = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) const u64 valid_root_flags = BTRFS_ROOT_SUBVOL_RDONLY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) BTRFS_ROOT_SUBVOL_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ret = check_root_key(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (btrfs_item_size_nr(leaf, slot) != sizeof(ri) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) btrfs_item_size_nr(leaf, slot) != btrfs_legacy_root_item_size()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) "invalid root item size, have %u expect %zu or %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) btrfs_item_size_nr(leaf, slot), sizeof(ri),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) btrfs_legacy_root_item_size());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * For legacy root item, the members starting at generation_v2 will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * all filled with 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * And since we allow geneartion_v2 as 0, it will still pass the check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) read_extent_buffer(leaf, &ri, btrfs_item_ptr_offset(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) btrfs_item_size_nr(leaf, slot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) /* Generation related */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (btrfs_root_generation(&ri) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) btrfs_super_generation(fs_info->super_copy) + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) "invalid root generation, have %llu expect (0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) btrfs_root_generation(&ri),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) btrfs_super_generation(fs_info->super_copy) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (btrfs_root_generation_v2(&ri) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) btrfs_super_generation(fs_info->super_copy) + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) "invalid root v2 generation, have %llu expect (0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) btrfs_root_generation_v2(&ri),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) btrfs_super_generation(fs_info->super_copy) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (btrfs_root_last_snapshot(&ri) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) btrfs_super_generation(fs_info->super_copy) + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) "invalid root last_snapshot, have %llu expect (0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) btrfs_root_last_snapshot(&ri),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) btrfs_super_generation(fs_info->super_copy) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /* Alignment and level check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (!IS_ALIGNED(btrfs_root_bytenr(&ri), fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) "invalid root bytenr, have %llu expect to be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) btrfs_root_bytenr(&ri), fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) if (btrfs_root_level(&ri) >= BTRFS_MAX_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) "invalid root level, have %u expect [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) btrfs_root_level(&ri), BTRFS_MAX_LEVEL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (ri.drop_level >= BTRFS_MAX_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) "invalid root level, have %u expect [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ri.drop_level, BTRFS_MAX_LEVEL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* Flags check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (btrfs_root_flags(&ri) & ~valid_root_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) "invalid root flags, have 0x%llx expect mask 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) btrfs_root_flags(&ri), valid_root_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) __printf(3,4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) __cold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static void extent_err(const struct extent_buffer *eb, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) struct va_format vaf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) u64 bytenr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) u64 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) btrfs_item_key_to_cpu(eb, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) bytenr = key.objectid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (key.type == BTRFS_METADATA_ITEM_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) key.type == BTRFS_TREE_BLOCK_REF_KEY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) key.type == BTRFS_SHARED_BLOCK_REF_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) len = eb->fs_info->nodesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) len = key.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) vaf.fmt = fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) vaf.va = &args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) btrfs_crit(eb->fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) "corrupt %s: block=%llu slot=%d extent bytenr=%llu len=%llu %pV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) btrfs_header_level(eb) == 0 ? "leaf" : "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) eb->start, slot, bytenr, len, &vaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static int check_extent_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct btrfs_extent_item *ei;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) bool is_tree_block = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) unsigned long ptr; /* Current pointer inside inline refs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) unsigned long end; /* Extent item end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) const u32 item_size = btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) u64 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) u64 generation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) u64 total_refs; /* Total refs in btrfs_extent_item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) u64 inline_refs = 0; /* found total inline refs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (key->type == BTRFS_METADATA_ITEM_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) !btrfs_fs_incompat(fs_info, SKINNY_METADATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) "invalid key type, METADATA_ITEM type invalid when SKINNY_METADATA feature disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /* key->objectid is the bytenr for both key types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (!IS_ALIGNED(key->objectid, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) "invalid key objectid, have %llu expect to be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) key->objectid, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* key->offset is tree level for METADATA_ITEM_KEY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (key->type == BTRFS_METADATA_ITEM_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) key->offset >= BTRFS_MAX_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) "invalid tree level, have %llu expect [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) key->offset, BTRFS_MAX_LEVEL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * EXTENT/METADATA_ITEM consists of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * 1) One btrfs_extent_item
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * Records the total refs, type and generation of the extent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * 2) One btrfs_tree_block_info (for EXTENT_ITEM and tree backref only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * Records the first key and level of the tree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * 2) Zero or more btrfs_extent_inline_ref(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * Each inline ref has one btrfs_extent_inline_ref shows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * 2.1) The ref type, one of the 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * TREE_BLOCK_REF Tree block only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * SHARED_BLOCK_REF Tree block only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) * EXTENT_DATA_REF Data only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * SHARED_DATA_REF Data only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * 2.2) Ref type specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * Either using btrfs_extent_inline_ref::offset, or specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (item_size < sizeof(*ei)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) "invalid item size, have %u expect [%zu, %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) item_size, sizeof(*ei),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) BTRFS_LEAF_DATA_SIZE(fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) end = item_size + btrfs_item_ptr_offset(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* Checks against extent_item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) flags = btrfs_extent_flags(leaf, ei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) total_refs = btrfs_extent_refs(leaf, ei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) generation = btrfs_extent_generation(leaf, ei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (generation > btrfs_super_generation(fs_info->super_copy) + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) "invalid generation, have %llu expect (0, %llu]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) generation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) btrfs_super_generation(fs_info->super_copy) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (!has_single_bit_set(flags & (BTRFS_EXTENT_FLAG_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) BTRFS_EXTENT_FLAG_TREE_BLOCK))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) "invalid extent flag, have 0x%llx expect 1 bit set in 0x%llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) flags, BTRFS_EXTENT_FLAG_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) BTRFS_EXTENT_FLAG_TREE_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) is_tree_block = !!(flags & BTRFS_EXTENT_FLAG_TREE_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (is_tree_block) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (key->type == BTRFS_EXTENT_ITEM_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) key->offset != fs_info->nodesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) "invalid extent length, have %llu expect %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) key->offset, fs_info->nodesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (key->type != BTRFS_EXTENT_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) "invalid key type, have %u expect %u for data backref",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) key->type, BTRFS_EXTENT_ITEM_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (!IS_ALIGNED(key->offset, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) "invalid extent length, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) key->offset, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ptr = (unsigned long)(struct btrfs_extent_item *)(ei + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /* Check the special case of btrfs_tree_block_info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (is_tree_block && key->type != BTRFS_METADATA_ITEM_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) struct btrfs_tree_block_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) info = (struct btrfs_tree_block_info *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (btrfs_tree_block_level(leaf, info) >= BTRFS_MAX_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) "invalid tree block info level, have %u expect [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) btrfs_tree_block_level(leaf, info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) BTRFS_MAX_LEVEL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ptr = (unsigned long)(struct btrfs_tree_block_info *)(info + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* Check inline refs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) while (ptr < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct btrfs_extent_inline_ref *iref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct btrfs_extent_data_ref *dref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct btrfs_shared_data_ref *sref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) u64 dref_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) u64 inline_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) u8 inline_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (ptr + sizeof(*iref) > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) "inline ref item overflows extent item, ptr %lu iref size %zu end %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) ptr, sizeof(*iref), end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) iref = (struct btrfs_extent_inline_ref *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) inline_type = btrfs_extent_inline_ref_type(leaf, iref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) inline_offset = btrfs_extent_inline_ref_offset(leaf, iref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (ptr + btrfs_extent_inline_ref_size(inline_type) > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) "inline ref item overflows extent item, ptr %lu iref size %u end %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) ptr, inline_type, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) switch (inline_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* inline_offset is subvolid of the owner, no need to check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) case BTRFS_TREE_BLOCK_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) inline_refs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* Contains parent bytenr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) case BTRFS_SHARED_BLOCK_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (!IS_ALIGNED(inline_offset, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) "invalid tree parent bytenr, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) inline_offset, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) inline_refs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * Contains owner subvolid, owner key objectid, adjusted offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) * The only obvious corruption can happen in that offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) case BTRFS_EXTENT_DATA_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) dref = (struct btrfs_extent_data_ref *)(&iref->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) dref_offset = btrfs_extent_data_ref_offset(leaf, dref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (!IS_ALIGNED(dref_offset, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) "invalid data ref offset, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dref_offset, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) inline_refs += btrfs_extent_data_ref_count(leaf, dref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* Contains parent bytenr and ref count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) case BTRFS_SHARED_DATA_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) sref = (struct btrfs_shared_data_ref *)(iref + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) if (!IS_ALIGNED(inline_offset, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) "invalid data parent bytenr, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) inline_offset, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) inline_refs += btrfs_shared_data_ref_count(leaf, sref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) extent_err(leaf, slot, "unknown inline ref type: %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) inline_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ptr += btrfs_extent_inline_ref_size(inline_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* No padding is allowed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (ptr != end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) "invalid extent item size, padding bytes found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* Finally, check the inline refs against total refs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (inline_refs > total_refs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) "invalid extent refs, have %llu expect >= inline %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) total_refs, inline_refs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) static int check_simple_keyed_refs(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) u32 expect_item_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (key->type == BTRFS_SHARED_DATA_REF_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) expect_item_size = sizeof(struct btrfs_shared_data_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (btrfs_item_size_nr(leaf, slot) != expect_item_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) "invalid item size, have %u expect %u for key type %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) btrfs_item_size_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) expect_item_size, key->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) "invalid key objectid for shared block ref, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) key->objectid, leaf->fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (key->type != BTRFS_TREE_BLOCK_REF_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) !IS_ALIGNED(key->offset, leaf->fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) "invalid tree parent bytenr, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) key->offset, leaf->fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) static int check_extent_data_ref(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct btrfs_key *key, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) struct btrfs_extent_data_ref *dref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) unsigned long ptr = btrfs_item_ptr_offset(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) const unsigned long end = ptr + btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (btrfs_item_size_nr(leaf, slot) % sizeof(*dref) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) "invalid item size, have %u expect aligned to %zu for key type %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) btrfs_item_size_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) sizeof(*dref), key->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) "invalid key objectid for shared block ref, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) key->objectid, leaf->fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) for (; ptr < end; ptr += sizeof(*dref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) u64 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * We cannot check the extent_data_ref hash due to possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * overflow from the leaf due to hash collisions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) dref = (struct btrfs_extent_data_ref *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) offset = btrfs_extent_data_ref_offset(leaf, dref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (!IS_ALIGNED(offset, leaf->fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) extent_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) "invalid extent data backref offset, have %llu expect aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) offset, leaf->fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) #define inode_ref_err(eb, slot, fmt, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) inode_item_err(eb, slot, fmt, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static int check_inode_ref(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct btrfs_key *key, struct btrfs_key *prev_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) struct btrfs_inode_ref *iref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) unsigned long ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) unsigned long end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (!check_prev_ino(leaf, key, slot, prev_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) /* namelen can't be 0, so item_size == sizeof() is also invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (btrfs_item_size_nr(leaf, slot) <= sizeof(*iref)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) inode_ref_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) "invalid item size, have %u expect (%zu, %u)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) btrfs_item_size_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) sizeof(*iref), BTRFS_LEAF_DATA_SIZE(leaf->fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) ptr = btrfs_item_ptr_offset(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) end = ptr + btrfs_item_size_nr(leaf, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) while (ptr < end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) u16 namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (ptr + sizeof(iref) > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) inode_ref_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) "inode ref overflow, ptr %lu end %lu inode_ref_size %zu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) ptr, end, sizeof(iref));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) iref = (struct btrfs_inode_ref *)ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) namelen = btrfs_inode_ref_name_len(leaf, iref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (ptr + sizeof(*iref) + namelen > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) inode_ref_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) "inode ref overflow, ptr %lu end %lu namelen %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) ptr, end, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * NOTE: In theory we should record all found index numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * to find any duplicated indexes, but that will be too time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * consuming for inodes with too many hard links.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) ptr += sizeof(*iref) + namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) * Common point to switch the item-specific validation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) static int check_leaf_item(struct extent_buffer *leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct btrfs_key *key, int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) struct btrfs_key *prev_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct btrfs_chunk *chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) switch (key->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) case BTRFS_EXTENT_DATA_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ret = check_extent_data_item(leaf, key, slot, prev_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) case BTRFS_EXTENT_CSUM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) ret = check_csum_item(leaf, key, slot, prev_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) case BTRFS_DIR_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) case BTRFS_DIR_INDEX_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) case BTRFS_XATTR_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) ret = check_dir_item(leaf, key, prev_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) case BTRFS_INODE_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ret = check_inode_ref(leaf, key, prev_key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) case BTRFS_BLOCK_GROUP_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ret = check_block_group_item(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) case BTRFS_CHUNK_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) ret = check_leaf_chunk_item(leaf, chunk, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) case BTRFS_DEV_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) ret = check_dev_item(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) case BTRFS_INODE_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) ret = check_inode_item(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) case BTRFS_ROOT_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) ret = check_root_item(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) case BTRFS_EXTENT_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) case BTRFS_METADATA_ITEM_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) ret = check_extent_item(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case BTRFS_TREE_BLOCK_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) case BTRFS_SHARED_DATA_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) case BTRFS_SHARED_BLOCK_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) ret = check_simple_keyed_refs(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) case BTRFS_EXTENT_DATA_REF_KEY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ret = check_extent_data_ref(leaf, key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) static int check_leaf(struct extent_buffer *leaf, bool check_item_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct btrfs_fs_info *fs_info = leaf->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) /* No valid key type is 0, so all key should be larger than this key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) struct btrfs_key prev_key = {0, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct btrfs_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) u32 nritems = btrfs_header_nritems(leaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (btrfs_header_level(leaf) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) generic_err(leaf, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) "invalid level for leaf, have %d expect 0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) btrfs_header_level(leaf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * Extent buffers from a relocation tree have a owner field that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * corresponds to the subvolume tree they are based on. So just from an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) * extent buffer alone we can not find out what is the id of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) * corresponding subvolume tree, so we can not figure out if the extent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) * buffer corresponds to the root of the relocation tree or not. So
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) * skip this check for relocation trees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) u64 owner = btrfs_header_owner(leaf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) /* These trees must never be empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (owner == BTRFS_ROOT_TREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) owner == BTRFS_CHUNK_TREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) owner == BTRFS_EXTENT_TREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) owner == BTRFS_DEV_TREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) owner == BTRFS_FS_TREE_OBJECTID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) owner == BTRFS_DATA_RELOC_TREE_OBJECTID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) generic_err(leaf, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) "invalid root, root %llu must never be empty",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /* Unknown tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (owner == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) generic_err(leaf, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) "invalid owner, root 0 is not defined");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) if (nritems == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * Check the following things to make sure this is a good leaf, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) * leaf users won't need to bother with similar sanity checks:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * 1) key ordering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) * 2) item offset and size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * No overlap, no hole, all inside the leaf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) * 3) item content
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * If possible, do comprehensive sanity check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) * NOTE: All checks must only rely on the item data itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) for (slot = 0; slot < nritems; slot++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) u32 item_end_expected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) btrfs_item_key_to_cpu(leaf, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) /* Make sure the keys are in the right order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) "bad key order, prev (%llu %u %llu) current (%llu %u %llu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) prev_key.objectid, prev_key.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) prev_key.offset, key.objectid, key.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) key.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) * Make sure the offset and ends are right, remember that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * item data starts at the end of the leaf and grows towards the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * front.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (slot == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) item_end_expected = BTRFS_LEAF_DATA_SIZE(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) item_end_expected = btrfs_item_offset_nr(leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) slot - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (btrfs_item_end_nr(leaf, slot) != item_end_expected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) "unexpected item end, have %u expect %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) btrfs_item_end_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) item_end_expected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) * Check to make sure that we don't point outside of the leaf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) * just in case all the items are consistent to each other, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) * all point outside of the leaf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (btrfs_item_end_nr(leaf, slot) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) BTRFS_LEAF_DATA_SIZE(fs_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) "slot end outside of leaf, have %u expect range [0, %u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) btrfs_item_end_nr(leaf, slot),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) BTRFS_LEAF_DATA_SIZE(fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) /* Also check if the item pointer overlaps with btrfs item. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) btrfs_item_ptr_offset(leaf, slot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) generic_err(leaf, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) "slot overlaps with its data, item end %lu data start %lu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) btrfs_item_nr_offset(slot) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) sizeof(struct btrfs_item),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) btrfs_item_ptr_offset(leaf, slot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (check_item_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * Check if the item size and content meet other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * criteria
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ret = check_leaf_item(leaf, &key, slot, &prev_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) prev_key.objectid = key.objectid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) prev_key.type = key.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) prev_key.offset = key.offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) int btrfs_check_leaf_full(struct extent_buffer *leaf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) return check_leaf(leaf, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) ALLOW_ERROR_INJECTION(btrfs_check_leaf_full, ERRNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) int btrfs_check_leaf_relaxed(struct extent_buffer *leaf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return check_leaf(leaf, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) int btrfs_check_node(struct extent_buffer *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) struct btrfs_fs_info *fs_info = node->fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) unsigned long nr = btrfs_header_nritems(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct btrfs_key key, next_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) int slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int level = btrfs_header_level(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) u64 bytenr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (level <= 0 || level >= BTRFS_MAX_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) generic_err(node, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) "invalid level for node, have %d expect [1, %d]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) level, BTRFS_MAX_LEVEL - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) btrfs_crit(fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) "corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) btrfs_header_owner(node), node->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) nr == 0 ? "small" : "large", nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) BTRFS_NODEPTRS_PER_BLOCK(fs_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) return -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) for (slot = 0; slot < nr - 1; slot++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) bytenr = btrfs_node_blockptr(node, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) btrfs_node_key_to_cpu(node, &key, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) btrfs_node_key_to_cpu(node, &next_key, slot + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (!bytenr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) generic_err(node, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) "invalid NULL node pointer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) ret = -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (!IS_ALIGNED(bytenr, fs_info->sectorsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) generic_err(node, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) "unaligned pointer, have %llu should be aligned to %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) bytenr, fs_info->sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) ret = -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) generic_err(node, slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) "bad key order, current (%llu %u %llu) next (%llu %u %llu)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) key.objectid, key.type, key.offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) next_key.objectid, next_key.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) next_key.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) ret = -EUCLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) ALLOW_ERROR_INJECTION(btrfs_check_node, ERRNO);