]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: delay dentry trimming until after cap traversal 22201/head
authorPatrick Donnelly <pdonnell@redhat.com>
Fri, 18 May 2018 00:06:52 +0000 (17:06 -0700)
committerPatrick Donnelly <pdonnell@redhat.com>
Tue, 19 Jun 2018 22:50:02 +0000 (15:50 -0700)
Fixes: http://tracker.ceph.com/issues/24137
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
(cherry picked from commit 9199179799b41d9534b27bcceefc1bc9f2763bac)

Conflicts:
    src/client/Client.cc

src/client/Client.cc
src/client/Client.h

index bf1cba22f1ac6847c278bed46f90017ee80b0a01..41eff1b4b2a247e64b534a4646a8dfd96172a8df 100644 (file)
@@ -4090,16 +4090,17 @@ void Client::_invalidate_kernel_dcache()
   }
 }
 
-void Client::trim_caps(MetaSession *s, int max)
+void Client::trim_caps(MetaSession *s, uint64_t max)
 {
   mds_rank_t mds = s->mds_num;
-  int caps_size = s->caps.size();
+  size_t caps_size = s->caps.size();
   ldout(cct, 10) << "trim_caps mds." << mds << " max " << max 
     << " caps " << caps_size << dendl;
 
-  int trimmed = 0;
-  xlist<Cap*>::iterator p = s->caps.begin();
-  std::set<InodeRef> anchor; /* prevent put_inode from deleting all caps during traversal */
+  uint64_t trimmed = 0;
+  auto p = s->caps.begin();
+  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);
@@ -4114,8 +4115,7 @@ void Client::trim_caps(MetaSession *s, int max)
       // disposable non-auth cap
       if (!(get_caps_used(in.get()) & ~oissued & mine)) {
        ldout(cct, 20) << " removing unused, unneeded non-auth cap on " << *in << dendl;
-       remove_cap(cap, true);
-        /* N.B. no need to push onto anchor, as we are only removing one cap */
+       cap = (remove_cap(cap, true), nullptr);
        trimmed++;
       }
     } else {
@@ -4132,9 +4132,8 @@ void Client::trim_caps(MetaSession *s, int 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;
@@ -4146,8 +4145,11 @@ void Client::trim_caps(MetaSession *s, int 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 > max)
index 358c183857a8686af47a9f42fd27478a54ff820c..9c076214ac76bcce47f066df3c60fd6da8040325 100644 (file)
@@ -537,7 +537,7 @@ protected:
   void trim_cache(bool trim_kernel_dcache=false);
   void trim_cache_for_reconnect(MetaSession *s);
   void trim_dentry(Dentry *dn);
-  void trim_caps(MetaSession *s, int max);
+  void trim_caps(MetaSession *s, uint64_t max);
   void _invalidate_kernel_dcache();
   
   void dump_inode(Formatter *f, Inode *in, set<Inode*>& did, bool disconnected);