Re: Re: question about striped_read

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>On Wed, Jul 31, 2013 at 9:36 AM, majianpeng <majianpeng@xxxxxxxxx> wrote:
>> [snip]
>> I think this patch can do work:
>> Those case which i tested
>> A: filesize=0,  buffer=1M
>> B:  data[2M] | hole| data[2M], bs= 6M/7M
>
>I don't think your zero buffer change is correct for this test case.
>
dd if=/dev/urandom of=file bs=1M count=2  oflag=direct
dd if=/dev/urandom of=file bs=1M count=2 seek=4  oflag=direct
ls file
-rw-r--r-- 1 root root  6291456 Jul 31 12:46 file

debug message:
[78370.408220] ceph:           file.c:355  : striped_read 0~7340032 (read 0) got 2097152 HITSTRIPE SHORT
[78370.409179] ceph:           file.c:355  : striped_read 2097152~5242880 (read 2097152) got 0 HITSTRIPE HITHOLE
[78370.409182] ceph:           file.c:362  :  zero hole 2097152 to 4194304
[78370.431289] ceph:           file.c:355  : striped_read 4194304~3145728 (read 4194304) got 2097152 SHORT
[78370.431294] ceph:           file.c:399  : striped_read returns 6291456

Am i missing something?

>> C: data[4m] | hole | hole |data[2M]  bs=16M/18M
>>
>> Are there some case ignore?
>> Thanks!
>> Jianpeng Ma
>>
>>
>> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
>> index 2ddf061..96ce893 100644
>> --- a/fs/ceph/file.c
>> +++ b/fs/ceph/file.c
>> @@ -319,7 +319,7 @@ static int striped_read(struct inode *inode,
>>         int read;
>>         struct page **page_pos;
>>         int ret;
>> -       bool hit_stripe, was_short;
>> +       bool hit_stripe, was_short, hit_hole = false;
>>
>>         /*
>>          * we may need to do multiple reads.  not atomic, unfortunately.
>> @@ -342,21 +342,30 @@ more:
>>                                   ci->i_truncate_seq,
>>                                   ci->i_truncate_size,
>>                                   page_pos, pages_left, page_align);
>> -       if (ret == -ENOENT)
>> +
>> +       if ((ret == 0  || ret == -ENOENT) && pos < inode->i_size)
>> +               hit_hole = true;
>
>why do we need 'hit_hole', it's essential the same as was_short. The code
>is already so messy.
>I don't think adding 'hit_hole' make it more readable.
>
hit_hole means return value are ENOENT or zero.
But the short-read contain EOF beside above two case.
>> +       else if (ret == -ENOENT)
>>                 ret = 0;
>> +
>>         hit_stripe = this_len < left;
>> -       was_short = ret >= 0 && ret < this_len;
>> -       dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left,
>read,
>> -            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" :
>"");
>> -
>> -       if (ret > 0) {
>> -               int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
>> -
>> -               if (read < pos - off) {
>> -                       dout(" zero gap %llu to %llu\n", off + read, pos);
>> -                       ceph_zero_page_vector_range(page_align + read,
>> -                                                   pos - off - read,
>pages);
>> +       was_short = ret > 0 && ret < this_len;
>> +       dout("striped_read %llu~%u (read %u) got %d%s%s%s\n", pos, left,
>read,
>> +            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" :
>"",
>> +            hit_hole ? " HITHOLE" : "");
>> +
>> +       if (ret > 0 || hit_hole) {
>> +               int didpages;
>> +
>> +               if (hit_hole) {
>> +                       ret = this_len;
>> +                       dout(" zero hole %llu to %llu\n", pos , pos +
>ret);
>> +                       ceph_zero_page_vector_range(page_align + read,
>> +                                                       ret, pages);
>> +                       hit_hole = false;
>this is incorrect for the 'ret > 0' and 'ret = -ENOENT' cases.
>
For the ret > 0, it can't do those.
For the ret = -ENOENT and  pos + this_len > i_size mean , can you give me a example ?

Jianpeng Ma
>Besides, if 'pos + this_len >= i_size'. we should do nothing here. let the
>'zero trailing bytes'
>code do the job.
>
>Yan, Zheng
>
>>                 }
>> +               didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
>> +
>>                 pos += ret;
>>                 read = pos - off;
>>                 left -= ret;
>
Thanks!
Jianpeng Ma
>On Wed, Jul 31, 2013 at 9:36 AM, majianpeng <majianpeng@xxxxxxxxx> wrote:
>> [snip]
>> I think this patch can do work:
>> Those case which i tested
>> A: filesize=0,  buffer=1M
>> B:  data[2M] | hole| data[2M], bs= 6M/7M
>
>I don't think your zero buffer change is correct for this test case.
>
>> C: data[4m] | hole | hole |data[2M]  bs=16M/18M
>>
>> Are there some case ignore?
>> Thanks!
>> Jianpeng Ma
>>
>>
>> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
>> index 2ddf061..96ce893 100644
>> --- a/fs/ceph/file.c
>> +++ b/fs/ceph/file.c
>> @@ -319,7 +319,7 @@ static int striped_read(struct inode *inode,
>>         int read;
>>         struct page **page_pos;
>>         int ret;
>> -       bool hit_stripe, was_short;
>> +       bool hit_stripe, was_short, hit_hole = false;
>>
>>         /*
>>          * we may need to do multiple reads.  not atomic, unfortunately.
>> @@ -342,21 +342,30 @@ more:
>>                                   ci->i_truncate_seq,
>>                                   ci->i_truncate_size,
>>                                   page_pos, pages_left, page_align);
>> -       if (ret == -ENOENT)
>> +
>> +       if ((ret == 0  || ret == -ENOENT) && pos < inode->i_size)
>> +               hit_hole = true;
>
>why do we need 'hit_hole', it's essential the same as was_short. The code
>is already so messy.
>I don't think adding 'hit_hole' make it more readable.
>
>> +       else if (ret == -ENOENT)
>>                 ret = 0;
>> +
>>         hit_stripe = this_len < left;
>> -       was_short = ret >= 0 && ret < this_len;
>> -       dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left,
>read,
>> -            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" :
>"");
>> -
>> -       if (ret > 0) {
>> -               int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
>> -
>> -               if (read < pos - off) {
>> -                       dout(" zero gap %llu to %llu\n", off + read, pos);
>> -                       ceph_zero_page_vector_range(page_align + read,
>> -                                                   pos - off - read,
>pages);
>> +       was_short = ret > 0 && ret < this_len;
>> +       dout("striped_read %llu~%u (read %u) got %d%s%s%s\n", pos, left,
>read,
>> +            ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" :
>"",
>> +            hit_hole ? " HITHOLE" : "");
>> +
>> +       if (ret > 0 || hit_hole) {
>> +               int didpages;
>> +
>> +               if (hit_hole) {
>> +                       ret = this_len;
>> +                       dout(" zero hole %llu to %llu\n", pos , pos +
>ret);
>> +                       ceph_zero_page_vector_range(page_align + read,
>> +                                                       ret, pages);
>> +                       hit_hole = false;
>this is incorrect for the 'ret > 0' and 'ret = -ENOENT' cases.
>
>Besides, if 'pos + this_len >= i_size'. we should do nothing here. let the
>'zero trailing bytes'
>code do the job.
>
>Yan, Zheng
>
>>                 }
>> +               didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
>> +
>>                 pos += ret;
>>                 read = pos - off;
>>                 left -= ret;
>?韬{.n?????%??檩??w?{.n????u朕?Ф?塄}?财??j:+v??????2??璀??摺?囤??z夸z罐?+?????w棹f





[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux