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>
This commit is contained in:
parent
a512bbf855
commit
934d375bac
3 changed files with 9 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Reference in a new issue