Message ID | f8cf038608f5da4a94d95f435cc24065afb2c21f.1723419296.git.wqu@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: tree-checker: reject BTRFS_FT_UNKNOWN dir type | expand |
On Mon, Aug 12, 2024 at 09:05:34AM +0930, Qu Wenruo wrote: > [REPORT] > There is a bug report that kernel is rejecting a mismatching inode mode > and its dir item: > > [ 1881.553937] BTRFS critical (device dm-0): inode mode mismatch with > dir: inode mode=040700 btrfs type=2 dir type=0 > > [CAUSE] > It looks like the inode mode is correct, while the dir item type > 0 is BTRFS_FT_UNKNOWN, which should not be generated by btrfs at all. > > This may be caused by a memory bit flip. I haven't read the report but according to your analysis it most certainly is a bitflip, there's no logic that would accidentally use the 0 value and not lead some error. > [ENHACENMENT] > Although tree-checker is not able to do any cross-leaf verification, for > this particular case we can at least reject any dir type with > BTRFS_FT_UNKNOWN. > > So here we enhance the dir type check from [0, BTRFS_FT_MAX), to (0, > BTRFS_FT_MAX). > Although the existing corruption can not be fixed just by such enhanced > checking, it should prevent the same 0x2->0x0 bitflip for dir type to > reach disk in the future. > > Reported-by: Kota <nospam@kota.moe> > Link: https://lore.kernel.org/linux-btrfs/CACsxjPYnQF9ZF-0OhH16dAx50=BXXOcP74MxBc3BG+xae4vTTw@mail.gmail.com/ > Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com>
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 3e8fbedfe04d..634d69964fe4 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -569,9 +569,10 @@ static int check_dir_item(struct extent_buffer *leaf, /* dir type check */ dir_type = btrfs_dir_ftype(leaf, di); - if (unlikely(dir_type >= BTRFS_FT_MAX)) { + if (unlikely(dir_type <= BTRFS_FT_UNKNOWN || + dir_type >= BTRFS_FT_MAX)) { dir_item_err(leaf, slot, - "invalid dir item type, have %u expect [0, %u)", + "invalid dir item type, have %u expect (0, %u)", dir_type, BTRFS_FT_MAX); return -EUCLEAN; }
[REPORT] There is a bug report that kernel is rejecting a mismatching inode mode and its dir item: [ 1881.553937] BTRFS critical (device dm-0): inode mode mismatch with dir: inode mode=040700 btrfs type=2 dir type=0 [CAUSE] It looks like the inode mode is correct, while the dir item type 0 is BTRFS_FT_UNKNOWN, which should not be generated by btrfs at all. This may be caused by a memory bit flip. [ENHACENMENT] Although tree-checker is not able to do any cross-leaf verification, for this particular case we can at least reject any dir type with BTRFS_FT_UNKNOWN. So here we enhance the dir type check from [0, BTRFS_FT_MAX), to (0, BTRFS_FT_MAX). Although the existing corruption can not be fixed just by such enhanced checking, it should prevent the same 0x2->0x0 bitflip for dir type to reach disk in the future. Reported-by: Kota <nospam@kota.moe> Link: https://lore.kernel.org/linux-btrfs/CACsxjPYnQF9ZF-0OhH16dAx50=BXXOcP74MxBc3BG+xae4vTTw@mail.gmail.com/ Signed-off-by: Qu Wenruo <wqu@suse.com> --- fs/btrfs/tree-checker.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)