]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use 'is in stray' instead 'nlink == 0' to check deleted inodes
authorYan, Zheng <zyan@redhat.com>
Fri, 14 Apr 2017 01:28:10 +0000 (09:28 +0800)
committerYan, Zheng <zyan@redhat.com>
Thu, 11 May 2017 06:13:24 +0000 (14:13 +0800)
Checking inode's nlink is not reliable when mds is not auth mds of
the inode.

This patch also removes the code that skips committing dirfrag of
deleted inode. it's not safe for uncommitted slave rmmdir.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/CDir.cc

index eb813c9a7e06af7d3b03e54f25f3d244a8577a17..3bc939b43cf2ef2948b65dabfc9b1c506ebdc914 100644 (file)
@@ -712,7 +712,7 @@ void CDir::remove_null_dentries() {
 void CDir::try_remove_dentries_for_stray()
 {
   dout(10) << __func__ << dendl;
-  assert(inode->inode.nlink == 0);
+  assert(get_parent_dir()->inode->is_stray());
 
   // clear dirty only when the directory was not snapshotted
   bool clear_dirty = !inode->snaprealm;
@@ -1445,9 +1445,11 @@ void CDir::fetch(MDSInternalContextBase *c, const string& want_dn, bool ignore_a
   }
 
   // unlinked directory inode shouldn't have any entry
-  if (inode->inode.nlink == 0 && !inode->snaprealm) {
+  if (!inode->is_base() && get_parent_dir()->inode->is_stray() &&
+      !inode->snaprealm) {
     dout(7) << "fetch dirfrag for unlinked directory, mark complete" << dendl;
     if (get_version() == 0) {
+      assert(inode->is_auth());
       set_version(1);
 
       if (state_test(STATE_REJOINUNDEF)) {
@@ -2023,14 +2025,6 @@ void CDir::commit(version_t want, MDSInternalContextBase *c, bool ignore_authpin
   assert(is_auth());
   assert(ignore_authpinnability || can_auth_pin());
 
-  if (inode->inode.nlink == 0 && !inode->snaprealm) {
-    dout(7) << "commit dirfrag for unlinked directory, mark clean" << dendl;
-    try_remove_dentries_for_stray();
-    if (c)
-      cache->mds->queue_waiter(c);
-    return;
-  }
-
   // note: queue up a noop if necessary, so that we always
   // get an auth_pin.
   if (!c)
@@ -2288,9 +2282,10 @@ void CDir::_committed(int r, version_t v)
   if (r < 0) {
     // the directory could be partly purged during MDS failover
     if (r == -ENOENT && committed_version == 0 &&
-       inode->inode.nlink == 0 && inode->snaprealm) {
-      inode->state_set(CInode::STATE_MISSINGOBJS);
+       !inode->is_base() && get_parent_dir()->inode->is_stray()) {
       r = 0;
+      if (inode->snaprealm)
+       inode->state_set(CInode::STATE_MISSINGOBJS);
     }
     if (r < 0) {
       dout(1) << "commit error " << r << " v " << v << dendl;
@@ -2381,7 +2376,8 @@ void CDir::_committed(int r, version_t v)
   } 
 
   // try drop dentries in this dirfrag if it's about to be purged
-  if (inode->inode.nlink == 0 && inode->snaprealm)
+  if (!inode->is_base() && get_parent_dir()->inode->is_stray() &&
+      inode->snaprealm)
     cache->maybe_eval_stray(inode, true);
 
   // unpin if we kicked the last waiter.