Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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);