diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-12-08 16:43:10 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-12-08 16:43:10 -0500 |
commit | 934d375bacf9ea8a37fbfff5f3cf1c093f324095 (patch) | |
tree | e81948e6e26028fd979ce59f4fc5988c1813694c /fs/btrfs/ctree.c | |
parent | a512bbf855ff0af474257475f2e6da7acd854f52 (diff) |
Btrfs: Use map_private_extent_buffer during generic_bin_search
It is possible that generic_bin_search will be called on a tree block
that has not been locked. This happens because cache_block_block skips
locking on the tree blocks.
Since the tree block isn't locked, we aren't allowed to change
the extent_buffer->map_token field. Using map_private_extent_buffer
avoids any changes to the internal extent buffer fields.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index a83cbdf1d8c4..19c0dd33b1e8 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -813,7 +813,8 @@ static noinline int generic_bin_search(struct extent_buffer *eb, | |||
813 | unmap_extent_buffer(eb, map_token, KM_USER0); | 813 | unmap_extent_buffer(eb, map_token, KM_USER0); |
814 | map_token = NULL; | 814 | map_token = NULL; |
815 | } | 815 | } |
816 | err = map_extent_buffer(eb, offset, | 816 | |
817 | err = map_private_extent_buffer(eb, offset, | ||
817 | sizeof(struct btrfs_disk_key), | 818 | sizeof(struct btrfs_disk_key), |
818 | &map_token, &kaddr, | 819 | &map_token, &kaddr, |
819 | &map_start, &map_len, KM_USER0); | 820 | &map_start, &map_len, KM_USER0); |
@@ -3585,6 +3586,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | |||
3585 | int level; | 3586 | int level; |
3586 | int ret = 1; | 3587 | int ret = 1; |
3587 | 3588 | ||
3589 | WARN_ON(!path->keep_locks); | ||
3588 | again: | 3590 | again: |
3589 | cur = btrfs_lock_root_node(root); | 3591 | cur = btrfs_lock_root_node(root); |
3590 | level = btrfs_header_level(cur); | 3592 | level = btrfs_header_level(cur); |
@@ -3708,6 +3710,7 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, | |||
3708 | int slot; | 3710 | int slot; |
3709 | struct extent_buffer *c; | 3711 | struct extent_buffer *c; |
3710 | 3712 | ||
3713 | WARN_ON(!path->keep_locks); | ||
3711 | while(level < BTRFS_MAX_LEVEL) { | 3714 | while(level < BTRFS_MAX_LEVEL) { |
3712 | if (!path->nodes[level]) | 3715 | if (!path->nodes[level]) |
3713 | return 1; | 3716 | return 1; |