]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: explictly specify if MDCache::path_traverse() needs to check null dentry
authorYan, Zheng <zyan@redhat.com>
Mon, 12 Aug 2019 02:09:02 +0000 (10:09 +0800)
committerYan, Zheng <zyan@redhat.com>
Sat, 9 Nov 2019 03:03:15 +0000 (11:03 +0800)
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/Server.cc

index d1333a19fa84324e0165eaf47a59d2c877c6e468..18198b0d8084161d56c43fa5e9326798fafebbb6 100644 (file)
@@ -8054,6 +8054,7 @@ int MDCache::path_traverse(MDRequestRef& mdr, MDSContextFactory& cf,
   bool discover = (flags & MDS_TRAVERSE_DISCOVER);
   bool forward = !discover;
   bool last_xlocked = (flags & MDS_TRAVERSE_LAST_XLOCKED);
+  bool want_dentry = (flags & MDS_TRAVERSE_WANT_DENTRY);
 
   if (forward)
     ceph_assert(mdr);  // forward requires a request
@@ -8208,19 +8209,14 @@ int MDCache::path_traverse(MDRequestRef& mdr, MDSContextFactory& cf,
       CDentry::linkage_t *dnl = dn->get_projected_linkage();
       // can we conclude ENOENT?
       if (dnl->is_null()) {
-       if (pin)
-         *pin = nullptr;
-
+       dout(10) << "traverse: null+readable dentry at " << *dn << dendl;
        if (depth == path.depth() - 1) {
-         if (last_xlocked) {
-           dout(10) << "traverse: null+tail+xlocked dentry at " << *dn << dendl;
+         if (want_dentry)
            break;
-         }
        } else {
          if (pdnvec)
            pdnvec->clear();   // do not confuse likes of rdlock_path_pin_ref();
        }
-       dout(10) << "traverse: null+readable dentry at " << *dn << dendl;
        return -ENOENT;
       }
 
@@ -8263,6 +8259,8 @@ int MDCache::path_traverse(MDRequestRef& mdr, MDSContextFactory& cf,
       continue;
     }
 
+    ceph_assert(!dn);
+
     // MISS.  dentry doesn't exist.
     dout(12) << "traverse: miss on dentry " << path[depth] << " in " << *curdir << dendl;
 
@@ -8275,24 +8273,26 @@ int MDCache::path_traverse(MDRequestRef& mdr, MDSContextFactory& cf,
         // file not found
        if (pdnvec) {
          // instantiate a null dn?
-         if (depth < path.depth()-1){
+         if (depth < path.depth() - 1) {
            dout(20) << " didn't traverse full path; not returning pdnvec" << dendl;
-           dn = NULL;
-         } else if (dn) {
-           ceph_abort(); // should have fallen out in ->is_null() check above
-         } else if (curdir->is_frozen()) {
-           dout(20) << " not adding null to frozen dir " << dendl;
          } else if (snapid < CEPH_MAXSNAP) {
            dout(20) << " not adding null for snapid " << snapid << dendl;
+         } else if (curdir->is_frozen()) {
+           dout(7) << "traverse: " << *curdir << " is frozen, waiting" << dendl;
+           curdir->add_waiter(CDir::WAIT_UNFREEZE, cf.build());
+           return 1;
          } else {
            // create a null dentry
            dn = curdir->add_null_dentry(path[depth]);
            dout(20) << " added null " << *dn << dendl;
          }
-         if (dn)
+         if (dn) {
            pdnvec->push_back(dn);
-         else
+           if (want_dentry)
+             break;
+         } else {
            pdnvec->clear();   // do not confuse likes of rdlock_path_pin_ref();
+         }
        }
         return -ENOENT;
       } else {
index d416d0fb9cf53e3a91b8a124eef284c9199f0146..0e3f781d5f315c5818212000e6dabca7ad7733c8 100644 (file)
@@ -113,6 +113,7 @@ enum {
 // flags for path_traverse();
 static const int MDS_TRAVERSE_DISCOVER         = (1 << 0);
 static const int MDS_TRAVERSE_LAST_XLOCKED     = (1 << 1);
+static const int MDS_TRAVERSE_WANT_DENTRY      = (1 << 2);
 
 // flags for predirty_journal_parents()
 static const int PREDIRTY_PRIMARY = 1; // primary dn, adjust nested accounting
@@ -769,8 +770,10 @@ class MDCache {
    * MDS_TRAVERSE_DISCOVER: Instead of forwarding request, path_traverse()
    * attempts to look up the path from a different MDS (and bring them into
    * its cache as replicas).
-   * MDS_TRAVERSE_LAST_XLOCKED: path_traverse() will succeed on xlocked tail
-   * dentry (return 0 even it's null).
+   * MDS_TRAVERSE_LAST_XLOCKED: path_traverse() will procceed when xlocked tail
+   * dentry is encountered.
+   * MDS_TRAVERSE_WANT_DENTRY: Caller wants tail dentry. Add a null dentry if
+   * tail dentry does not exist. return 0 even tail dentry is null.
    *
    * @param pdnvec Data return parameter -- on success, contains a
    * vector of dentries. On failure, is either empty or contains the
index ae83a48d53cbd46a1ef825be7bf52bd9a9c5512b..c2a9c27a4cc10adc98a7dc0331f2369e7926d5bf 100644 (file)
@@ -8693,7 +8693,7 @@ void Server::handle_slave_rename_prep(MDRequestRef& mdr)
   vector<CDentry*> trace;
   CF_MDS_MDRContextFactory cf(mdcache, mdr);
   int r = mdcache->path_traverse(mdr, cf, destpath,
-                                MDS_TRAVERSE_DISCOVER | MDS_TRAVERSE_LAST_XLOCKED,
+                                MDS_TRAVERSE_DISCOVER | MDS_TRAVERSE_LAST_XLOCKED | MDS_TRAVERSE_WANT_DENTRY,
                                 &trace);
   if (r > 0) return;
   if (r == -ESTALE) {
@@ -8718,9 +8718,6 @@ void Server::handle_slave_rename_prep(MDRequestRef& mdr)
   if (r > 0) return;
   ceph_assert(r == 0);
 
-  // srcpath must not point to a null dentry
-  ceph_assert(srci != nullptr);
-      
   CDentry *srcdn = trace.back();
   CDentry::linkage_t *srcdnl = srcdn->get_projected_linkage();
   dout(10) << " srcdn " << *srcdn << dendl;