[Btrfs-devel] Some queries about map_extent_buffer()

Peter Teoh htmldeveloper at gmail.com
Mon Mar 17 08:41:34 PDT 2008


Yes, u are right.   After this extended discussion, I have a better
understanding now :-).   Thanks for the sharing :-).

On Mon, Mar 17, 2008 at 9:07 PM, Yan Zheng <yanzheng at 21cn.com> wrote:
>
> 2008/3/17, Peter Teoh <htmldeveloper at gmail.com>:
>  > On Mon, Mar 17, 2008 at 7:52 PM, Yan Zheng <yanzheng at 21cn.com> wrote:
>  >  > 2008/3/17, Peter Teoh <htmldeveloper at gmail.com>:
>  >  >
>  >  > > 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);
>  >  >  >                 }
>  >  >  Please pay attention to the fourth parameter for map_extent_buffer.
>  >  >  Once map_extent_buffer has been called,  parent->map_token must not be
>  >  >  NULL.
>  >
>  >
>  > Yes, but I think u are assuming that map_extent_buffer() execute
>  >  correctly.   What if it is not?
>  >
>  >  Trace through map_extent_buffer()-->inside the function:
>  >
>  >  map_extent_buffer:
>  >  {
>  >         int err;
>  >         int save = 0;
>  >
>  >         if (eb->map_token) {
>  >                 unmap_extent_buffer(eb, eb->map_token, km);
>  >                 eb->map_token = NULL;
>  >                 save = 1;
>  >         }
>  >
>  >         err = map_private_extent_buffer(eb, start, min_len, token, map,
>  >                                        map_start, map_len, km);
>  >         if (!err && save) {
>  >                 eb->map_token = *token;
>  >                 eb->kaddr = *map;
>  >                 eb->map_start = *map_start;
>  >                 eb->map_len = *map_len;
>  >         }
>  >         return err;
>  >  }
>  >
>  >  err can be EINVAL, because of this:
>  >
>  >         if (i != end_i)
>  >                 return -EINVAL;
>  >
>  >  And this is returned even before assigning the token:
>  >
>  >         *token = kaddr;
>  >
>  >  So if parent->map_token started off with NULL value, it will continue
>  >  to remain as NULL, thus leading to map_extent_buffer() being called
>  >  multiple times.   Correct?
>  >
>  map_extent_buffer releases previous map (if there is any) at very
>  beginning, so there is no problem even map_extent_buffer is called
>  multiple times.
>
>  Regards
>  YZ
>



-- 
Regards,
Peter Teoh



More information about the Btrfs-devel mailing list