[Btrfs-devel] Some queries about map_extent_buffer()
Peter Teoh
htmldeveloper at gmail.com
Mon Mar 17 04:00:36 PDT 2008
Thanks for the explanation. But my point is the C statement "continue":
for (i = start_slot; i < end_slot; i++) {============> start
of loop, "continue" therefore will come here.
int close = 1;
if (!parent->map_token) {
map_extent_buffer(parent,
btrfs_node_key_ptr_offset(i),
sizeof(struct btrfs_key_ptr),
&parent->map_token, &parent->kaddr,
&parent->map_start, &parent->map_len,
KM_USER1);
}
btrfs_node_key(parent, &disk_key, i);
if (!progress_passed && comp_keys(&disk_key, progress) < 0)
continue;==================>for example, this
is executed
progress_passed = 1;
blocknr = btrfs_node_blockptr(parent, i);
if (last_block == 0)
last_block = blocknr;
if (i > 0) {
other = btrfs_node_blockptr(parent, i - 1);
close = close_blocks(blocknr, other, blocksize);
}
if (close && i < end_slot - 2) {
other = btrfs_node_blockptr(parent, i + 1);
close = close_blocks(blocknr, other, blocksize);
}
if (close) {
last_block = blocknr;
continue;==================>or for example,
this is executed
}
if (parent->map_token) {
unmap_extent_buffer(parent, parent->map_token,
KM_USER1);
parent->map_token = NULL;
}
cur = btrfs_find_tree_block(root, blocknr, blocksize);
When the statement "continue" is executed, the next loop will call
map_extent_buffer() again, in addition to the previously called
map_extent_buffer(), with NO unmap_extent_buffer() called in between.
So the result is effectively kmap_atomic() is called twice, without
kunmap_atomic() called. Is this execution path possible? Will it
lead to a problem? I am not sure.
>
> First, at the end of all of these (that is to say, the end of function
> btrfs_realloc_node), there is:
>
>
> if (parent->map_token) {
> unmap_extent_buffer(parent, parent->map_token,KM_USER1);
> parent->map_token = NULL;
> }
> return err;
>
> It can make sure that we can call unmap_extent_buffer anyway when we
> get out of the function (of course, if parent->map_token != NULL).
>
> Also, at the very beginning of map_extent_buffer, there is :
>
> if (eb->map_token) {
> unmap_extent_buffer(eb, eb->map_token, km);
> eb->map_token = NULL;
> save = 1;
> }
>
> So if we feed a mapped extent buffer into the function, it will unmap
> it at first, and then call map_private_extent_buffer to map it.
>
>
> Regards,
> ZYH
>
>
>
>
> --
> - Zhu Yanhai
>
--
Regards,
Peter Teoh
More information about the Btrfs-devel
mailing list