From 934d375bacf9ea8a37fbfff5f3cf1c093f324095 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 8 Dec 2008 16:43:10 -0500 Subject: [PATCH] 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 --- fs/btrfs/ctree.c | 5 ++++- fs/btrfs/extent_io.c | 1 + fs/btrfs/volumes.c | 5 ++++- 3 files changed, 9 insertions(+), 2 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, unmap_extent_buffer(eb, map_token, KM_USER0); map_token = NULL; } - err = map_extent_buffer(eb, offset, + + err = map_private_extent_buffer(eb, offset, sizeof(struct btrfs_disk_key), &map_token, &kaddr, &map_start, &map_len, KM_USER0); @@ -3585,6 +3586,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, int level; int ret = 1; + WARN_ON(!path->keep_locks); again: cur = btrfs_lock_root_node(root); level = btrfs_header_level(cur); @@ -3708,6 +3710,7 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, int slot; struct extent_buffer *c; + WARN_ON(!path->keep_locks); while(level < BTRFS_MAX_LEVEL) { if (!path->nodes[level]) return 1; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 7449ecf32c50..607f5ff2791c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3471,6 +3471,7 @@ int map_extent_buffer(struct extent_buffer *eb, unsigned long start, unmap_extent_buffer(eb, eb->map_token, km); eb->map_token = NULL; save = 1; + WARN_ON(!mutex_is_locked(&eb->mutex)); } err = map_private_extent_buffer(eb, start, min_len, token, map, map_start, map_len, km); diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index a79b3cc09e94..825364fae690 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2594,12 +2594,15 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, stripe_nr = stripe_nr * map->num_stripes + i; } bytenr = chunk_start + stripe_nr * map->stripe_len; + WARN_ON(nr >= map->num_stripes); for (j = 0; j < nr; j++) { if (buf[j] == bytenr) break; } - if (j == nr) + if (j == nr) { + WARN_ON(nr >= map->num_stripes); buf[nr++] = bytenr; + } } for (i = 0; i > nr; i++) { -- 2.30.2