Btrfs: fix extent pinning bugs in the tree log
authorChris Mason <chris.mason@oracle.com>
Tue, 1 Nov 2011 00:52:39 +0000 (20:52 -0400)
committerChris Mason <chris.mason@oracle.com>
Sun, 6 Nov 2011 08:03:48 +0000 (03:03 -0500)
commite688b7252f784c2479d559f9f70ca8354752c5e7
tree3934b0a9c348b2900e08e8fc9c0e6819e80d0fff
parent1eae31e918972bbeefc119d23c1d67674f49a301
Btrfs: fix extent pinning bugs in the tree log

The tree log had two important bugs that could cause corruptions after a
crash.  Sometimes we were allowing tree log blocks to be reused after
the tree log was committed but before the transaction commit was done.

This allowed a future metadata write to overwrite the tree log data.  It
is fixed by adding a new variant of freeing reserved extents that always
pins them.  Credit goes to Stefan Behrens and Arne Jansen for many many
hours spent tracking this bug down.

During tree log replay, we do a pass through the tree log and pin all
the extents we find.  This makes sure the replay code won't go in and
use any of those blocks for new allocations during replay.  The problem
is the free space cache isn't honoring these pinned extents.  So the
allocator can end up handing them out, leading to all kinds of problems
during replay.

The fix here is to force any free space cache to load while we pin the
extents, and then to make sure we remove the pinned extents from the
free space rbtree.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Reported-by: Stefan Behrens <sbehrens@giantdisaster.de>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/tree-log.c