Skip to content

Commit

Permalink
Btrfs: fix releasepage to avoid unlocking extents we haven't locked
Browse files Browse the repository at this point in the history
During releasepage, we try to drop any extent_state structs for the
bye offsets of the page we're releaseing.  But the code was incorrectly
telling clear_extent_bit to delete the state struct unconditionallly.

Normally this would be fine because we have the page locked, but other
parts of btrfs will lock down an entire extent, the most common place
being IO completion.

releasepage was deleting the extent state without first locking the extent,
which may result in removing a state struct that another process had
locked down.  The fix here is to leave the NODATASUM and EXTENT_LOCKED
bits alone in releasepage.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Sep 24, 2009
1 parent 46562ce commit 11ef160
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,8 +2809,13 @@ int try_release_extent_state(struct extent_map_tree *map,
else {
if ((mask & GFP_NOFS) == GFP_NOFS)
mask = GFP_NOFS;
clear_extent_bit(tree, start, end, EXTENT_UPTODATE,
1, 1, NULL, mask);
/*
* at this point we can safely clear everything except the
* locked bit and the nodatasum bit
*/
clear_extent_bit(tree, start, end,
~(EXTENT_LOCKED | EXTENT_NODATASUM),
0, 0, NULL, mask);
}
return ret;
}
Expand Down

0 comments on commit 11ef160

Please sign in to comment.