On Mon, Jan 30, 2012 at 6:03 PM, Jan Schmidt <list.bt...@jan-o-sch.net> wrote:
> On 30.01.2012 07:33, Li Zefan wrote:
>> Jan Schmidt wrote:
>>> I was looking at the clone range ioctl and have some remarks:
>>>
>>> On 27.01.2011 09:46, Li Zefan wrote:
>>>> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
>>>> index f87552a..1b61dab 100644
>>>> --- a/fs/btrfs/ioctl.c
>>>> +++ b/fs/btrfs/ioctl.c
>>>> @@ -1788,7 +1788,10 @@ static noinline long btrfs_ioctl_clone(struct file 
>>>> *file, unsigned long srcfd,
>>>>
>>>>                     memcpy(&new_key, &key, sizeof(new_key));
>>>>                     new_key.objectid = inode->i_ino;
>>>> -                   new_key.offset = key.offset + destoff - off;
>>>> +                   if (off <= key.offset)
>>>> +                           new_key.offset = key.offset + destoff - off;
>>>> +                   else
>>>> +                           new_key.offset = destoff;
>>>                                               ^^^^^^^
>>> 1) This looks spurious to me. What if destoff isn't aligned? That's what
>>> the "key.offset - off" code above is for. Before the patch, the code
>>> didn't work at all, I agree. But this fix can only work for aligned
>>> requests.
>>>
>>> 2) The error in new_key also has propagated to the extent item's backref
>>> and wasn't fixed there. I did a range clone and ended up with an extent
>>> item like that:
>>>         item 30 key (1318842368 EXTENT_ITEM 131072) itemoff 1047
>>> itemsize 169
>>>                 extent refs 8 gen 11103 flags 1
>>> [...]
>>>                 extent data backref root 257 objectid 272 offset
>>> 18446744073709494272 count 1
>>>
>>> The last offset (equal to -14 * 4k) is obviously wrong. I didn't figure
>>> out how the variables are computed, but it looks like there's something
>>> wrong with the "datao" u64 to me.
>>>
>>
>> Unfortunately this is expected. The calculation is:
>>
>> extent_item.extent_data_ref.offset = file_pos - file_extent.extent_offset
>>
>> so you may get negative offset.
>
> I see where the negative offset comes from. But what can this offset be
> used for?
>

The offset in backref isn't equal to the offset of the file extent,
it's just a hint for searching
file extents, Negative offset isn't that bad if you consider it as
value that is close to zero.



>> The design idea was to reduce the number of extent backrefs in that
>> a data backref can point to different file extents in the same file
>> (in this case the "count" field > 1). We didn't expect nagetive
>> offset until range clone was implemented.
>
> Reducing the number of backrefs is a good thing. In case of count > 1,
> it's clear that the offset cannot reference all of the extent data
> items. We have different design choices:
>
> a) Use the above computation and leave the filesystem with an unusable
> offset value for extent backrefs.
>
> b) Use either one of the extent data item offsets this backref references.
>
> c) Always use a predefined constant (like 0 or -1) when count > 1.
>
> d) Disallow count > 1 for those refs and turn them into shared refs as
> soon as count gets > 1.
>
> I don't like a :-)
>
> -Jan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to