diff mbox

btrfs GPF in read_extent_buffer() while scrubbing with kernel 3.4.2

Message ID 4FF5998D.8020205@jan-o-sch.net (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Schmidt July 5, 2012, 1:41 p.m. UTC
On 04.07.2012 22:24, Sami Liedes wrote:
> On Wed, Jul 04, 2012 at 06:38:00PM +0200, Jan Schmidt wrote:
>>> [  200.980496] btrfs: invalid parameters for read_extent_buffer: start (32771) > eb->len (32768). eb start is 2243489562624, level 26, generation 3144240307695375391, nritems 620178657. len param 17. debug 2/989/620178657/3144240307695375391
> 
> Let's call this try 1. I ran it three more times, so below we have
> tries 2, 3 and 4.
> 
>> Wow, that's strange. Can you repeat your test once or twice and paste that line,
>> please? I'd like to get a feeling if the values are completely random.
> 
> Curiously, it clearly takes longer for it to crash after starting the
> scrub each time I run it. Also on try 4 I got an entirely different
> crash (backtrace below). Now it scrubs maybe the first 200G or so of
> both devices of the (raid-1) 2.2T filesystem before it crashes.

Can you double check that there's nothing about corrected errors in your
logs? Scrub will correct errors along the way and log that. So maybe
we've only a few tries left to find the root cause.

> start and eb->len seem to be the same (32771 and 32768) every time.

That's the tree block size in your setup.

> eb start varies, but there's some pattern if you view them in hex:
> 
>   Try 1  20a5a660000
>   Try 2  20bb0018000
>   Try 3  20a8bc28000
>   Try 4  (no output, different crash)

I fail to identify a real pattern there.

> The rest of the values seem to me to be completely different every time.

Which is itself interesting.

> Try 4:

That one is not that much different. We read some garbage from a tree
block and started the next read ahead cycle for the alledged children.
That way we came to a logical address that's out of bounds, instead of a
logical address with even more garbage.

I'd like to see if you corrupted your trees on disk in a really strange
manner (with matching checksums?), or if data comes from the disk intact
and becomes damaged thereafter.

Could you store the output of
	btrfs-debug-tree /dev/[whatever]
before try number 5 and afterwards? It will be quite a lot if you've got
a lot of files in there. Don't send it anywhere right now, just store it
away if possible.

What I'd like to get in the next reply is the output of the attached
patch, a single pass should do this time.

NB: As we've already check_leaf doing exta leaf checks after reading
them, we should probably add something like check_node as a general
manner to make btrfs more robust.

Thank you,
-Jan

---
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Sami Liedes July 5, 2012, 11:47 p.m. UTC | #1
On Thu, Jul 05, 2012 at 03:41:33PM +0200, Jan Schmidt wrote:
> I'd like to see if you corrupted your trees on disk in a really strange
> manner (with matching checksums?), or if data comes from the disk intact
> and becomes damaged thereafter.
> 
> Could you store the output of
> 	btrfs-debug-tree /dev/[whatever]
> before try number 5 and afterwards? It will be quite a lot if you've got
> a lot of files in there. Don't send it anywhere right now, just store it
> away if possible.

Ok, I have it stored. I mounted the fs read-only to do that just to be
safe, because when I did it on a live fs I got some (~15) "parent
transid verify failed" messages.

> Can you double check that there's nothing about corrected errors in your
> logs? Scrub will correct errors along the way and log that. So maybe
> we've only a few tries left to find the root cause.

Nope, definitely nothing there. A few "unlinked orphans" messages at
mount time, but that's all. I'm sure I would have captured any further
messages on my netconsole. Also nothing in any earlier logs that I can
see.

Well, until now (try 6) anyway. I actually ran btrfs scrub / twice now
after running btrfs-debug-tree (tries 5 and 6), because on the first
try I ran on wrong kernel (without the debug patch). On try 5 it
crashed very quickly, probably in less than a second. I also noticed
that it doesn't actually crash the machine or even make the filesystem
unusable in any way (apart from unmount blocking at shutdown), so I
also have the same oopses in my log files stored on the same
filesystem. But no, nothing about corrected errors or checksum
failures. So:

Try 5 (without your new patch, but after running btrfs-debug-tree); no
checksum failures as before, similar crash to before:

------------------------------------------------------------
[ 2036.512656] btrfs: invalid parameters for read_extent_buffer: start (32771) > eb->len (32768). eb start is 2239379931136, level 102, generation 309534250463128, nritems 56187918. len param 17. debug 2/989/56187918/309534250463128
[ 2036.512770] ------------[ cut here ]------------
[ 2036.512834] WARNING: at fs/btrfs/extent_io.c:4528 read_extent_buffer+0x167/0x1a0 [btrfs]()
[ 2036.512880] Hardware name: System Product Name
[ 2036.512906] Modules linked in: <omitted>  [last unloaded: netconsole]
[ 2036.512954] Pid: 1135, comm: btrfs-endio-met Tainted: G        W    3.4.4-modded-oops+ #2
[...]
------------------------------------------------------------

Try 6, with your new patch - as a new thing, got checksum errors,
including one very slightly before the crash and with the same "eb
start" as in the "invalid parameters" message. Crashed in a couple of
minutes.

Now that I look at the the log below it actually has two crashes in
it, one of btrfs-endio-met pid 1212 and another one of btrfs-endio-met
pid some 72 seconds later. I didn't notice that until after the fact.

dm-6 (the device with checksum failures) is on a disk on which I don't
have anything else besides this partition, so I suppose it could be
corrupting data without me having noticed. I know it used to work at
one time, but that doesn't mean too much. Anyway, I'm sure I haven't
seen any "checksum verify failed" messages until now. None in the logs
either.

Ah, one thing I have forgotten to mention. I think I've been using
this filesystem for maybe a month now. It started as a single-device
filesystem, but I did restriping to raid-1 on June 12. dm-5 is the
original device, while dm-6 (the one with the checksum failures in try
6) is the added one. I still have logs of the restriping and
everything after that; grep reveals no unusual lines containing
"btrfs" in all the logs since then, apart from the crashes. Besides
the oopses and lines that mention btrfs just because of the kernel
version 3.4.4+btrfsdebug, this is a summary of all the lines that
mention btrfs:

  btrfs: disk space caching is enabled
  btrfs flagging fs with big metadata feature
  btrfs: new size for /dev/mapper/rootvg-scratch_crypt is 751617179648
     * this device is not on the filesystem with problems - although I
       haven't tried scrubbing this filesystem
  btrfs: unlinked 104 orphans (10 times with 4 different numbers)

And during restriping

  btrfs: found 10008 extents (and similar)
  btrfs: relocating block group 1019010351104 flags 1 (and similar)

And two different warnings in the last few days, but I think this is
only because the debug patches changed the code:

  WARNING: at fs/btrfs/extent_io.c:4522 read_extent_buffer+0xe6/0x110 [btrfs]()
  WARNING: at fs/btrfs/extent_io.c:4528 read_extent_buffer+0x167/0x1a0 [btrfs]()

Another thing that comes to mind that I might well be the only one
that uses btrfs with raid-1 on two separate dm-crypted devices
(contrary to the way suggested on Btrfs FAQ - in my experience that
can actually speed up things, especially on computers without hardware
crypto, because the kernel has only one kcryptd thread per dm-crypt
device and therefore only can use a single core per device. Plus I get
the benefits of btrfs "smart raid".).

So, try 6. The three first lines are from me starting btrfs-debug-tree
again just as a quick way to verify that my netconsole setup was
working. The first checksum failure came pretty much instantly after
starting scrub:

------------------------------------------------------------
[  168.207151] device fsid f26f08b1-89e6-4f2d-b7f9-857010dd2517 devid 1 transid 151087 /dev/dm-5
[  168.208541] device fsid f26f08b1-89e6-4f2d-b7f9-857010dd2517 devid 2 transid 151087 /dev/dm-6
[  168.284668] device fsid ad75beab-b52b-4f63-9d14-956cc8e95fc7 devid 1 transid 5001 /dev/dm-9
[  188.507789] btrfs: dm-6 checksum verify failed on 2237998628864 wanted C3D64F found DCBF0869 level 88
[  188.507852] btrfs: node seems invalid now. checksum ok = 1
[  262.706585] btrfs: dm-6 checksum verify failed on 2246859587584 wanted 3D013CF8 found AD06874A level 77
[  262.706650] btrfs: node seems invalid now. checksum ok = 1
[  262.706822] btrfs: invalid parameters for read_extent_buffer: start (32771) > eb->len (32768). eb start is 2246859587584, level 77, generation 93067543380099401, nritems 21766576. len param 17. debug 2/989/21766576/93067543380099401
[  262.706929] ------------[ cut here ]------------
[  262.706992] WARNING: at fs/btrfs/extent_io.c:4529 read_extent_buffer+0x167/0x1a0 [btrfs]()
[  262.707051] Hardware name: System Product Name
[  262.707078] Modules linked in: <omitted> [last unloaded: netconsole]
[  262.707126] Pid: 1212, comm: btrfs-endio-met Tainted: G        W    3.4.4+btrfsdebug #1
[  262.707169] Call Trace:
[  262.707193]  [<ffffffff8103905a>] warn_slowpath_common+0x7a/0xb0
[  262.707229]  [<ffffffff810390a5>] warn_slowpath_null+0x15/0x20
[  262.707282]  [<ffffffffa01d8fc7>] read_extent_buffer+0x167/0x1a0 [btrfs]
[  262.707339]  [<ffffffffa01d01fd>] btrfs_node_key+0x1d/0x20 [btrfs]
[  262.707391]  [<ffffffffa02067af>] __readahead_hook+0x44f/0x500 [btrfs]
[  262.707444]  [<ffffffffa0206b78>] btree_readahead_hook+0x18/0x40 [btrfs]
[  262.707497]  [<ffffffffa01ac9d1>] btree_readpage_end_io_hook+0x111/0x270 [btrfs]
[  262.707556]  [<ffffffffa01d4602>] ? find_first_extent_bit_state+0x22/0x80 [btrfs]
[  262.707613]  [<ffffffffa01d524b>] end_bio_extent_readpage+0xcb/0xa30 [btrfs]
[  262.707668]  [<ffffffffa01abe61>] ? end_workqueue_fn+0x31/0x50 [btrfs]
[  262.707708]  [<ffffffff81158988>] bio_endio+0x18/0x30
[  262.707753]  [<ffffffffa01abe6c>] end_workqueue_fn+0x3c/0x50 [btrfs]
[  262.707805]  [<ffffffffa01e2a97>] worker_loop+0x157/0x560 [btrfs]
[  262.707856]  [<ffffffffa01e2940>] ? btrfs_queue_worker+0x310/0x310 [btrfs]
[  262.707898]  [<ffffffff81058e5e>] kthread+0x8e/0xa0
[  262.707930]  [<ffffffff81419064>] kernel_thread_helper+0x4/0x10
[  262.707966]  [<ffffffff81058dd0>] ? flush_kthread_worker+0x70/0x70
[  262.708003]  [<ffffffff81419060>] ? gs_change+0x13/0x13
[  262.708034] ---[ end trace e93713a9d40cd06e ]---
[  262.708072] general protection fault: 0000 [#1] SMP 
[  262.708112] CPU 1 
[  262.708126] Modules linked in: <omitted> [last unloaded: netconsole]
[  262.708176] 
[  262.708190] Pid: 1212, comm: btrfs-endio-met Tainted: G        W    3.4.4+btrfsdebug #1 System manufacturer System Product Name/P8P67 EVO
[  262.708268] RIP: 0010:[<ffffffff811e83ed>]  [<ffffffff811e83ed>] memcpy+0xd/0x110
[  262.708316] RSP: 0018:ffff8801fe19bb68  EFLAGS: 00010202
[  262.708347] RAX: ffff8801fe19bc8f RBX: 0000000000000011 RCX: 0000000000000002
[  262.708387] RDX: 0000000000000001 RSI: 0005080000000003 RDI: ffff8801fe19bc8f
[  262.708426] RBP: ffff8801fe19bbe0 R08: 0000000000000000 R09: 0000000000000000
[  262.708466] R10: ffff8801fe19bc8f R11: ffff8801f3184780 R12: ffff8801fe19bca0
[  262.708505] R13: ffff88020fc0ca48 R14: 0000000000000048 R15: 0000000000000011
[  262.708545] FS:  0000000000000000(0000) GS:ffff88021ec40000(0000) knlGS:0000000000000000
[  262.708590] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  262.708622] CR2: ffffffffff600400 CR3: 000000000180c000 CR4: 00000000000407e0
[  262.708661] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  262.708701] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  262.708741] Process btrfs-endio-met (pid: 1212, threadinfo ffff8801fe19a000, task ffff88020e07c2f0)
[  262.708790] Stack:
[  262.708804]  ffffffffa01d8f1b ffff8802014c21b0 0000000000000011 0000000000000002
[  262.708864]  00000000000003dd 00000000014c21b0 014aa470074a0149 ffff88020f95e000
[  262.708925]  ffff8801fe19bc8f 0000000000001000 ffff8801fe19bc58 00000000000003dd
[  262.708984] Call Trace:
[  262.709021]  [<ffffffffa01d8f1b>] ? read_extent_buffer+0xbb/0x1a0 [btrfs]
[  262.709077]  [<ffffffffa01d01fd>] btrfs_node_key+0x1d/0x20 [btrfs]
[  262.709128]  [<ffffffffa02067af>] __readahead_hook+0x44f/0x500 [btrfs]
[  262.709179]  [<ffffffffa0206b78>] btree_readahead_hook+0x18/0x40 [btrfs]
[  262.709233]  [<ffffffffa01ac9d1>] btree_readpage_end_io_hook+0x111/0x270 [btrfs]
[  262.709291]  [<ffffffffa01d4602>] ? find_first_extent_bit_state+0x22/0x80 [btrfs]
[  262.709349]  [<ffffffffa01d524b>] end_bio_extent_readpage+0xcb/0xa30 [btrfs]
[  262.709404]  [<ffffffffa01abe61>] ? end_workqueue_fn+0x31/0x50 [btrfs]
[  262.709443]  [<ffffffff81158988>] bio_endio+0x18/0x30
[  262.709487]  [<ffffffffa01abe6c>] end_workqueue_fn+0x3c/0x50 [btrfs]
[  262.709539]  [<ffffffffa01e2a97>] worker_loop+0x157/0x560 [btrfs]
[  262.709590]  [<ffffffffa01e2940>] ? btrfs_queue_worker+0x310/0x310 [btrfs]
[  262.709631]  [<ffffffff81058e5e>] kthread+0x8e/0xa0
[  262.709662]  [<ffffffff81419064>] kernel_thread_helper+0x4/0x10
[  262.709698]  [<ffffffff81058dd0>] ? flush_kthread_worker+0x70/0x70
[  262.709735]  [<ffffffff81419060>] ? gs_change+0x13/0x13
[  262.709765] Code: 4e 48 83 c4 08 5b 5d c3 66 0f 1f 44 00 00 e8 eb fb ff ff eb e1 90 90 90 90 90 90 90 90 90 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 <f3> 48 a5 89 d1 f3 a4 c3 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 
[  262.710178] RIP  [<ffffffff811e83ed>] memcpy+0xd/0x110
[  262.712431]  RSP <ffff8801fe19bb68>
[  262.714672] ---[ end trace e93713a9d40cd06f ]---
[  334.817046] btrfs: dm-6 checksum verify failed on 2239529385984 wanted 206D6165 found C4529DEC level 10
[  334.818677] btrfs: node seems invalid now. checksum ok = 1
[  334.820432] btrfs: invalid parameters for read_extent_buffer: start (32771) > eb->len (32768). eb start is 2239529385984, level 10, generation 7310033184097661728, nritems 996502889. len param 17. debug 2/989/996502889/7310033184097661728
[  334.823857] ------------[ cut here ]------------
[  334.825602] WARNING: at fs/btrfs/extent_io.c:4529 read_extent_buffer+0x167/0x1a0 [btrfs]()
[  334.827336] Hardware name: System Product Name
[  334.829049] Modules linked in: <omitted> [last unloaded: netconsole]
[  334.830814] Pid: 1132, comm: btrfs-endio-met Tainted: G      D W    3.4.4+btrfsdebug #1
[  334.832571] Call Trace:
[  334.834323]  [<ffffffff8103905a>] warn_slowpath_common+0x7a/0xb0
[  334.836095]  [<ffffffff810390a5>] warn_slowpath_null+0x15/0x20
[  334.837883]  [<ffffffffa01d8fc7>] read_extent_buffer+0x167/0x1a0 [btrfs]
[  334.839658]  [<ffffffffa01d01fd>] btrfs_node_key+0x1d/0x20 [btrfs]
[  334.841427]  [<ffffffffa02067af>] __readahead_hook+0x44f/0x500 [btrfs]
[  334.843209]  [<ffffffffa0206b78>] btree_readahead_hook+0x18/0x40 [btrfs]
[  334.844996]  [<ffffffffa01ac9d1>] btree_readpage_end_io_hook+0x111/0x270 [btrfs]
[  334.846807]  [<ffffffffa01d4602>] ? find_first_extent_bit_state+0x22/0x80 [btrfs]
[  334.848618]  [<ffffffffa01d524b>] end_bio_extent_readpage+0xcb/0xa30 [btrfs]
[  334.850448]  [<ffffffffa01abe61>] ? end_workqueue_fn+0x31/0x50 [btrfs]
[  334.852246]  [<ffffffff81158988>] bio_endio+0x18/0x30
[  334.854051]  [<ffffffffa01abe6c>] end_workqueue_fn+0x3c/0x50 [btrfs]
[  334.855866]  [<ffffffffa01e2a97>] worker_loop+0x157/0x560 [btrfs]
[  334.857674]  [<ffffffffa01e2940>] ? btrfs_queue_worker+0x310/0x310 [btrfs]
[  334.859471]  [<ffffffff81058e5e>] kthread+0x8e/0xa0
[  334.861248]  [<ffffffff81419064>] kernel_thread_helper+0x4/0x10
[  334.863039]  [<ffffffff81058dd0>] ? flush_kthread_worker+0x70/0x70
[  334.864824]  [<ffffffff81419060>] ? gs_change+0x13/0x13
[  334.866604] ---[ end trace e93713a9d40cd070 ]---
[  334.868388] general protection fault: 0000 [#2] SMP 
[  334.870179] CPU 1 
[  334.870193] Modules linked in: <omitted> [last unloaded: netconsole]
[  334.873732] 
[  334.875508] Pid: 1132, comm: btrfs-endio-met Tainted: G      D W    3.4.4+btrfsdebug #1 System manufacturer System Product Name/P8P67 EVO
[  334.877390] RIP: 0010:[<ffffffff811e83ed>]  [<ffffffff811e83ed>] memcpy+0xd/0x110
[  334.879272] RSP: 0018:ffff8801f2cbdb68  EFLAGS: 00010202
[  334.881147] RAX: ffff8801f2cbdc8f RBX: 0000000000000011 RCX: 0000000000000002
[  334.883023] RDX: 0000000000000001 RSI: 0005080000000003 RDI: ffff8801f2cbdc8f
[  334.884885] RBP: ffff8801f2cbdbe0 R08: 0000000000000000 R09: 0000000000000000
[  334.886768] R10: ffff8801f2cbdc8f R11: ffff8801f3184780 R12: ffff8801f2cbdca0
[  334.888636] R13: ffff88020fcca468 R14: 0000000000000048 R15: 0000000000000011
[  334.890521] FS:  0000000000000000(0000) GS:ffff88021ec40000(0000) knlGS:0000000000000000
[  334.892409] CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[  334.894314] CR2: 00007f784a4fd5d8 CR3: 000000000180c000 CR4: 00000000000407e0
[  334.896227] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  334.898169] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[  334.900095] Process btrfs-endio-met (pid: 1132, threadinfo ffff8801f2cbc000, task ffff8801f491d940)
[  334.902067] Stack:
[  334.904011]  ffffffffa01d8f1b ffff88023b656d69 0000000000000011 0000000000000002
[  334.906031]  00000000000003dd 000000003b656d69 6572747362757320 ffff88020d9a8000
[  334.908045]  ffff8801f2cbdc8f 0000000000001000 ffff8801f2cbdc58 00000000000003dd
[  334.910091] Call Trace:
[  334.912112]  [<ffffffffa01d8f1b>] ? read_extent_buffer+0xbb/0x1a0 [btrfs]
[  334.914183]  [<ffffffffa01d01fd>] btrfs_node_key+0x1d/0x20 [btrfs]
[  334.916243]  [<ffffffffa02067af>] __readahead_hook+0x44f/0x500 [btrfs]
[  334.918312]  [<ffffffffa0206b78>] btree_readahead_hook+0x18/0x40 [btrfs]
[  334.920376]  [<ffffffffa01ac9d1>] btree_readpage_end_io_hook+0x111/0x270 [btrfs]
[  334.922471]  [<ffffffffa01d4602>] ? find_first_extent_bit_state+0x22/0x80 [btrfs]
[  334.924568]  [<ffffffffa01d524b>] end_bio_extent_readpage+0xcb/0xa30 [btrfs]
[  334.926667]  [<ffffffffa01abe61>] ? end_workqueue_fn+0x31/0x50 [btrfs]
[  334.928729]  [<ffffffff81158988>] bio_endio+0x18/0x30
[  334.930798]  [<ffffffffa01abe6c>] end_workqueue_fn+0x3c/0x50 [btrfs]
[  334.932878]  [<ffffffffa01e2a97>] worker_loop+0x157/0x560 [btrfs]
[  334.934952]  [<ffffffffa01e2940>] ? btrfs_queue_worker+0x310/0x310 [btrfs]
[  334.937009]  [<ffffffff81058e5e>] kthread+0x8e/0xa0
[  334.939053]  [<ffffffff81419064>] kernel_thread_helper+0x4/0x10
[  334.941105]  [<ffffffff81058dd0>] ? flush_kthread_worker+0x70/0x70
[  334.943190]  [<ffffffff81419060>] ? gs_change+0x13/0x13
[  334.945270] Code: 4e 48 83 c4 08 5b 5d c3 66 0f 1f 44 00 00 e8 eb fb ff ff eb e1 90 90 90 90 90 90 90 90 90 48 89 f8 48 89 d1 48 c1 e9 03 83 e2 07 <f3> 48 a5 89 d1 f3 a4 c3 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 
[  334.950107] RIP  [<ffffffff811e83ed>] memcpy+0xd/0x110
[  334.952402]  RSP <ffff8801f2cbdb68>
[  334.954732] ---[ end trace e93713a9d40cd071 ]---
------------------------------------------------------------

	Sami
diff mbox

Patch

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a7ffc88..34122c2 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -316,6 +316,11 @@  static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
        return 0;
 }

+int btrfs_csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
+{
+       return csum_tree_block(root, buf, 1);
+}
+
 /*
  * we can't consider a given block up to date unless the transid of the
  * block matches the transid in the parent node's pointer.  This is how we
@@ -471,6 +476,12 @@  static int check_tree_block_fsid(struct btrfs_root *root,
               (unsigned long long)btrfs_header_bytenr(eb),     \
               (unsigned long long)root->objectid, slot)

+#define CORRUPT_NODE(root, node, reason, ...)                  \
+       printk(KERN_CRIT "btrfs: corrupt node block=%llu,"      \
+              "root=%llu: " reason,                            \
+              (unsigned long long)btrfs_header_bytenr(node),   \
+              (unsigned long long)root->objectid, ##__VA_ARGS__)
+
 static noinline int check_leaf(struct btrfs_root *root,
                               struct extent_buffer *leaf)
 {
@@ -532,6 +543,42 @@  static noinline int check_leaf(struct btrfs_root *root,
        return 0;
 }

+static noinline int check_node(struct btrfs_root *root,
+                              struct extent_buffer *node)
+{
+       int i;
+       u32 nritems = btrfs_header_nritems(node);
+       u64 generation;
+
+       if (nritems == 0)
+               return 0;
+
+       if (nritems > BTRFS_NODEPTRS_PER_BLOCK(root)) {
+               CORRUPT_NODE(root, node, "nritems (%lu) too large (%lu)\n",
+                            (unsigned long)nritems,
+                            BTRFS_NODEPTRS_PER_BLOCK(root));
+               return -EIO;
+       }
+
+       if (node->len > root->nodesize) {
+               CORRUPT_NODE(root, node, "length (%lu) too large (%lu)\n",
+                            node->len, (unsigned long)root->nodesize);
+               return -EIO;
+       }
+
+       generation = btrfs_super_generation(root->fs_info->super_copy);
+       for (i = 0; i < nritems; i++) {
+               if (btrfs_node_ptr_generation(node, i) > generation) {
+                       CORRUPT_NODE(root, node, "generation (%llu) too new in slot %d (maximum expected %llu)\n",
+                                    btrfs_node_ptr_generation(node, i), i,
+                                    generation);
+                       return -EIO;
+               }
+       }
+
+       return 0;
+}
+
 struct extent_buffer *find_eb_for_page(struct extent_io_tree *tree,
                                       struct page *page, int max_walk)
 {
@@ -634,6 +681,10 @@  static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
                set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
                ret = -EIO;
        }
+       if (found_level != 0 && check_node(root, eb)) {
+               set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
+               ret = -EIO;
+       }

        if (!ret)
                set_extent_buffer_uptodate(eb);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index beabe99..099ce6e 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -4507,6 +4507,7 @@  unlock_exit:
        return ret;
 }

+extern int btrfs_csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf);
 void read_extent_buffer(struct extent_buffer *eb, void *dstv,
                        unsigned long start,
                        unsigned long len)
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c
index d9c1146..b659c8d 100644
--- a/fs/btrfs/reada.c
+++ b/fs/btrfs/reada.c
@@ -103,6 +103,7 @@  static void __reada_start_machine(struct btrfs_fs_info *fs_info);
 static int reada_add_block(struct reada_control *rc, u64 logical,
                           struct btrfs_key *top, int level, u64 generation);

+extern int btrfs_csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf);
 /* recurses */
 /* in case of err, eb might be NULL */
 static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,
@@ -144,6 +145,10 @@  static int __readahead_hook(struct btrfs_root *root, struct extent_buffer *eb,

        if (err == 0) {
                nritems = level ? btrfs_header_nritems(eb) : 0;
+               if (level > BTRFS_MAX_LEVEL ||
+                   nritems > BTRFS_NODEPTRS_PER_BLOCK(root))
+                       printk(KERN_ERR "btrfs: node seems invalid now. checksum ok = %d\n",
+                               btrfs_csum_tree_block(root, eb));
                generation = btrfs_header_generation(eb);
                /*
                 * FIXME: currently we just set nritems to 0 if this is a leaf,