CEPH filesystem development
 help / color / mirror / Atom feed
From: "Yan, Zheng" <zheng.z.yan@intel.com>
To: Sage Weil <sage@inktank.com>
Cc: ceph-devel@vger.kernel.org
Subject: Re: [PATCH V2] mds: fix CDir::_commit_partial() bug
Date: Sun, 25 Nov 2012 02:14:21 +0800	[thread overview]
Message-ID: <50B10E7D.6000600@intel.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1211240949410.23552@cobra.newdream.net>

On 11/25/2012 01:51 AM, Sage Weil wrote:
> On Sun, 25 Nov 2012, Yan, Zheng wrote:
>> On 11/25/2012 12:21 AM, Sage Weil wrote:
>>> On Sat, 24 Nov 2012, Yan, Zheng wrote:
>>>> Hi, Sage
>>>>
>>>> I found this fix is still not enough because we don't know if a dentry has been
>>>> successfully deleted from the directory fragment after MDS restart. There are several
>>>> options to fix this, which one do you like?
>>>>
>>>> 1. Make OSD ignore the TMAP_RM commands if it can't the find items.
>>>
>>> This is certainly the simplest.  Since TMAP is effectively deprecated and 
>>> everyone should be using the omap stuff anyway, it gets my vote.
>>>
>>> Speaking of, we should transition the MDS to use the omap operations soon 
>>> as well, since TMAP is horribly inefficient for large directories.  Also, 
>>> the rmkey method in that case does not have this problem.
>>
>> I can do this, it should be easy.
>>
>>>
>>> Let's ignore enoent on TMAP_RM for bobtail, and transition to omap in the 
>>> next release... do you want to test the patch that drops the !key_exists 
>>> check?
>>
>> I will modify the code and test it. but I think it is hiding bugs ;)
>>
>> Another issue of tmap is that we may get different results when comparing two dentry_key_t
>> and their string representation. So the dentries in tmap can be out of order, setkey method
>> may add duplicated dentry and rmkey method may fail to find existing dentry. Since tmap is
>> so buggy, let's switch the MDS to use the omap ASAP.
> 
> Yeah.  I think the question is what is the minimal set of fixes we should 
> do to the TMAP implementation for bobtail before changing to omap.  The 
> dentry_key_t ordering fix you posted the other day and ignoring the rm 
> failures should catch these, right?

Yes, that bug was caught by the !key_exists check. Actually the patch I previously sent
is buggy too, it breaks CDir::lookup. I have a patch that sorts dentries in CDir::_commit_full
and CDir::_commit_partial. It survives over night fsstress test, but change is ugly and
relatively large. I will send it out tomorrow.

Regards
Yan, Zheng
> 
> sage
> 
> 
>>
>> Regards
>> Yan, Zheng
>>
>>
>>>
>>> Thanks!
>>> sage
>>>
>>>  
>>>> 2. Add a new item deletion command for tmap, the new command doesn't make whole tmap
>>>>    update operation fail if it can't the item. When committing directory fragments,
>>>>    use the new command for null dentries that were added by MDS log replay.
>>>>
>>>> 3. When committing a directory fragment, Re-fetch it if it contains dirty+null dentries
>>>>    that were added by MDS log replay. Find already deleted items and mark corresponding
>>>>    dentries as new.
>>>>
>>>> Regards
>>>> Yan, Zheng
>>>>
>>>> On 11/23/2012 12:52 AM, Yan, Zheng wrote:
>>>>> From: "Yan, Zheng" <zheng.z.yan@intel.com>
>>>>>
>>>>> When a null dentry is encountered, CDir::_commit_partial() adds
>>>>> a OSD_TMAP_RM command to delete the dentry. But if the dentry is
>>>>> new, the osd will not find the dentry when handling the command
>>>>> and the tmap update operation will fail totally.
>>>>>
>>>>> This patch also makes sure dentries are properly marked as new
>>>>> when preparing new dentries and exporting dentries.
>>>>>
>>>>> Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
>>>>> ---
>>>>>  src/mds/CDentry.h  |  2 ++
>>>>>  src/mds/CDir.cc    | 11 ++++++++---
>>>>>  src/mds/CDir.h     |  2 +-
>>>>>  src/mds/MDCache.cc |  9 ++++++---
>>>>>  src/mds/Server.cc  |  3 +++
>>>>>  5 files changed, 20 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h
>>>>> index 480e562..5755c55 100644
>>>>> --- a/src/mds/CDentry.h
>>>>> +++ b/src/mds/CDentry.h
>>>>> @@ -347,6 +347,8 @@ public:
>>>>>      // twiddle
>>>>>      state = 0;
>>>>>      state_set(CDentry::STATE_AUTH);
>>>>> +    if (nstate & STATE_NEW)
>>>>> +      mark_new();
>>>>>      if (nstate & STATE_DIRTY)
>>>>>        _mark_dirty(ls);
>>>>>      if (!replica_map.empty())
>>>>> diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc
>>>>> index c5220ed..411d864 100644
>>>>> --- a/src/mds/CDir.cc
>>>>> +++ b/src/mds/CDir.cc
>>>>> @@ -1696,7 +1696,7 @@ class C_Dir_Committed : public Context {
>>>>>  public:
>>>>>    C_Dir_Committed(CDir *d, version_t v, version_t lrv) : dir(d), version(v), last_renamed_version(lrv) { }
>>>>>    void finish(int r) {
>>>>> -    dir->_committed(version, last_renamed_version);
>>>>> +    dir->_committed(version, last_renamed_version, r);
>>>>>    }
>>>>>  };
>>>>>  
>>>>> @@ -1802,6 +1802,10 @@ CDir::map_t::iterator CDir::_commit_partial(ObjectOperation& m,
>>>>>        continue;  // skip clean dentries
>>>>>  
>>>>>      if (dn->get_linkage()->is_null()) {
>>>>> +      if (dn->is_new()) {
>>>>> +	dn->mark_clean();
>>>>> +	continue;
>>>>> +      }
>>>>>        dout(10) << " rm " << dn->name << " " << *dn << dendl;
>>>>>        finalbl.append(CEPH_OSD_TMAP_RM);
>>>>>        dn->key().encode(finalbl);
>>>>> @@ -1997,10 +2001,11 @@ void CDir::_commit(version_t want)
>>>>>   *
>>>>>   * @param v version i just committed
>>>>>   */
>>>>> -void CDir::_committed(version_t v, version_t lrv)
>>>>> +void CDir::_committed(version_t v, version_t lrv, int ret)
>>>>>  {
>>>>> -  dout(10) << "_committed v " << v << " (last renamed " << lrv << ") on " << *this << dendl;
>>>>> +  dout(10) << "_committed ret " << ret << " v " << v << " (last renamed " << lrv << ") on " << *this << dendl;
>>>>>    assert(is_auth());
>>>>> +  assert(ret == 0);
>>>>>  
>>>>>    bool stray = inode->is_stray();
>>>>>  
>>>>> diff --git a/src/mds/CDir.h b/src/mds/CDir.h
>>>>> index 2222418..274e38b 100644
>>>>> --- a/src/mds/CDir.h
>>>>> +++ b/src/mds/CDir.h
>>>>> @@ -487,7 +487,7 @@ private:
>>>>>                         unsigned max_write_size=-1,
>>>>>                         map_t::iterator last_committed_dn=map_t::iterator());
>>>>>    void _encode_dentry(CDentry *dn, bufferlist& bl, const set<snapid_t> *snaps);
>>>>> -  void _committed(version_t v, version_t last_renamed_version);
>>>>> +  void _committed(version_t v, version_t last_renamed_version, int ret);
>>>>>    void wait_for_commit(Context *c, version_t v=0);
>>>>>  
>>>>>    // -- dirtyness --
>>>>> diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc
>>>>> index f8b1c8f..e69a49f 100644
>>>>> --- a/src/mds/MDCache.cc
>>>>> +++ b/src/mds/MDCache.cc
>>>>> @@ -657,12 +657,15 @@ CDentry *MDCache::get_or_create_stray_dentry(CInode *in)
>>>>>    CDir *straydir = strayi->get_dirfrag(fg);
>>>>>    assert(straydir);
>>>>>    CDentry *straydn = straydir->lookup(straydname);
>>>>> -  if (!straydn) {
>>>>> +
>>>>> +  if (!straydn)
>>>>>      straydn = straydir->add_null_dentry(straydname);
>>>>> -    straydn->mark_new();
>>>>> -  } else 
>>>>> +  else
>>>>>      assert(straydn->get_projected_linkage()->is_null());
>>>>>  
>>>>> +  if (!straydn->is_dirty())
>>>>> +    straydn->mark_new();
>>>>> +
>>>>>    return straydn;
>>>>>  }
>>>>>  
>>>>> diff --git a/src/mds/Server.cc b/src/mds/Server.cc
>>>>> index ec0d5d5..228fede 100644
>>>>> --- a/src/mds/Server.cc
>>>>> +++ b/src/mds/Server.cc
>>>>> @@ -1685,6 +1685,9 @@ CDentry* Server::prepare_null_dentry(MDRequest *mdr, CDir *dir, const string& dn
>>>>>        }
>>>>>      }
>>>>>  
>>>>> +    if (!dn->is_dirty())
>>>>> +      dn->mark_new();
>>>>> +
>>>>>      return dn;
>>>>>    }
>>>>>  
>>>>>
>>>>
>>>>
>>
>>


  reply	other threads:[~2012-11-24 18:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-22 16:52 [PATCH V2] mds: fix CDir::_commit_partial() bug Yan, Zheng
2012-11-24 11:05 ` Yan, Zheng
2012-11-24 16:21   ` Sage Weil
2012-11-24 17:45     ` Yan, Zheng
2012-11-24 17:51       ` Sage Weil
2012-11-24 18:14         ` Yan, Zheng [this message]
2012-12-01 13:58 ` Yan, Zheng
2012-12-01 20:56   ` Sage Weil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50B10E7D.6000600@intel.com \
    --to=zheng.z.yan@intel.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=sage@inktank.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox