]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: delay dentry trimming until after cap traversal 22073/head
authorPatrick Donnelly <pdonnell@redhat.com>
Fri, 18 May 2018 00:06:52 +0000 (17:06 -0700)
committerPatrick Donnelly <pdonnell@redhat.com>
Sat, 19 May 2018 04:36:02 +0000 (21:36 -0700)
Fixes: http://tracker.ceph.com/issues/24137
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
src/client/Client.cc

index e1be4e27626a4eeac9591c60215060aa38afae16..9030cfef9e9ceece58db73ad97f6abadd9e2e066 100644 (file)
@@ -4089,7 +4089,8 @@ void Client::trim_caps(MetaSession *s, uint64_t max)
 
   uint64_t trimmed = 0;
   auto p = s->caps.begin();
-  std::set<InodeRef> anchor; /* prevent put_inode from deleting all caps during traversal */
+  std::set<Dentry *> to_trim; /* this avoids caps other than the one we're
+                               * looking at from getting deleted during traversal. */
   while ((caps_size - trimmed) > max && !p.end()) {
     Cap *cap = *p;
     InodeRef in(cap->inode);
@@ -4105,7 +4106,6 @@ void Client::trim_caps(MetaSession *s, uint64_t max)
       if (!(get_caps_used(in.get()) & ~oissued & mine)) {
        ldout(cct, 20) << " removing unused, unneeded non-auth cap on " << *in << dendl;
        cap = (remove_cap(cap, true), nullptr);
-        /* N.B. no need to push onto anchor, as we are only removing one cap */
        trimmed++;
       }
     } else {
@@ -4124,9 +4124,8 @@ void Client::trim_caps(MetaSession *s, uint64_t max)
            // the end of this function.
            _schedule_invalidate_dentry_callback(dn, true);
          }
-          ldout(cct, 20) << " anchoring inode: " << in->ino << dendl;
-          anchor.insert(in);
-         trim_dentry(dn);
+          ldout(cct, 20) << " queueing dentry for trimming: " << dn->name << dendl;
+          to_trim.insert(dn);
         } else {
           ldout(cct, 20) << "  not expirable: " << dn->name << dendl;
          all = false;
@@ -4138,8 +4137,11 @@ void Client::trim_caps(MetaSession *s, uint64_t max)
       }
     }
   }
-  ldout(cct, 20) << " clearing anchored inodes" << dendl;
-  anchor.clear();
+  ldout(cct, 20) << " trimming queued dentries: " << dendl;
+  for (const auto &dn : to_trim) {
+    trim_dentry(dn);
+  }
+  to_trim.clear();
 
   caps_size = s->caps.size();
   if (caps_size > (size_t)max)