]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: don't add null dentry to frozen stray dir
authorYan, Zheng <zyan@redhat.com>
Tue, 3 Mar 2020 03:52:29 +0000 (11:52 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 20 Apr 2020 10:11:18 +0000 (18:11 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc

index 214649467d5e6a0105263a816dff5ddfe261c038..6a1e1525f22c71374648da67c67b033f383b4eff 100644 (file)
@@ -794,25 +794,6 @@ CDir *MDCache::get_stray_dir(CInode *in)
   return straydir;
 }
 
-CDentry *MDCache::get_or_create_stray_dentry(CInode *in)
-{
-  CDir *straydir = get_stray_dir(in);
-  string straydname;
-  in->name_stray_dentry(straydname);
-  CDentry *straydn = straydir->lookup(straydname);
-  if (!straydn) {
-    straydn = straydir->add_null_dentry(straydname);
-    straydn->mark_new();
-  } else {
-    ceph_assert(straydn->get_projected_linkage()->is_null());
-  }
-
-  straydn->state_set(CDentry::STATE_STRAY);
-  return straydn;
-}
-
-
-
 MDSCacheObject *MDCache::get_object(const MDSCacheObjectInfo &info)
 {
   // inode?
@@ -10813,6 +10794,7 @@ void MDCache::decode_replica_inode(CInode *&in, bufferlist::const_iterator& p, C
  
 void MDCache::encode_replica_stray(CDentry *straydn, mds_rank_t who, bufferlist& bl)
 {
+  ceph_assert(straydn->get_num_auth_pins());
   ENCODE_START(1, 1, bl);
   uint64_t features = mds->mdsmap->get_up_features();
   encode_replica_inode(get_myin(), who, bl, features);
index 2c841481e32b0abde4ca337ed53778ed16995490..6dd04f1bfb575a48b5844c9bd9adde22aa88b4d4 100644 (file)
@@ -760,7 +760,6 @@ class MDCache {
 
   void open_foreign_mdsdir(inodeno_t ino, MDSContext *c);
   CDir *get_stray_dir(CInode *in);
-  CDentry *get_or_create_stray_dentry(CInode *in);
 
   /**
    * Find the given dentry (and whether it exists or not), its ancestors,
index ae5996e086f35a20c96095e6d322684fcbcd9252..a32babaa28359bdddaecc4fdfaeb8bff42254c89 100644 (file)
@@ -3190,23 +3190,39 @@ bool Server::check_fragment_space(MDRequestRef &mdr, CDir *in)
 
 CDentry* Server::prepare_stray_dentry(MDRequestRef& mdr, CInode *in)
 {
+  string straydname;
+  in->name_stray_dentry(straydname);
+
   CDentry *straydn = mdr->straydn;
   if (straydn) {
-    string straydname;
-    in->name_stray_dentry(straydname);
     ceph_assert(straydn->get_name() == straydname);
     return straydn;
   }
-
   CDir *straydir = mdcache->get_stray_dir(in);
 
   if (!mdr->client_request->is_replay() &&
       !check_fragment_space(mdr, straydir))
-    return NULL;
+    return nullptr;
 
-  straydn = mdcache->get_or_create_stray_dentry(in);
+  straydn = straydir->lookup(straydname);
+  if (!straydn) {
+    if (straydir->is_frozen_dir()) {
+      dout(10) << __func__ << ": " << *straydir << " is frozen, waiting" << dendl;
+      mds->locker->drop_locks(mdr.get());
+      mdr->drop_local_auth_pins();
+      straydir->add_waiter(CInode::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr));
+      return nullptr;
+    }
+    straydn = straydir->add_null_dentry(straydname);
+    straydn->mark_new();
+  } else {
+    ceph_assert(straydn->get_projected_linkage()->is_null());
+  }
+
+  straydn->state_set(CDentry::STATE_STRAY);
   mdr->straydn = straydn;
   mdr->pin(straydn);
+
   return straydn;
 }