On Tue, Sep 24, 2013 at 10:43 AM, majianpeng <[email protected]> wrote:
>>On Mon, Sep 23, 2013 at 9:39 AM, majianpeng <[email protected]> wrote:
>>> As Yan,Zheng said, commit 0913444208db intruoduce a bug:"getattr need to
>>> "read lock" inode's filelock. But the lock can be in unstable state.
>>> the getattr request waits for lock's state to become stable, the lock
>>> waits for client to release Fr cap."
>>>
>>> Commit 6a026589ba333185c466c90 resolved the same bug also.
>>> Before doing getattr, it must put the caps which already hold avoid
>>> deadlock.
>>>
>>> Reported-by: Yan, Zheng <[email protected]>
>>> Signed-off-by: Jianpeng Ma <[email protected]>
>>> ---
>>> fs/ceph/file.c | 25 ++++++++++++++++++++-----
>>> 1 file changed, 20 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
>>> index 7da35c7..bc00ace 100644
>>> --- a/fs/ceph/file.c
>>> +++ b/fs/ceph/file.c
>>> @@ -839,7 +839,15 @@ again:
>>> ret = ceph_sync_read(iocb, &i, &checkeof);
>>>
>>> if (checkeof && ret >= 0) {
>>> - int statret = ceph_do_getattr(inode,
>>> + int statret;
>>> + /*
>>> + *Before getattr,it should put caps avoid
>>> + *deadlock.
>>> + */
>>> + ceph_put_cap_refs(ci, got);
>>> + got = 0;
>>> +
>>> + statret = ceph_do_getattr(inode,
>>> CEPH_STAT_CAP_SIZE);
>>>
>>> /* hit EOF or hole? */
>>> @@ -851,16 +859,23 @@ again:
>>>
>>> read += ret;
>>> checkeof = 0;
>>> - goto again;
>>> + ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD,
>>> + want, &got, -1);
>>> + if (ret < 0)
>>> + ret = 0;
>>> + else
>>> + goto again;
>>
>>I think we should try getting Frc caps here, because mds may issue Fc
>>cap to the client while requesting the size.
>>
> Yes,it maybe get Fc.My though whether or not, the later read only using
> sync_mode.
I don't see any reason for not doing buffered read when we succeed in
getting Fc cap. Buffered read is much faster than the sync read, we
should use it if possible.
> The reason:
> A:for requesting size only for sync-read not cache-read
> B:By the original, it will make the cache-read to do the same thing which
> sync-read alread done.
For buffered read, 'checkeof' be false, so the requesting size code
should never get executed.
>
> Thanks!
> Jianpeng Ma
>>Your previous patch moved the getattr code to here. please revert the
>>code to its original shape. I think it does the right thing.
>>
Another reason I prefer the original code is that it prints message
for getting/releasing caps.
Sage dropped your readv patch from the test branch (writev is still
in), please update and re-send the patch.
Regards
Yan, Zheng
>>
>>
>>> }
>>> }
>>>
>>> } else
>>> ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
>>>
>>> - dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
>>> - inode, ceph_vinop(inode), ceph_cap_string(got), (int)ret);
>>> - ceph_put_cap_refs(ci, got);
>>> + if (got) {
>>> + dout("aio_read %p %llx.%llx dropping cap refs on %s = %d\n",
>>> + inode, ceph_vinop(inode), ceph_cap_string(got),
>>> (int)ret);
>>> + ceph_put_cap_refs(ci, got);
>>> + }
>>
>>
>>
>>
>>>
>>> if (ret >= 0)
>>> ret += read;
>>> --
>>> 1.8.4-rc0
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html