Skip to content

Commit 4f3fb9e

Browse files
committed
btrfs-progs: enhance detection on unknown inode keys
There is a bug report that a bitflip corrupted one tree block, causing a corruption that can not be repaired by btrfs-check. The corruption looks like this: item 10 key (730455 INODE_ITEM 0) itemoff 15456 itemsize 160 generation 7280 transid 9794 size 13829 nbytes 16384 block group 0 mode 100600 links 1 uid 1000 gid 1000 rdev 0 sequence 11 flags 0x0(none) atime 1765397443.29231914 (2025-12-11 06:40:43) ctime 1764798591.882909548 (2025-12-04 08:19:51) mtime 1764798591.882909548 (2025-12-04 08:19:51) otime 1764712848.413821734 (2025-12-03 08:30:48) item 11 key (730455 UNKNOWN.8 1924) itemoff 15406 itemsize 50 Note item 11, it has a unknown key, but the itemsize indicates it's an INODE_REF with 40 name_len (which matches the DIR_ITEM). bin(BTRFS_INODE_REF_KEY) = 0b1100 bin(8) = 0b1000 So it's indeed a bitflip. At least we should report such unknown inode key types as errors. The lowmem mode is already doing such report, although not treating them as an error. The original mode just ignores them completely. So this patch enhance btrfs check to: - Report such unknown item and treat them as error for the original mode - Treat such unknown item as error for the lowmem mode Reported-by: mikkel+btrfs@mikkel.cc Link: https://lore.kernel.org/linux-btrfs/5d5e344e-96be-4436-9a58-d60ba14fdb4f@gmx.com/T/#me22cef92653e660e88a4c005b10f5201a8fd83ac Signed-off-by: Qu Wenruo <wqu@suse.com>
1 parent 79c154a commit 4f3fb9e

File tree

3 files changed

+11
-2
lines changed

3 files changed

+11
-2
lines changed

check/main.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ bool is_free_space_tree = false;
8787
bool init_extent_tree = false;
8888
bool check_data_csum = false;
8989
static bool found_free_ino_cache = false;
90+
static bool found_unknown_key = false;
9091
struct cache_tree *roots_info_cache = NULL;
9192

9293
enum btrfs_check_mode {
@@ -1895,6 +1896,10 @@ static int process_one_leaf(struct btrfs_root *root, struct extent_buffer *eb,
18951896
ret = process_xattr_item(eb, i, &key, active_node);
18961897
break;
18971898
default:
1899+
error("Unknown key (%llu %u %llu) found in leaf %llu",
1900+
key.objectid, key.type, key.offset,
1901+
eb->start);
1902+
found_unknown_key = true;
18981903
break;
18991904
};
19001905
}
@@ -4027,6 +4032,8 @@ static int check_fs_roots(struct cache_tree *root_cache)
40274032
free_extent_cache_tree(&wc.shared);
40284033
if (!cache_tree_empty(&wc.shared))
40294034
fprintf(stderr, "warning line %d\n", __LINE__);
4035+
if (!err && found_unknown_key)
4036+
err = 1;
40304037

40314038
return err;
40324039
}

check/mode-lowmem.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2808,8 +2808,9 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path)
28082808
case BTRFS_XATTR_ITEM_KEY:
28092809
break;
28102810
default:
2811-
error("ITEM[%llu %u %llu] UNKNOWN TYPE",
2812-
key.objectid, key.type, key.offset);
2811+
error("ITEM[%llu %u %llu] UNKNOWN TYPE in leaf %llu",
2812+
key.objectid, key.type, key.offset, node->start);
2813+
err |= UNKNOWN_KEY;
28132814
}
28142815
}
28152816

check/mode-lowmem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#define INVALID_GENERATION (1U << 26) /* Generation is too new */
4949
#define SUPER_BYTES_USED_ERROR (1U << 27) /* Super bytes_used is invalid */
5050
#define DUP_FILENAME_ERROR (1U << 28) /* DIR_ITEM contains duplicate names */
51+
#define UNKNOWN_KEY (1U << 29) /* Found unknown key type in fs trees */
5152

5253
/*
5354
* Error bit for low memory mode check.

0 commit comments

Comments
 (0)