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>
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index a83cbdf..19c0dd3 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -813,7 +813,8 @@
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 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 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 7449ecf..607f5ff 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3471,6 +3471,7 @@
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 a79b3cc..825364f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2594,12 +2594,15 @@
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++) {